本次教程的目标是一个使用 ASProtect 1.1b 加壳的程序,该版本相对较早,目前市面上主流已是 1.2x 或更新版本。不过,深入了解其保护机制,对于掌握加壳技术的发展脉络仍然很有帮助。查壳结果显示为:ASProtect 1.1b Registered [SAC],即 Alexey Solodovnikov 的作品。
与当前流行的 ASProtect 1.2x 版本相比,1.1b 版本在异常处理上有一个显著差异:它并未使用 SEH 链,而是精心设计了 13 个非法指令来触发异常。这意味着传统的模拟跟踪方法(用于寻找 OEP,即原始入口点)已不再适用。既然方法失效,我们直接换一种思路,手动操作。
寻找 OEP
使用 Ollydbg(OD)加载目标程序。首先,将除了“错误”和“有特权的指令”之外的所有异常均设置为“忽略”。好消息是,1.1b 版本的壳不会检测调试器,因此省去了隐藏 OD 的麻烦。
加载后,程序停在外壳的入口点:
0040D001 > 60 pushad //外壳入口,F9运行。
0040D002 E9 95050000 jmp chap709.0040D59C
……
直接按 F9 运行。程序会触发一系列精心安排的非法指令异常,例如 lea eax, eax 这种看似合法但实际非法的用法。需要连续按 Shift+F9 共 13 次,将这 13 个异常全部处理。每按一次,程序就会执行一小段异常处理代码,最终到达第 13 次异常的位置。
第 13 次异常处理完后,按 ALT+M 打开内存镜像窗口。找到如下区域:
内存镜像,项目 21
地址=00401000
大小=00004000 (16384.)
Owner=chap709 00400000
区段=
包含=code //对这里下内存访问断点,Shift F9运行。
类型=Imag 01001002
访问=R
初始访问=RWE
对标注为“包含=code”的区段(即代码段)设置一个“内存访问”断点,然后再次按 Shift+F9 运行。这一步至关重要,它会直接引导我们到达程序真正代码开始执行的位置。
程序中断后,我们看到了熟悉的场景:
004010CC 55 push ebp //到达Oep,用Loadpe脱壳吧。
004010CD 8BEC mov ebp, esp
004010CF 83EC 44 sub esp, 44
004010D2 56 push esi
……
这里的 push ebp; mov ebp, esp 是典型的 Windows 程序入口特征。很好,OEP 已经找到,地址为 0x10CC。
到了这一步,就可以使用 LoadPE 等工具将这个进程转存(Dump)下来,生成一个脱壳后的文件。不过先别急,壳虽然脱了,但输入表(IAT)通常已被加密破坏,还需要修复。
IAT 修复
打开 ImportREC,在进程列表中选择正在调试的程序。在 OEP 栏填入 10CC,然后点击“自动搜索”。ImportREC 会根据代码特征找到 IAT 的地址。扫描完成后,发现共有 111 个函数指针未被正确识别,这很常见,壳确实做了手脚。
对于这种加密的 IAT,可以通过调整“跟踪等级”来尝试修复。先用“等级 1”试一下,这次修复了 98 个指针。剩下 13 个顽固分子,再用“等级 3”的深度跟踪处理,这次全部顺利修复。点击“修复转储文件”按钮,选择之前用 LoadPE 转存出来的文件,一个可以正常运行的程序就诞生了。
区段减肥与 PE 重建
不过,事情还没完。脱壳后的程序里,通常还残留着 ASProtect 加壳时创建的许多垃圾区段,例如那些巨大的、包含异常处理代码的区块。这些区段不仅增加了文件体积,有时还会干扰其他分析工具或导致程序不稳定。因此,合理地进行“区段减肥”和“PE 重建”是脱壳工作中的良好习惯。
这个步骤需要一些 PE 文件结构的知识,但跟着做一遍,经验就会慢慢积累。建议先备份好脱壳后的程序,因为如果减肥过度或操作不当,程序可能无法运行。本次操作仅作为示例,旨在展示如何分析原程序的结构,以后遇到类似情况就能举一反三。
我们可以同时用 OD 加载脱壳后的程序和原版的 Win98 记事本(Notepad.exe),分析它们的区段结构,找出哪些是原程序需要的,哪些是垃圾。
原版记事本的内存镜像结构非常清晰:
地址 大小 Owner Section Contains 类型 访问 初始访问 映射为
00400000 00001000 NOTEPAD PE header Imag R RWE
00401000 00004000 NOTEPAD .text code Imag R RWE
00405000 00001000 NOTEPAD .data data Imag R RWE
00406000 00001000 NOTEPAD .idata imports Imag R RWE
00407000 00005000 NOTEPAD .rsrc resources Imag R RWE
0040C000 00001000 NOTEPAD .reloc relocations Imag R RWE
这里的关键区段包括:
- .text:代码段,包含程序的逻辑指令。
- .data:数据段,存放程序初始化时用到的全局变量等。
- .idata:输入表,也就是刚修复好的 IAT,是壳重点破坏的对象。
- .rsrc:资源段,包含图标、菜单、对话框等。
- .reloc:重定位表,对于 EXE 文件来说通常不是必需,可以删除以减小体积。
有了原版的结构作为参照,就能清楚哪些垃圾区段可以安全删除。例如,那些巨大的、名为 .ASProtect 或类似名字的区段,基本都可以移除。最后,使用 PE 工具(如 LordPE 或 CFF Explorer)重建 PE 头,修正所有节表偏移和大小,一个干净、小巧的脱壳版程序就完成了。
整个过程的核心在于两点:一是通过 13 次异常处理找到 OEP,二是修复被加密的 IAT。掌握了这两个关键步骤,再遇到这个系列的壳,处理起来就心中有数了。
