手动脱壳入门第十八篇 PC Shrinker 0.71
PC Shrinker 0.71 压缩工具提供了丰富的可选项,界面中并未显示加密设置,因此使用 OD 调试时无需额外处理异常设置。下面以该工具加壳的记事本作为练习对象——Peid 查壳结果显示为 PC Shrinker 0.71 -> Virogen,OD 载入后无任何异常,基本可以断定这是一个纯压缩壳。
入口代码如下:
0040AAFB > 9C PUSHFD //记事本外壳入口。 0040AAFC 60 PUSHAD //仍然是ESP定律 0040AAFD BD B7710000 MOV EBP,71B7 //这里的ESP为12FFA0 0040AB02 01AD 543A4000 ADD DWORD PTR SS:[EBP+403A54],EBP 0040AB08 FFB5 503A4000 PUSH DWORD PTR SS:[EBP+403A50] 0040AB0E 6A 40 PUSH 40 0040AB10 FF95 883A4000 CALL DWORD PTR SS:[EBP+403A88] 0040AB16 50 PUSH EAX 0040AB17 50 PUSH EAX 0040AB18 2D 7D394000 SUB EAX,NOTEPAD.0040397D 0040AB1D 8985 7E394000 MOV DWORD PTR SS:[EBP+40397E],EAX 0040AB23 5F POP EDI 0040AB24 8DB5 7D394000 LEA ESI,DWORD PTR SS:[EBP+40397D] 0040AB2A B9 FC000000 MOV ECX,0FC 0040AB2F F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI] 0040AB31 5F POP EDI 0040AB32 FFE7 JMP EDI
在命令行输入 dd 12ffa0,下硬件访问-Dword 断点,然后按 F9 运行。硬件中断后,可以看到解压缩过程——实际上就是常规的一个循环解压操作。
00132DC6 61 POPAD //堆栈平衡,完全工整对应。 00132DC7 9D POPFD //这里是出口,断在这里。
断在出口后,继续往下看:
00132DC8 BA CC104000 MOV EDX,4010CC 00132DCD FFE2 JMP EDX //EDX=4010CC,这是记事本的OEP(地球人都知道) 004010CC 55 PUSH EBP //在这里用Loadpe直接脱壳 004010CD 8BEC MOV EBP,ESP 004010CF 83EC 44 SUB ESP,44 004010D2 56 PUSH ESI //加密表没有被破坏,往下看到KERNEL32.GetCommandLineA 004010D3 FF15 E4634000 CALL DWORD PTR DS:[4063E4] ; KERNEL32.GetCommandLineA 004010D9 8BF0 MOV ESI,EAX 004010DB 8A00 MOV AL,BYTE PTR DS:[EAX] 004010DD 3C 22 CMP AL,22 004010DF 75 1B JNZ SHORT NOTEPAD.004010FC 004010E1 56 PUSH ESI 004010E2 FF15 F4644000 CALL DWORD PTR DS:[4064F4] ; USER32.CharNextA 004010E8 8BF0 MOV ESI,EAX 004010EA 8A00 MOV AL,BYTE PTR DS:[EAX] 004010EC 84C0 TEST AL,AL 004010EE 74 04 JE SHORT NOTEPAD.004010F4 004010F0 3C 22 CMP AL,22 004010F2 ^ 75 ED JNZ SHORT NOTEPAD.004010E1
运行 ImportREC,选择当前进程,将 OEP 改为 000010cc,点击 IT AutoSearch,再点击“Get Import”——所有函数均显示有效。FixDump 后,记事本正常运行,脱壳顺利完成。
脱壳主程序
接下来用 OD 载入主程序,入口同样清晰直观:
004066F8 > 9C PUSHFD //主程序外壳入口。 004066F9 60 PUSHAD //从这句过后用ESP定律 004066FA BD B42D0000 MOV EBP,2DB4 //此时ESP=19ffa0 004066FF 01AD 543A4000 ADD DWORD PTR SS:[EBP+403A54],EBP 00406705 FFB5 503A4000 PUSH DWORD PTR SS:[EBP+403A50] 0040670B 6A 40 PUSH 40 0040670D FF95 883A4000 CALL DWORD PTR SS:[EBP+403A88] 00406713 50 PUSH EAX 00406714 50 PUSH EAX 00406715 2D 7D394000 SUB EAX,PCSHRINK.0040397D 0040671A 8985 7E394000 MOV DWORD PTR SS:[EBP+40397E],EAX 00406720 5F POP EDI 00406721 8DB5 7D394000 LEA ESI,DWORD PTR SS:[EBP+40397D] 00406727 B9 FC000000 MOV ECX,0FC 0040672C F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI] 0040672E 5F POP EDI 0040672F FFE7 JMP EDI
同样在命令行输入 dd 19ffa0,下硬件访问-Dword 断点,按 F9 运行,硬件中断后:
001A2DD6 61 POPAD 001A2DD7 9D POPFD //堆栈平衡 001A2DD8 BA 00104000 MOV EDX,401000 001A2DDD FFE2 JMP EDX //EDX=401000是主程序的OEP 00401000 E8 DB E8 //这种情况很常见:右键-分析-清除分析 00401001 05 DB 05 00401002 16 DB 16 00401003 00 DB 00 00401004 00 DB 00 00401005 A3 DB A3 00401006 DF DB DF 00401007 37 DB 37 00401008 40 DB 40 00401009 00 DB 00 0040100A E8 DB E8 0040100B BF DB BF 0040100C 15 DB 15
在 OEP 处执行右键“分析→清除分析”后,同样使用 ImportREC 进行修复,将 OEP 改为 00001000,点击 Get Import 后所有函数均显示有效,FixDump 即可得到脱壳后的主程序。整个操作流程与记事本如出一辙,PC Shrinker 0.71 的压缩壳脱壳难度并不高,核心技巧在于利用 ESP 定律配合硬件断点定位出口,随后找到 OEP 并用 ImportREC 完成修复即可。
