转储 PE 中的硬编码地址

逆向工程 拆卸 去混淆
2021-07-09 10:41:38

我使用 Explorer Suite 对游戏进行了转储,在查看 IDA 中游戏 PE 文本部分的一些混淆部分时,我看到了遵循以下形式的代码:

mov rbp, 7FF633CE2790h
jmp rbp

据我所知,代码是可重定位的,那么为什么硬编码地址——它似乎指的是一个直到运行时才知道的虚拟地址——会在这里?

为了处理这些“硬编码”跳转地址,我是否需要将 IDA 中的 PE 重新设置为程序运行时它所在的虚拟地址?我相信我用的dumperrebases到了140000000,这当然导致IDA无法分析上面的代码。

编辑:这是一个具体的例子:

 game.exe+1B9E0E1E - 45 85 C0              - test r8d,r8d              ; ZF = r8d == 0
 game.exe+1B9E0E21 - 48 89 6C 24 F8        - mov [rsp-08],rbp          ; rsp = &a
 game.exe+1B9E0E26 - E9 D8897FFF           - jmp game.exe+1B1D9803

 game.exe+1B1D9803 - 48 8D 64 24 F8        - lea rsp,[rsp-08]          ; rsp = &b
 game.exe+1B1D9808 - 48 BD 7527F508F77F0000 - mov rbp,game.exe+1382775 ; rbp = addr1
 game.exe+1B1D9812 - 48 87 2C 24           - xchg [rsp],rbp            ; b = addr1, rbp = rbp
 game.exe+1B1D9816 - E9 E6F33C02           - jmp game.exe+1D5A8C01

 game.exe+1D5A8C01 - 48 8D 64 24 F8        - lea rsp,[rsp-08]          ; rsp = &c
 game.exe+1D5A8C06 - 48 89 1C 24           - mov [rsp],rbx             ; c = rbx
 game.exe+1D5A8C0A - 48 89 44 24 F8        - mov [rsp-08],rax          ; d = rax
 game.exe+1D5A8C0F - 48 8D 64 24 F8        - lea rsp,[rsp-08]          ; rsp = &d
 game.exe+1D5A8C14 - E9 D8151C00           - jmp game.exe+1D76A1F1

 game.exe+1D76A1F1 - 48 8B 5C 24 10        - mov rbx,[rsp+10]          ; rbx = b
 game.exe+1D76A1F6 - 48 B8 9027F508F77F0000 - mov rax,game.exe+1382790 ; rax = addr2
 game.exe+1D76A200 - E9 CA476400           - jmp game.exe+1DDAE9CF

 game.exe+1DDAE9CF - 48 0F44 D8            - cmove rbx,rax             ; rbx = (r8d == 0) ? addr2 : addr1
 game.exe+1DDAE9D3 - 48 89 5C 24 10        - mov [rsp+10],rbx          ; b = rbx (addr1 or addr2)
 game.exe+1DDAE9D8 - 48 8B 04 24           - mov rax,[rsp]                      
 game.exe+1DDAE9DC - 48 8D 64 24 08        - lea rsp,[rsp+08]          ; rsp = &c
 game.exe+1DDAE9E1 - E9 08F408FD           - jmp game.exe+1AE3DDEE              

 game.exe+1AE3DDEE - 48 8B 1C 24           - mov rbx,[rsp]
 game.exe+1AE3DDF2 - 48 8D 64 24 08        - lea rsp,[rsp+08]          ; rsp = &b
 game.exe+1AE3DDF7 - 48 8D 64 24 08        - lea rsp,[rsp+08]          ; rsp = &a
 game.exe+1AE3DDFC - FF 64 24 F8           - jmp qword ptr [rsp-08]    ; r8d == 0: jmp addr2, else jmp addr1

 ; addr1
 game.exe+1382775 - E9 234F0800           - jmp game.exe+140769D

 ; addr2
 game.exe+1382790 - E9 FDAD991C           - jmp game.exe+1DD1D592
2个回答

通过阅读这里使用的混淆工具,这是一种使分析变得更难的技术。

现在的问题是如何解决这个问题:
我想我可以使用脚本在转储的 PE 中找到这些绝对地址,并将它们转换为 IDA 可以找到的地址。

还有其他想法吗?

编辑:

在将转储的可执行文件加载到具有几个不同基地址的 IDA 中后,我发现地址常量发生了变化。我还在可执行文件的重定位目录中找到了一个条目game.exe+1B1D980A(这是代码示例中的地址常量所在的位置)。

如果我可以禁用 IDA 在这些地址上执行的重定位,分析就会正常工作。我将就此提交一个新问题。

一种可能的解释是处理包含绝对代码的游戏

通常,您在常规日常机器上运行的大多数游戏都是完全可重新定位的,以确保在不同机器上的最大稳定性。然而,尤其是在 ROM 的情况下,例如游戏机的游戏,并且制造商/操作系统可以提供/指定一些预定义的内存位置,以便更容易和更快地运行特定于控制台的功能。

基本上,这样的代码通常依赖于链接器/程序员信任的已知内存位置,并且确定它包含适当的代码,这样的位置可以在机器文档/开发人员指南中明确指定。

由于这是一个在 Windows 上的 PE,它看起来有点奇怪,特别是因为地址是每个进程的 VA 空间的范围,可能这个地址确实指向一些特殊的函数或者进程本身请求分配这个位置并加载了用作混淆的一部分的代码,这可能为此类调用和信任此地址提供理由。