0

这是我试图弄清楚如何分解 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

在此之下有许多 DB 调用,我尝试每隔一个 RETN 设置断点,但没有调用它们。有人可以给我一个提示,如何处理这种 exe 文件?

感谢您的时间,

4

1 回答 1

4

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. 由于它在 a之后紧跟 adword之前被推送,因此可能是after实际上从堆栈中弹出值并跳转到. 另一方面,如果有混淆代码的意图,则调用的函数可能会修改压入堆栈的值,因此after不会跳转到,而是跳转到其他地方。因此,在存储的堆栈地址处设置另一个断点。在函数调用之前应该指向 value ,所以在那里设置断点。它也可以在函数内部设置,但在这种情况下,地址将是call dword 0xbretretcall 0xb0x445001cs:0x445001call dword 0xb0x445001retcall dword 0xb0x4450010x445001call 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),或者从不执行该代码。

于 2013-01-23T01:59:11.033 回答