这是我试图弄清楚如何分解exe的第四天。
仍然没有运气,文件在运行后立即给出调试器错误。我正在使用OllyDBG,似乎该文件要么被压缩,要么包含大量数据。我认为它仅用于调试保护,但是我无法使其正常工作。
我正在努力学习组装,这是我在测试应用程序中变得更好的"新水平"成就。我只想在文件 exe 内将一个文本更改为另一个文本。所以这是一个变量的变化。即使里面有简单的数字更改,我也会感到满意。只是想知道怎么做。
该文件在打开后最初会运行其他 exe,但这不是我想要触摸或编辑的内容。
这是文件打开的方式:
00401000 >/$ 68 01504400 PUSH tryme.00445001
00401005 |. E8 01000000 CALL tryme.0040100B
0040100A . C3 RETN
0040100B $ C3 RETN
0040100C A9 DB A9
0040100D FE DB FE
0040100E 39 DB 39 ; CHAR '9'
0040100F B1 DB B1
00401010 30 DB 30 ; CHAR '0'
00401011 D8 DB D8
00401012 BB DB BB
00401013 A6 DB A6
00401014 45 DB 45 ; CHAR 'E'
00401015 23 DB 23 ; CHAR '#'
00401016 92 DB 92
00401017 AC DB AC
00401018 3D DB 3D ; CHAR '='
00401019 B3 DB B3
0040101A 9C DB 9C
0040101B 8C DB 8C
0040101C 90 NOP
0040101D 0E DB 0E
0040101E 26 DB 26 ; CHAR '&'
0040101F 3B DB 3B ; CHAR ';'
00401020 D3 DB D3
00401021 48 DB 48 ; CHAR 'H'
00401022 49 DB 49 ; CHAR 'I'
00401023 70 DB 70 ; CHAR 'p'
00401024 88 DB 88
00401025 07 DB 07
00401026 78 DB 78 ; CHAR 'x'
00401027 36 DB 36 ; CHAR '6'
00401028 7C DB 7C ; CHAR '|'
00401029 88 DB 88
在此之下有许多数据库调用,我尝试每隔一个 RETN 断点,但它们没有被调用。有人可以给我一个提示,如何处理这种exe文件吗?
谢谢你的时间,
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 位英特尔代码......通常,您可以看到并感觉到代码是否看起来很奇怪,在这种情况下,它要么是错误的处理器,要么是错误的处理器模式,要么代码可能被加密,或者可能是数据而不是代码。
让我们试试它是否是 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
在call dword 0xb
后立即被ret
之前推送,因此可能是call 0xb
之后的ret
实际上将值从堆栈中弹出0x445001
并跳转到cs:0x445001
。另一方面,如果有意混淆代码,则可能是使用 call dword 0xb
调用的函数可能会修改0x445001
推送到堆栈中的值,以便call dword 0xb
之后的ret
不会跳转到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
),或者从不执行该代码。