使用Vgcrypt Notepad.exe命令行工具压缩了一个Win98的记事本程序,发现压缩后文件大小仍为52K,与原文件相同。该程序未加密IAT,仅扰乱了代码段,导致无法直接反汇编,但通过资源编辑软件仍可编辑资源。首先用PEiD查壳,识别为Virogen Crypt 0.75。用OllyDbg载入运行,未发现异常,判断为压缩壳。
记事本外壳入口:
0040584C > 9C PUSHFD //记事本外壳入口。 0040584D 55 PUSH EBP 0040584E E8 EC000000 CALL 1.0040593F 00405853 87D5 XCHG EBP,EDX 00405855 5D POP EBP 00405856 60 PUSHAD //从这这句过后用ESP定律吧, 00405857 87D5 XCHG EBP,EDX //到这里ESP=12ffa0 00405859 80BD 15274000 0>CMP BYTE PTR SS:[EBP+402715],1 00405860 74 39 JE SHORT 1.0040589B 00405862 C685 15274000 0>MOV BYTE PTR SS:[EBP+402715],1 00405869 E9 E4000000 JMP 1.00405952 0040586E - E9 79DAFF90 JMP 914032EC 00405873 D6 SALC 00405874 64:CE INTO ; 多余的前缀 00405876 E4 3C IN AL,3C ; I/O 命令 00405878 40 INC EAX 00405879 94 XCHG EAX,ESP 0040587A 65:EC IN AL,DX ; I/O 命令 0040587C ^ 78 8D JS SHORT 1.0040580B
在PUSHAD指令执行后,ESP值为12ffa0。使用命令dd 12ffa0设置硬件访问Dword断点,按F9运行,程序断在POPFD处:
004058A8 9D POPFD //堆栈平衡 004058A9 8B9A 09274000 MOV EBX,DWORD PTR DS:[EDX+402709] 004058AF 898A 09274000 MOV DWORD PTR DS:[EDX+402709],ECX 004058B5 FFE3 JMP EBX //跳往OEP 4010CC
跳转后到达OEP:
004010CC 55 DB 55 //右键清除分析 004010CD 8B DB 8B 004010CE EC DB EC 004010CF 83 DB 83 004010D0 EC DB EC 004010D1 44 DB 44 ; CHAR 'D' 004010D2 56 DB 56 ; CHAR 'V' 004010D3 FF DB FF 004010D4 15 DB 15 004010D5 . E4634000 DD 004010D9 8B DB 8B 004010DA F0 DB F0 004010DB 8A DB 8A 004010DC 00 DB 00 004010DD 3C DB 3C ; CHAR '; 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 1.004010FC 004010E1 56 PUSH ESI 004010E2 FF15 F4644000 CALL DWORD PTR DS:[<>] ; 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 1.004010F4 004010F0 3C 22 CMP AL,22 004010F2 ^ 75 ED JNZ SHORT 1.004010E1 004010F4 803E 22 CMP BYTE PTR DS:[ESI],22
接着运行ImportREC,选择该进程,将OEP设置为000010cc。点击IT AutoSearch,再点击“Get Import”,所有函数均显示有效。但FixDump后程序无法运行——不过没关系,使用Loadpe重建PE即可恢复正常运行。
继续用OD载入它的主程序(Vgcrypt自身)。
00408000 > 9C PUSHFD //主程序外壳入口。 00408001 55 PUSH EBP 00408002 E8 EC000000 CALL Vgcrypt.004080F3 00408007 87D5 XCHG EBP,EDX 00408009 5D POP EBP 0040800A 60 PUSHAD //从这这句过后用ESP定律吧, 0040800B 87D5 XCHG EBP,EDX //到这里ESP=12ffa0 0040800D 80BD 15274000 0>CMP BYTE PTR SS:[EBP+402715],1 00408014 74 39 JE SHORT Vgcrypt.0040804F 00408016 C685 15274000 0>MOV BYTE PTR SS:[EBP+402715],1
采用同样的ESP定律手法,设置硬件断点,跟踪执行,最终也能找到OEP,修复方法完全相同。整个壳的脱壳过程非常典型,适合初学者练习。
