DLL文件脱壳(重定位表修复部分)

 

 

13.5 DLL文件脱壳
 

DLL文件的脱壳与EXE文件步骤差不多,所不同的是,DLL文件多了个基址重定位表等要考虑。
 
在2003年出版的《加密与解密》(第二版)中以UPX,PECompact为例讲述了DLL重定位重建的方法,由于本人的思路限制,当时只是从UPX,PECompact自身特点找思路解决这问题,即先分析UPX,PECompact对重定位表处理算法,然后写工具逆算法还原重定位表,如UPXAngela.exe等工具。这种思路的通用性不好,针对不同的壳和版本,要重写工具,并且逆算法可能不完美,从而存在bug。
 
后来,askformore在“ 重建重定位表脚本”一文中,提出了一种更通用性的解决办法,利用外壳重定位相关数据时,会根据外壳转储的重定位表确定要重定位的RVA,完成代码重定位工作。将这些要重定位的RVA提取出来,再将这些RVA根据重定位表的定义重新生成一份新的重定位表。shoooo也曾提到过这个思路。于是,在第三版重写这部分时,根据这个思路写了一款工具来完成这个重建功能,详见附件的ReloREC。另外,ReloREC重构重定位表的算法代码,参考了ccfer在看雪论坛.珠海金山2007逆向分析挑战赛  第二阶段第三题 提交的代码。在此一并表示感谢!

 
声明:本文以第三版“13.5 DLL文件脱壳”一文和其他章节临时整理组织,稍有简化,可能有部分地方用词和描述不是太连贯。

加壳的DLL处理重定位表有以下几种情况: 
1)完整的保留了原重定位表; 
2)对原重定位表进行了加密处理;
等等
 
像ASPack,ASProtect等壳属于第1种情况,没有加密重定位表,脱壳后,只需找到重定位的地址和大小即可。
像UPX,PECompact等壳属于第2种情况,必须重建重定位表,这也是本文所要讨论的,本文以UPX为例来讲述一下重定位的重建。
用UPX v3.01将EdrLib.dll文件加壳,用PE工具查看其PE信息。
EntryPoint:E640h
ImageBase:400000h
 
 
13.5.1 寻找OEP
 
当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。
 
13.5.3 重建DLL的输入表
 
ImportREC能很好地支持DLL的输入表的重建, 首先,在Options里将“Use PE Header From Disk”默认的选项去除。这是因为ImportREC需要获得基址计算RVA值,DLL如果重定位了,从磁盘取默认基址计算会导致结果错误。
 
1)在ImportREC下拉列表框中选择DLL装载器的进程,此处为loaddll.exe进程。
2)单击“Pick DLL”按钮,在DLL进程列表中选择EdrLib.dll进程(见图13.47)。
 
 
图13.47 选择DLL进程
3)在OEP处,填上DLL入口的RVA值1240h,单击IAT AutoSearch按钮获取IAT地址。如果失败,必须手工判断DLL的IAT位置和大小,其RVA为7000h,Size为E8h。
4)单击“Get Import”按钮,让其分析IAT结构重建输入表。
5)勾选Add new section,单击“Fix Dump”按钮,并选择刚抓取的映像文件dumped.dll,它将创建一个dumped_.dll文件。
 
13.5.4 构造重定位表
 
原理请参考本文开始处的说明。
先来回顾一个重定位表的结构:
代码:
IMAGE_BASE_RELOCATION STRUCT
    VirtualAddress    dd    0
    SizeOfBlock        dd    0
    Type1            dw    0; 其中:Bit15Bit12为类型 type,Bit11--Bit0 为ItemOffset
IMAGE_RELOCATION ENDS
重定位表以1000h大小为一个段,因为ItemOffset最长为12位,即刚好为1000h。如果还有更多段,将重复上面数据结构,直到VirtualAddress为NULL,表示结束。
ReloREC工具可以根据一组重定位的RVA,重新构造一个新的重定位表。首先要做的工作是将UPX外壳这些要重定位的RVA提取出来。
 在处理重定位代码语句中,下面这句就是对代码重定位,其中EBX保存的就是要重定位的地址。
代码:
003DE7B6     mov     dword ptr [ebx], eax      ;EBX指向要重定位的RVA
补丁的思路是找块代码空间,跳过去执行补丁代码,将重定位的地址转成RVA,并保存下来。如下语句跳到补丁代码处:
代码:
003DE7B8   jmp     short 003DE80A
我们键入的补丁代码:
003DE80A   pushad
003DE80B   mov     edx, dword ptr [3E0000]    ;从全局变量3E0000h取一地址指针
003DE811   sub     ebx, 3D0000                  ;减外壳基址,将ebx中的地址转成RVA
003DE817   mov     dword ptr [edx], ebx       ;将获得的RVA保存下来
003DE819   add     edx, 4                        ;指向下一个DWRD地址
003DE81C   mov     dword ptr [3E0000], edx  ;将指针保存到全局变量中
003DE822   popad
003DE823   jmp     003DE79C                       ;跳回外壳代码
 
3E0000h这个地址是OllyDbg的插件HideOD临时分配的,其初始值设为3E0010h,如图13.71。


 
 补丁代码键入完成后,外壳在处理重定位相关代码时,这段补丁代码将需要重定位的RVA全部提取出来。执行完补丁代码,数据窗口将保存需要重定位的RVA,
 将需要重定位的RVA复制出来(选取数据时,最后一个DWORD数据是0),操作时单击鼠标右键,执行菜单Binary/Binary copy(二进制复制)功能,再运行WinHex,新建一文档,将这段二进制数据粘贴进去,粘贴时,选择ASCII Hex模式(图13.52),然后将提取的数据保存为Relo.bin。

