处理混淆的程序集

逆向工程 拆卸 混淆 转储
2021-06-09 07:37:10

使用 objdump 时,我看到以下反汇编代码:

8049436:    89 04 24                mov    DWORD PTR [esp],eax
8049439:    e8 52 f7 ff ff          call   8048b90 <gtk_entry_get_text@plt>
804943e:    89 44 24 24             mov    DWORD PTR [esp+0x24],eax
8049442:    eb 01                   jmp    8049445 <gtk_grid_new@plt+0x6c5>
8049444:    1d c7 04 24 0b          sbb    eax,0xb2404c7
8049449:    00 00                   add    BYTE PTR [eax],al
804944b:    00 e8                   add    al,ch
804944d:    0f f7 ff                maskmovq mm7,mm7
8049450:    ff eb                   jmp    <internal disassembler error>

这是使用混淆技术使反汇编更难。当我检查 gdb 时,我在 0x8049445 看到了真正的代码:

(gdb) > x/10i 0x8049445
0x8049445:  mov    DWORD PTR [esp],0xb
0x804944c:  call   0x8048b60 <raise@plt>
0x8049451:  jmp    0x8049454
0x8049453:  sbb    eax,0xfff8a7e8

现在,我的问题是:是否可以告诉 objdump 出于反汇编的目的可以忽略 0x8049444 处的字节?一个明显的方法是实际修补文件,但还有另一种方法吗?

如果没有 objdump,是否还有其他工具可以做到这一点?尽管我更愿意使用 Linux 附带的基本工具,以便更好地熟悉这些工具。

4个回答

大多数工具不支持“忽略该字节进行反汇编”功能,只有 IDA、Hopper 和其他一些工具支持。

唯一的选择是8049444用 a修补字节90 NOP,或者改变主意而不依赖基本工具。

这不是混淆,这只是一个糟糕的反汇编引擎的输出。

请改用IDA Pro您可以从这里下载 Linux 的评估版

这个问题来自objdump反汇编二进制文件的方式这里使用的技术称为线性扫描,它是通过在所有标记为的部分中的每个符号的开头开始CODE并在一条指令之后反汇编指令来完成的,假设跟随一条指令的也是一条指令。这种反汇编技术的问题在于,如果混合代码和数据,数据也会被解释为代码。例如:

...
0x0    mov DWORD PTR [esp+0x24],eax
0x4    jmp *0x10
0x6    DATA 0xfffa2345
0x10   mov DWORD PTR [esp+0x20],eax
...

在这里,对十六进制代码应用线性扫描技术将导致对数据的错误解释,这些数据将被视为代码。而且,如果你真的不走运,数据后面的几条指令也会被打乱。

正如其他答案中已经建议的那样,发现真正代码的唯一方法是使用不同的反汇编技术。不幸的是,objdump只提供一个(线性扫描),因此您需要使用另一个工具。

另请注意,其他答案中建议的其他技术(递归遍历)将在此特定情况下表现良好,但也可能在其他一些示例中对原始代码进行错误的反汇编。所以,你也不能相信它。

正如其他人所说,在这种情况下,这是由于线性扫描。但是,我想补充一点,即使是 IDA 也可能被垃圾字节愚弄,并且您只能在调试示例时信任反汇编。由于编码器可以在运行时更改代码,因此只相信 EIP 上的值,而不要相信其他任何东西都是正确的代码。