- 第一章 - OD 的各个窗口介绍
- 第二章 - 数值系统
- 第三章 - 寄存器
- 第四章 - 汇编指令
- 第五章 - 数学指令
- 第六章 - 比较和条件跳转
- 第七章 - call ret
- 第八章 - 循环 字符串指令和寻址方式
- 第九章 - 基本概念
- 第十章 - 断点
- 第十一章:硬件断点与条件断点
- 第十二章 - 消息断点
- 第十三章 - 硬编码序列号寻踪-Part1
- 第十四章 - 硬编码序列号寻踪-Part2
- 第十五章 - 硬编码序列号寻踪-Part3
- 第十六章 - 序列号生成算法分析-Part1
- 第十七章 - 序列号生成算法分析-Part2
- 第十八章 - 序列号生成算法分析-Part3
- 第十九章 - OllyDbg 反调试之 IsDebuggerPresent
- 第二十章 - OllyDbg 反调试之检测 OD 进程名
- 第二十一章 - OllyDbg 反调试之检测 OD 进程名,窗口类名,窗口标题名
- 第二十二章 - OllyDbg 反调试之 UnhandledExceptionFilter,ZwQueryInformationProcess
- 第二十三章 - OllyDbg 反调试之 ProcessHeap,NTGlobalFlag,OutputDebugStringA
- 第二十四章 - OllyDbg 反调试之综合 CrackMe
- 第二十五章 - 异常处理
- 第二十六章 - Visual Basic 程序的破解-Part1
- 第二十七章 - Visual Basic 程序的破解-Part2
- 第二十八章 - Visual Basic 程序的破解-Part3
- 第二十九章 - P-CODE-Part1
- 第三十章 - P-CODE-Part2
- 第三十一章 - 脱壳简介
- 第三十二章 - OEP 寻踪
- 第三十三章 - 神马是 IAT 如何修复
- 第三十四章 - 手脱 UPX,修复 IAT
- 第三十五章 - 手脱 ASPack V2.12
- 第三十六章 - IAT 重定向
- 第三十七章 - 论 IAT 重定向之修复
- 第三十八章 - 手脱 Yoda's Protector v1.3(Yoda's Crypter)
- 第三十九章 - 神马是 stolen bytes
- 第四十章 - OllyDbg 脚本的编写
- 第四十一章 - 神马是 AntiDump
- 第四十二章 - ACProtect V1.09 脱壳(寻找 OEP 绕过硬件断点的检测 修复 Stolen code)
- 第四十三章 - ACProtect V1.09 脱壳(编写脚本修复 IAT)
- 第四十四章 - ACProtect V1.09 脱壳(修复 AntiDump)
- 第四十五章补充章节-ReCrypt v0.80 脱壳(续)
- 第四十六章 - Patrick 的 CrackMe-Part1
- 第四十七章 - Patrick 的 CrackMe-Part2
- 第四十八章 - PeSpin V1.3.04 脱壳-Part1
- 第四十九章 - PeSpin V1.3.04 脱壳-Part2
- 第五十章 - 再谈 ReCrypt v.0.80 脱壳(调戏 OutputDebugString)
- 第五十一章 - ASProtect v2.3.04.26 脱壳-Part1
- 第五十二章 - ASProtect v2.3.04.26 脱壳-Part2
- 第五十三章 - TPPpack 脱壳
- 第五十四章 - EXECryptor v2.2.50.a 脱壳-Part1
- 第五十五章 - ExeCryptor v2.2.50.a-Part2
- 第五十六章 - EXECryptor v2.2.50.b 脱壳
- 第五十七章 - ExeCryptor v2.2.50.c/d/e/f/g 脱壳
- 第五十八章 - ExeCryptor v2.2.50
第四十三章 - ACProtect V1.09 脱壳(编写脚本修复 IAT)
上一章节,我们介绍了如何定位 stolen bytes,本章我们的任务是修复 IAT,再次用 OD 加载 UnPackMe_ACProtect1.09,我们可以通过并执行 HBP.TXT 脚本到达假的 OEP 处。
现在我们在壳的入口处,现在我们来利用上一章节编写的脚本定位到 OEP 处,首先,需要需要给 KiUserExceptionDispatcher 入口处以及其下方的 ZwContinue 调用处分别设置断点。
现在我们到了假的 OEP 处,大家可以修改一下这个脚本让其自动给 KiUserExceptionDispatcher 入口以及 ZwContinue 调用处设置断点,并且让其支持输入需要设置硬件断点的地址,但这里我们暂时没有必须修改,这个脚本目前来说已经够用了。
下面我们来随便定位一个 API 函数的调用处,单击鼠标右键选择 Search for - All intermodular calls 选项搜索。
我们可以看到很多 API 函数的调用,其中有些 IAT 项是正常的,显示出了函数名称,但是大部分的 IAT 项都是经过重定位的,并没有显示函数名称,我们随便选中一个重定向的 IAT 项,双击鼠标左键。
这里我们可以看到 CALL 的是 460E80 内存单元中对应的 IAT 项,我们在数据窗口中定位到该项。
这里我们可以看到很多经过重定向的项,这些项直接就位于壳的区段中,我们来看看区段列表窗口。
大家应该还记得该壳的入口点也是位于这个区段的,壳的入口点为 46B000,也就是说该壳并没有重新创建一个区段用来处理重定向的 API 函数。
接下来任务就需要定位修复 IAT 项的关键跳转(magical jump) 了。
下面我们就来通过 460ADC 这一项来定位关键跳。
首先我们将定位 OEP 的脚本备份一下。
我们将备份过的脚本重命名为 OEP.txt,接下来我们通过修改 HBP.txt 脚本来定位修复 IAT 的关键跳转。
这里我们将脚本修改为对 460ADC 这个重定向的 IAT 项设置硬件写入断点,也就是说断点类型修改为 W。
现在我们清除之前设置的硬件断点,重新启动 OD。
执行上面的脚本,不一会儿弹出了是否继续执行脚本的消息框。
我们可以看到这里对 460ADC 写入的时候触发了硬件写入断点,我们知道硬件断点是断在下一条指令处,我们来看看前一条指令是什么。
这里我们可以看到是这条指令将对 460ADC 地址进行写入,我们来看看 EAX 的值是多少。
这里 EAX 的值为 46B492。
这里我们在反汇编窗口中定位到 46B492 这个地址,看看该壳做什么处理。
这里我们看到这个重定向的处理非常简单,首先将常量 5BF11A9 压入堆栈,接着将该值与 793E0502 进行异或,接着就 RET 返回。
异或得到的结果就是 API 函数的入口地址,我们一起来计算一下。
5BF11A9 XOR 793E0502 = 7C8114AB
计算出来的这个地址就是 API 函数的入口地址,我们返回到 OD 中看看。
我们将堆栈窗口往上拉一点就能看到正确的 API 函数地址了,下面我们就来看看是不是所有的重定向的 IAT 项都是这样处理的,先停止脚本。
我们对部分重定向的 IAT 项设置内存写入断点,看看会发生什么。
我们运行起来,当下一个重定向的 IAT 项被写入的时候断了下来。
我们定位到重定向的部分,执行异或操作以后可以看到得到的 API 函数是 MulDiv,这么看来修复是有可能的,我们可以看到正常的 API 地址被保存在了堆栈中,确切点来说是[ESP - 0C]中。
这里我们可以看到往下都是需要重定向的,到了 460BA8,就是正常的 IAT 项了。
所以我们对 460BA8 这一项设置内存写入断点。
运行起来,到了这里。
我们可以看到对于正常的 IAT 项,[EBP - 0C]处并不会保存正确的 API 函数入口地址,所以说有点遗憾,不然我们可以使用一个简单的脚本轻松的修复 IAT。
我们该怎么做呢?我们需要对写入 IAT 项的指令设置硬件执行断点,当脚本执行到这里的时候,我们判断 EAX 的值是正常的还是重定向的,如果是重定向的,那么我们就将[ESP + 0C]的值填充到 IAT 对应的条目中,如果是正常的 IAT 项的话,我们就不予处理,我们来看看该脚本如何编写。
以上就是完整的脚本,这里我是在下一行的 4743d5 处设置的硬件执行断点,因为硬件执行断点当将要执行该条指令的时候就断下来,不同于硬件写入或者访问断点。
这个脚本是基于 HBP.txt 改写的,首先对 IAT 项重定向的下一条指令 4743d5 处设置硬件执行断点。
这里是 ToProcess 这个分支,当脚本检测到中断异常,将 EIP 与 4743d5 进行比较,如果相等就跳转到 ToRepair 分支中。
ToRepair 分支,我们首先判断 EAX 是否为正常,如果被重定向到壳所在区段的话,那么地址是小于 500000 的,反之,如果 EAX 的值大于 500000,就表示该 IAT 项是正常的,我们就无须进行修复,回到开始处继续捕获下一次中断。如果 EAX 是重定向的值的话,我们就使用变量 aux2 来保存正确的 API 函数地址,正确的 API 函数地址保存在[ESP - 0C]中。我们将其写入到 EDI 指向的 IAT 项中即可。
下面我们就来执行一下该脚本,试试效果。
重启程序,将之前设置的硬件断点全部清空,接着对 KiUserExceptionDispatcher 的入口处以及 ZwContinue 的调用处分别设置断点,然后运行脚本。
程序运行起来了,我们来看下 IAT。
嘿嘿,我们可以看到 IAT 项都被修复了。
我们将脚本重命名为 IAT.txt。
下面我们需要定位 IAT 的起始地址以及 IAT 的大小。
这里我们可以看到 IAT 的起始地址为 460818,结束于 460F28。
OEP(RVA) = 271b5
IAT 的起始地址(RVA) = 60818
IAT 的大小 = 710
这里我们可以用的假的 OEP,后面我们可以手工修改。
下一章节,我们来解决 AntiDump,敬请关注。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论