修复 IAT 重定向(二)

使用工具

  • OllyDbg 1.10原版,简称OD
  • OD 汉化插件均来自互联网;
  • UnPackMe来自互联网,仅供学习使用;
  • Dump 工具为 PETools,来自互联网;
  • IAT 重建工具为 ImportREC,来自互联网;
  • 文中特殊数字均是HEX,为了书写方便采用DEC

操作流程

  1. 将 CM 导入 OD,使用内存访问定位法到达 OEP;

  2. 到达 OEP 后跟随任意 CALL 定位 IAT,发现 IAT 中有部分未知数据:

    加密了

    通过跟随部分地址后确定不是无效数据,而是被部分 IAT 被重定向了;

  3. 记录 OEP 的 RVA,IAT 起始地址 RVA 和结束地址 RVA,计算 Size:

    记录 RVA

    OEP 的 RVA 为 271B0;
    IAT 的起始 RVA 为:60818;
    IAT 的结束 RVA 为:60F28;
    IAT 的 Size = 60F28 - 60818 = 710;

  4. 使用 PETools 将内存数据 Dump 并保存为可执行文件;

  5. 重载程序,给 IAT 的起始地址 00460818 设置内存写入断点,运行程序:

    元数据写入

    程序中断后,可以看到当前写入 IAT 起始地址的数据与到达 OEP 后 IAT 中的数据不一致;

    执行 1 行

    执行当前指令后,查看相关数据,发现当前写入的是函数字符串指针,而到达 OEP 后却是重定向数据,说明外壳在加载过程中对 IAT 进行了处理;

  6. 继续向下执行指令:

    加密了

    执行当前指令后,00460818 中存放的函数字符串指针被替换为 Hook API 数据,所以当前位置是关键代码;

  7. 找到关键代码后,为了不让外壳处理 IAT,需要跳过,上面的跳转是关键跳转:

    关键跳转

    多个跳转嵌套,弯弯绕,如果只是为了不让外壳加密程序,是否可以修改当前指令为无用指令(花指令)呢?

    修改关键指令

    既然要重定向部分 IAT,加密操作肯定是循环,So,单步执行代码重新来到关键位置,修改指令;

  8. 修改完成后,取消内存断点,并且给代码段设置断点(为了到达 OEP),然后运行程序:

    错误弹窗

    运行程序后产生一个异常,同时,查看 IAT,发现断点之后的同一个 DLL 中的数据没有被加密,而其它 DLL 中却还有加密数据,那么 IAT 起始地址应该不是外壳写入的第 1 个地址;

    Shift + F9忽略异常后,程序终止运行,应该是外壳有检测机制,检测是否修改了代码,且检测机制位于外壳处理IAT之后,因为之前没有修改过代码;

  9. 重载程序,给 IAT 所有内存地址设置内存写入断点:

    设置内存写入断点

    然后运行程序:

    460E8C

    程序中断后,通过查看提示信息发现,00460E8C 才是外壳写入的第 1 个地址;

  10. 找到并修改关键指令:

    找到并修改关键指令

    取消 IAT 的内存写入断点并给代码段设置内存访问断点,然后运行程序;

    还是弹窗

    依然有异常弹窗,不过查看 IAT 已经全部正常了,那还等什么?

  11. 使用 ImportREC 获取输入表:

    ImportREC

    获取的输入全部有效,然后修复程序;

  12. 程序可以运行,将程序导入 OD,检查 IAT:

    检查 IAT

    IAT 正常,脱壳完成!