我遇到了一个非常晦涩的32位ELF文件(这是一个破解程序),但我仍然不知道如何执行。首先,在没有任何部分的“可理解”属性旁边:

# readelf --sections SimpleVM

There are no sections in this file.


考虑分段: br />我观察到头段LOAD的大小为0x13c7字节,并映射到0xc01000的内存中;第二个并不重要,因为它的大小为零。但是,ELF文件的入口点是0xc023dc,这意味着在任何段LOAD之外!入口点是非法的。

由于程序没有INTERP段,因此第一个执行的指令必须位于0xc023dc处。但是此地址在任何“可靠”映射的数据之外,我们无法确定将执行哪条指令。我认为该ELF应该具有一些随机行为(例如,通常应使其崩溃),但不是,它可以正常执行,而不会崩溃。

所以我的问题是:这怎么会发生?

NB1。如果有人要查看此文件,请在此处提供链接,但请不要直接提供解决方案。我要自己处理。

NB2。使用Pintool找出发生的情况,我发现程序的OEP位于0xc01dfa,因为它的跟踪是: 0xc023dc始终是mov dword ptr [0xc01bf0], 0x252e8(因此二进制文件会以某种方式“自我修改”)

评论

文件/内存映射始终是页面大小的倍数,在x86上,通常为4k。此处的映射长度0x13c7将舍入为页面大小的倍数,这意味着将映射0x2000字节。如果将原始文件放在偏移量0x13dc处,则应该找到这些“额外”说明。

非常感谢@IanCook,这正是您所说的。实际上,第一条指令的操作码(10字节)位于0x13dc。我不知道映射大小应四舍五入为页面大小。

...然后,操作系统将从LOAD段中复制更多数据,无论它们在标头中的大小如何。您介意将您的评论作为答案吗?

#1 楼

文件/内存映射始终是页面大小的倍数,在x86上,通常为4k。此处的映射长度0x13c7将四舍五入为页面大小的倍数,这意味着将映射0x2000字节。如果将原始文件看在偏移量0x13dc处,则应该找到这些“额外”指令。
必须舍入到页面大小,因为内存管理器和处理器页面表以4k粒度工作,以减少内存管理的开销。

也有自我修改的过程。这是从0xc023dc处的指令到内存的写操作,它创建了您在地址0xC01BF0处看到的CALL(0xE8)指令。这将不在原始文件中。可以写入代码,因为通常情况下,代码是通过程序头中的write(W)访问映射的。