修复 IAT 重定向(二)
使用工具
- OllyDbg 1.10原版,简称
OD
; OD
汉化
和插件
均来自互联网;- UnPackMe来自互联网,仅供学习使用;
- Dump 工具为 PETools,来自互联网;
- IAT 重建工具为 ImportREC,来自互联网;
- 文中特殊数字均是
HEX
,为了书写方便采用DEC
;
操作流程
将 CM 导入 OD,使用
内存访问定位法
到达 OEP;到达 OEP 后跟随任意 CALL 定位 IAT,发现 IAT 中有部分未知数据:
通过跟随部分地址后确定不是无效数据,而是被部分 IAT 被重定向了;
记录 OEP 的 RVA,IAT 起始地址 RVA 和结束地址 RVA,计算 Size:
OEP 的 RVA 为 271B0;
IAT 的起始 RVA 为:60818;
IAT 的结束 RVA 为:60F28;
IAT 的 Size = 60F28 - 60818 = 710;使用 PETools 将内存数据 Dump 并保存为可执行文件;
重载程序,给 IAT 的起始地址 00460818 设置内存写入断点,运行程序:
程序中断后,可以看到当前写入 IAT 起始地址的数据与到达 OEP 后 IAT 中的数据不一致;
执行当前指令后,查看相关数据,发现当前写入的是函数字符串指针,而到达 OEP 后却是重定向数据,说明外壳在加载过程中对 IAT 进行了处理;
继续向下执行指令:
执行当前指令后,00460818 中存放的函数字符串指针被替换为 Hook API 数据,所以当前位置是关键代码;
找到关键代码后,为了不让外壳处理 IAT,需要跳过,上面的跳转是关键跳转:
多个跳转嵌套,弯弯绕,如果只是为了不让外壳加密程序,是否可以修改当前指令为无用指令(花指令)呢?
既然要重定向部分 IAT,加密操作肯定是循环,So,单步执行代码重新来到关键位置,修改指令;
修改完成后,取消内存断点,并且给代码段设置断点(为了到达 OEP),然后运行程序:
运行程序后产生一个异常,同时,查看 IAT,发现断点之后的同一个 DLL 中的数据没有被加密,而其它 DLL 中却还有加密数据,那么 IAT 起始地址应该不是外壳写入的第 1 个地址;
Shift + F9
忽略异常后,程序终止运行,应该是外壳有检测机制,检测是否修改了代码,且检测机制位于外壳处理IAT之后,因为之前没有修改过代码;重载程序,给 IAT 所有内存地址设置内存写入断点:
然后运行程序:
程序中断后,通过查看提示信息发现,00460E8C 才是外壳写入的第 1 个地址;
找到并修改关键指令:
取消 IAT 的内存写入断点并给代码段设置内存访问断点,然后运行程序;
依然有异常弹窗,不过查看 IAT 已经全部正常了,那还等什么?
使用 ImportREC 获取输入表:
获取的输入全部有效,然后修复程序;
程序可以运行,将程序导入 OD,检查 IAT:
IAT 正常,脱壳完成!