FSG 1.33 手动脱壳入门教程:模拟跟踪与API断点技巧
直接进入主题:本次要处理的是FSG 1.33压缩壳,使用Peid查壳显示为FSG 1.33 -> dulek/xt。用OD加载后没有任何异常,说明这是一个标准的压缩壳,既没有反调试机制,也不存在自校验。外壳入口代码如下:
00404B58 > BE A4014000 mov esi, fsg1_33.004001A4
00404B5D AD lods dword ptr ds:[esi]
00404B5E 93 xchg eax, ebx
00404B5F AD lods dword ptr ds:[esi]
00404B60 97 xchg eax, edi
00404B61 AD lods dword ptr ds:[esi]
00404B62 56 push esi
00404B63 96 xchg eax, esi
00404B64 B2 80 mov dl, 80
00404B66 A4 movs byte ptr es:[edi], byte ptr ds:[esi]
00404B67 B6 80 mov dh, 80
00404B69 FF13 call dword ptr ds:[ebx]
00404B6B ^ 73 F9 jnb short fsg1_33.00404B66
00404B6D 33C9 xor ecx, ecx
00404B6F FF13 call dword ptr ds:[ebx]
00404B71 73 16 jnb short fsg1_33.00404B89
00404B73 33C0 xor eax, eax
00404B75 FF13 call dword ptr ds:[ebx]
00404B77 73 1F jnb short fsg1_33.00404B98
打开内存镜像查看,发现工作区段位于404000(resources段),其中包含SFX、imports、resources。有意思的是,常规的内存镜像断点在这里并不奏效——因为这段外壳代码没有使用PUSHAD等方便配合ESP定律的指令。如果尝试单步跟踪,FSG 1.33还有变形版本,耗时较长不说,下API断点也会显得很慢。
对付此类壳的最佳策略是模拟跟踪——由于它根本没有SEH处理,模拟追踪几乎不会触发异常。来看内存镜像的详细信息:
内存镜像,项目 13
地址=00404000
大小=00001000 (4096.)
Owner=fsg1_33 00400000
区段=
包含=SFX,imports,resources // 当前段是在404000里面。
类型=Imag 01001002
访问=R
初始访问=RWE
内存镜像,项目 12
地址=00401000
大小=00003000 (12288.)
Owner=fsg1_33 00400000
区段=
包含=code // Oep肯定是在Code段里面。不管FSG在SFX,imports,resources区段里面解压,循环搞什么飞机。最后肯定要跨段访问401000 Code段。
类型=Imag 01001002
访问=R
初始访问=RWE
关键判断已经明确:OEP一定落在401000的code段里。无论外壳在resources段里如何折腾,最终都要跨段跳转到code段执行。于是直接在命令行下开搞:
tc eip
从外壳入口开始模拟运行。注意,模拟跟踪会快速执行,但一旦碰到跨段访问就会自动停下——这正是我们想要的效果。再加上一个断点:
bp GetModuleHandleA
运行程序,很快会停在GetModuleHandleA处。这时按下ALT+F9(执行到返回)回到外壳代码,然后单步往下走。不出意外,在某个位置就能看到OEP的身影了。整个流程快速而简洁,无需手动分析复杂的解压循环。
简单总结一下:FSG 1.33没有SEH、没有PUSHAD,当常规ESP定律和内存断点失效时,模拟跟踪配合API入口断点是最直接的解法。记住一个核心原则——外壳无论怎么折腾,最终都要跳到OEP所在的代码段,抓住这个必然的跨段动作,就能一击制胜。
