13.5.1 寻找OEP

作者:佚名    文章来源:互联网    点击数:    更新时间:2008-8-24
当DLL被初次映射到进程的地址空间中时,系统将调用DllMain函数,当卸载DLL时也会再次调用DllMain函数。也就是说,DLL文件相比EXE文件运行有一些特殊性,EXE的入口点只在开始时执行一次,而DLL的入口点在整个执行过程中至少要执行两次。一次是在开始时,用来对DLL做一些初始化。至少还有一次是在退出时,用来清理DLL再退出。所以DLL找OEP也有两条路可以走,一是载入时找,另一方法是在退出时找。而且一般来说前一种方法外壳代码较复杂,建议用第二种方法。
UPX壳比较简单,往下翻翻,就可看到跳到OEP的代码:
代码:
003DE7F5   .  58              pop     eax
003DE7F6   .  61              popad
003DE7F7   .  8D4424 80       lea     eax, dword ptr [esp-80]
003DE7FB   >  6A 00           push    0
003DE7FD   .  39C4            cmp     esp, eax
003DE7FF   .^ 75 FA           jnz     short 003DE7FB
003DE801   .  83EC 80         sub     esp, -80
003DE804   >- E9 372AFFFF     jmp     003D1240  //跳到OEP
 
13.5.2 Dump映像文件
 
停在OEP后,运行LordPE,在进程窗口选择loaddll.exe进程,在下方窗口中的EdrLib.dll模块上单击右键,执行“dump full”菜单命令,将文件抓取并保存到文件里,如图13.43所示。
 

图13.45 抓取DLL内存映像
 
对于DLL文件来说,Windows系统没有办法保证每一次运行时提供相同的基地址。如果DLL基址所在内存空间被占用或该区域不够大,系统会寻找另一个地址空间的区域来映射DLL,此时外壳将对DLL执行某些重定位操作。从图13.43得知,此时DLL被映射到内存的地址是03D000h,与EdrLib.dll默认的基址400000h不同,被重定位项所指向的地方是已经重定位了的代码数据。
例如这句:
代码:
003D1266     A1 58B43D00        mov     eax, dword ptr [3DB458]
为了得到与加壳前一样的文件,必须找到重定位的代码,跳过它,让其不被重定位。重新加载DLL,对上句重定位的地址3D1267h下内存写断点,中断几下,就可来到重定位的处理代码。
 
代码:
003DE79E  mov     al, byte ptr [edi]              ;指向UPX自己加密过的重定位表
003DE7A0  inc     edi                                  ;指针移向下一位
003DE7A1  or      eax, eax                            ;EAX=0?结束标志
003DE7A3  je      short 003DE7C7               
003DE7A5  cmp     al, 0EF
003DE7A7  ja      short 003DE7BA                   
003DE7A9  add     ebx, eax                          ;EBX的初值为(0xFFC+基址)
003DE7AB  mov     eax, dword ptr [ebx]             ;EBX指向需要重定位的数据,取出放到EAX
003DE7AD  xchg    ah, al
003DE7AF  rol     eax, 10
003DE7B2  xchg    ah, al
003DE7B4  add     eax, esi                          ; ESI指向UPX0区块的VA,本例=3D1000
003DE7B6  mov     dword ptr [ebx], eax           ;重定位
003DE7B8  jmp     short 003DE79C              
003DE7BA  and     al, 0F
003DE7BC  shl     eax, 10
003DE7BF  mov     ax, word ptr [edi]
003DE7C2  add     edi, 2
003DE7C5  jmp     short 003DE7A9            
003DE7C7  mov     ebp, dword ptr [esi+E044]        ;改好ESI为401000后,按F4到这里
 
UPX壳己将原基址重定位表清零,重定位操作时,使用其自己的重定位表。地址3DE7B4h处ESI指向UPX0区块的VA,本例为3D1000h,为了让代码以默认ImageBase的值400000h重定位代码,可以在这句强制将ESI的值改为401000h。来到这句后,双击ESI寄存器,改成401000h,然后按F4来到3DE7C7h这时。此时代码段的数据没被重定位,可以Dump了。
代码:
003D1253     833D 68AD4000 00     cmp     dword ptr [40AD68], 0
运行LordPE将DLL映像抓取,并保存为upx_dumped.dll。

  • 上一条文章:
  • 下一条文章: