ELF 文件的非法入口点

逆向工程 拆卸 小精灵
2021-06-13 03:09:48

我遇到了一个相当晦涩的 32 位 ELF 文件(即破解版),但我仍然不知道它是如何执行的。首先,除了一些“可理解”的属性之外,它没有任何部分:

# readelf --sections SimpleVM

There are no sections in this file.

考虑细分:

# readelf --segments SimpleVM

Elf file type is EXEC (Executable file)
Entry point 0xc023dc
There are 2 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x00c01000 0x00c01000 0x013c7 0x013c7 RWE 0x1000
  LOAD           0x00019c 0x0804b19c 0x0804b19c 0x00000 0x00000 RW  0x1000

我观察到第一个段LOAD有大小0x13c7字节,并映射到内存中0xc01000第二个并不重要,因为它的大小为零。但是,ELF 文件的入口点在0xc023dc,这意味着在任何段之外LOAD!!!

我也使用 IDA 6.8(评估版)来加载这个文件,IDA 说入口点是非法的。

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

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

NB1。如果有人想看这个文件,我在这里给出链接,但请不要直接给出解决方案。我想自己处理。

NB2。使用 Pintool 追踪发生了什么,我发现OEP程序的位置是在,0xc01dfa因为它的跟踪是:

0xc023dc  mov dword ptr [0xc01bf0], 0x252e8 <=== modify address 0xc01bf0
0xc023e6  jmp 0xc01bf0
0xc01bf0  call 0xc01e47                     <=== modified instruction
0xc01e47  pop ebp                           <=== OEP
0xc01e48  call 0xc01dfa
0xc01dfa  pop esi
0xc01dfb  lea eax, ptr [ebp-0x9]
0xc01dfe  mov edi, dword ptr [eax]
0xc01e00  sub eax, edi
0xc01e02  mov edx, eax
0xc01e04  add eax, dword ptr [eax+0x48]
0xc01e07  add eax, 0xfff
0xc01e0c  and eax, 0xfffff000
0xc01e11  push 0x1
0xc01e13  push eax
....

但我仍然无法理解为什么指令 at0xc023dc总是mov dword ptr [0xc01bf0], 0x252e8(所以二进制文件以某种方式“自我修改”)

1个回答

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

自我改造也在进行中。它是从0xc023dc创建您在地址处看到的 CALL (0xE8) 指令的指令写入内存0xC01BF0这不会在原始文件中。对代码的写入是可能的,因为该代码在异常W情况下通过程序头中的写入 ( ) 访问进行映射