# 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
(因此二进制文件会以某种方式“自我修改”)#1 楼
文件/内存映射始终是页面大小的倍数,在x86上,通常为4k。此处的映射长度0x13c7
将四舍五入为页面大小的倍数,这意味着将映射0x2000
字节。如果将原始文件看在偏移量0x13dc
处,则应该找到这些“额外”指令。必须舍入到页面大小,因为内存管理器和处理器页面表以4k粒度工作,以减少内存管理的开销。
也有自我修改的过程。这是从
0xc023dc
处的指令到内存的写操作,它创建了您在地址0xC01BF0
处看到的CALL(0xE8)指令。这将不在原始文件中。可以写入代码,因为通常情况下,代码是通过程序头中的write(W
)访问映射的。
评论
文件/内存映射始终是页面大小的倍数,在x86上,通常为4k。此处的映射长度0x13c7将舍入为页面大小的倍数,这意味着将映射0x2000字节。如果将原始文件放在偏移量0x13dc处,则应该找到这些“额外”说明。非常感谢@IanCook,这正是您所说的。实际上,第一条指令的操作码(10字节)位于0x13dc。我不知道映射大小应四舍五入为页面大小。
...然后,操作系统将从LOAD段中复制更多数据,无论它们在标头中的大小如何。您介意将您的评论作为答案吗?