udis86 反汇编程序库有一个非常有用且方便的反汇编程序,称为udcli
.
例如,我为理解您的代码所做的事情:
首先,将所有十六进制代码字节复制到 ASCII 文件中。我复制了你的 OllyDbg 输出,然后用 Vim 截断了除二进制代码之外的所有内容,得到了一个像这样的文本文件(比方说hexcode.txt
):
68 01 50 44 00 E8 01 00 00 00 C3 C3 A9 FE 39 B1 30 D8 BB A6 45 23 92 AC 3D B3 9C 8C 90 0E 26 3B D3 48 49 70 88 07 78 36 7C 88
然后想知道这是 16 位、32 位还是 64 位 Intel 代码...通常您可以看到并感觉到代码是否看起来很奇怪,在这种情况下,它要么是错误的处理器、错误的处理器模式,要么是代码可能被加密或者它可能是数据而不是代码。
我们来试试是否是16位代码:
在 Linux 控制台中,$ cat hexcode.txt | udcli -x -16
0000000000000000 680150 push word 0x5001
0000000000000003 44 inc sp
0000000000000004 00e8 add al, ch
0000000000000006 0100 add [bx+si], ax
0000000000000008 0000 add [bx+si], al
000000000000000a c3 ret
000000000000000b c3 ret
000000000000000c a9fe39 test ax, 0x39fe
000000000000000f b130 mov cl, 0x30
0000000000000011 d8bba645 fdivr dword [bp+di+0x45a6]
0000000000000015 2392ac3d and dx, [bp+si+0x3dac]
0000000000000019 b39c mov bl, 0x9c
000000000000001b 8c900e26 mov [bx+si+0x260e], ss
000000000000001f 3bd3 cmp dx, bx
0000000000000021 48 dec ax
0000000000000022 49 dec cx
0000000000000023 7088 jo 0xffffffffffffffad
0000000000000025 07 pop es
0000000000000026 7836 js 0x5e
0000000000000028 7c88 jl 0xffffffffffffffb2
嗯。已经开始了inc sp
,非常奇怪的指令。结论:不是16位代码。
也许是 32 位代码?
$ cat hexcode.txt | udcli -x -32
0000000000000000 6801504400 push dword 0x445001
0000000000000005 e801000000 call dword 0xb
000000000000000a c3 ret
000000000000000b c3 ret
000000000000000c a9fe39b130 test eax, 0x30b139fe
0000000000000011 d8bba6452392 fdivr dword [ebx+0x922345a6]
0000000000000017 ac lodsb
0000000000000018 3db39c8c90 cmp eax, 0x908c9cb3
000000000000001d 0e push cs
000000000000001e 263bd3 cmp edx, ebx
0000000000000021 48 dec eax
0000000000000022 49 dec ecx
0000000000000023 7088 jo 0xffffffffffffffad
0000000000000025 07 pop es
0000000000000026 7836 js 0x5e
0000000000000028 7c88 jl 0xffffffffffffffb2
这看起来已经好多了。首先,您可以设置一个断点0x445001
。就这样dword
在 a 之前立即被推送call dword 0xb
随后是一个ret
,可能是ret
after call 0xb
实际上弹出该值0x445001
从堆栈并跳转到cs:0x445001
。另一方面,如果有意混淆代码,则可能是使用以下命令调用的函数call dword 0xb
可以修改该值0x445001
推入堆栈,以便ret
after call dword 0xb
不会跳到0x445001
,但在其他地方。所以在堆栈地址处设置另一个断点0x445001
被储存了。函数调用之前call dword 0xb
[ss:esp]
应该指向值0x445001
,所以在那里设置断点。它也可以在函数内部设置,但在这种情况下,地址将是[ss:esp+4]
([ss:esp]
保存返回地址)。所以我会尝试首先设置这两个断点,然后在call dword 0xb
功能。
最后一个想法:如果这是 64 位代码怎么办?
$ cat hexcode.txt | udcli -x -64
0000000000000000 6801504400 push dword 0x445001
0000000000000005 e801000000 call dword 0xb
000000000000000a c3 ret
000000000000000b c3 ret
000000000000000c a9fe39b130 test eax, 0x30b139fe
0000000000000011 d8bba6452392 fdivr dword [rbx-0x6ddcba5a]
0000000000000017 ac lodsb
0000000000000018 3db39c8c90 cmp eax, 0x908c9cb3
000000000000001d 0e invalid
000000000000001e 263bd3 cmp edx, ebx
0000000000000021 48497088 jo 0xffffffffffffffad
0000000000000025 07 invalid
0000000000000026 7836 js 0x5e
0000000000000028 7c88 jl 0xffffffffffffffb2
开始方式与 32 位代码相同,但后来有一条无效指令,因此可能不是 64 位代码(除非代码挂钩无效操作码异常处理程序)int 6
),或者从不执行该代码。