Relo.bin中保存的就是需要重定位的地址,以RVA表示。部分数据如下:

代码:
0000101D
00001031
0000106E
0000108D
000010A1
000010DE
000010FB
00001109
0000110F
……
ReloREC这款工具,就是根据这些RVA重新生成一份新的重定位表


 准备工作完成,运行ReloREC,将Relo.bin拖放到ReloREC主界面上可打开此文件,如图13.53。然后在dumped_.dll里找一块空白代码处保存重定位表(一般在UPX1或UPX2区块里找),在这选择C000h处。在Relocation's RVA域里填上新重定位表的RVA地址,本例为C000h,最后单击“Fix Dump”按钮,打开上节刚修复输入表的dumped_.dll文件,即可完成重定位表的修复。



看雪学院
看雪软件安全论坛
http://www.pediy.com
2008.3.16
上传的附件 脱壳实例.rar ReloREC 1.0.rar

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: DLL文件修复是指修复动态链接库(DLL文件的过程。DLL文件是计算机程序中常用的一种文件类型,它包含了多个程序模块,可以为程序提供各种功能和服务。在使用计算机软件过程中,有时会遇到由于DLL文件损坏、丢失或缺失等原因导致的错误提示。 为了解决DLL文件问题,可以使用DLL修复精灵等专门的修复工具。DLL修复精灵是一款功能强大的修复工具,能够自动扫描和修复问题DLL文件。使用DLL修复精灵修复DLL文件非常简单,只需打开软件,点击扫描按钮,它将快速扫描计算机上的DLL文件,然后列出需要修复文件修复DLL文件时,DLL修复精灵会自动备份原始文件,并根据可靠的来源提供的修复方法进行修复修复完成后,DLL修复精灵会提示操作结果,并建议重新启动计算机以确保修复DLL文件能够正确应用。 通过使用DLL修复精灵修复DLL文件,可以解决许多常见的DLL错误,如“缺失DLL文件”、“DLL注册失败”等。它可以修复Internet Explorer、Microsoft Office等常见软件的DLL文件,并提供了备份和还原功能,确保修复操作的安全性。 总之,DLL文件修复是一项重要的维护任务,可以帮助解决由DLL文件问题导致的软件错误。使用DLL修复精灵等工具可以帮助简化修复过程,提高计算机的稳定性和性能。 ### 回答2: DLL文件修复是指对动态链接库(Dynamic Link Library,简称DLL文件进行修复和恢复的过程。DLL文件是Windows操作系统中常用的库文件,它包含了程序运行所需要的函数和资源。在使用过程中,由于各种原因,DLL文件可能会损坏或丢失,导致相关程序无法正常运行。 而DLL修复精灵是一款专业的DLL文件修复工具,它可以帮助用户轻松修复损坏的DLL文件,并恢复相关程序的正常运行。用户只需要运行该软件,选择需要修复DLL文件或指定修复目录,然后点击修复按钮即可完成修复过程。 DLL修复精灵具有以下几个主要功能: 1. 自动修复:该软件可以自动检测和修复电脑中的损坏DLL文件,无需用户手动干预,提高修复效率。 2. 备份和恢复:在修复DLL文件之前,该软件会先备份原有的DLL文件,以免修复过程中造成更多问题。如果修复过程中出现意外,用户可以通过软件提供的恢复功能恢复到修复前的状态。 3. 多种修复模式:该软件提供了多种修复模式,根据不同的情况选择合适的修复模式,有助于提高修复效果。 4. 兼容性:该软件兼容多种版本的Windows操作系统,用户可以在不同的电脑上使用。 总之,DLL文件修复|DLL修复精灵是一款功能强大的DLL文件修复工具,可以帮助用户高效修复损坏的DLL文件,恢复相关程序的正常运行。它的简单操作和多种修复模式使其成为广大用户修复DLL文件的首选工具。 ### 回答3: dll文件修复是一种用于解决动态链接库(DLL文件错误或损坏问题的方法。DLL文件是包含代码和数据的可执行文件,用于支持各种应用程序的运行。当DLL文件损坏或丢失时,相应的应用程序可能无法正常运行或出现错误。为了解决这些问题,可以使用一些特定的工具软件,比如dll修复精灵。 dll修复精灵是一款常用的DLL文件修复工具,它能够识别并修复由于DLL文件错误或丢失引起的问题。使用dll修复精灵可以帮助我们恢复受影响的应用程序,并使其再次正常工作。 使用dll修复精灵修复DLL文件的主要步骤包括以下几个方面: 1. 打开dll修复精灵软件,并选择需要修复DLL文件。 2. 执行系统扫描,软件将检测系统中存在的DLL文件问题。 3. 根据扫描结果,dll修复精灵会提供修复建议或自动修复受影响的DLL文件。 4. 完成修复后,重新启动相应的应用程序,以确保修复效果。 值得注意的是,使用dll修复精灵进行修复时,我们应该确保从可信任的来源获取软件,并及时更新软件版本,以便提供更好的修复功能和安全性。 总的来说,dll文件修复dll修复精灵是帮助我们解决DLL文件问题的方法和工具软件。通过使用dll修复精灵,我们能够修复受影响的DLL文件并使应用程序重新正常运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值