⑴脱壳:
该外挂的壳是NsPack 1.4,这是比较少见的,呵呵。ESP定律3秒搞定。
⑵附加数据处理:
用Stud_PE抓取原程序的附加数据,然后用WinHex将其复制,并粘贴到脱壳后的程序尾部。幸运的是,该程序全部是从end开始读取数据,不用修复指针。附加数据处理完毕,大概1分钟。运行,程序界面没显示,估计应该有自校验。
⑶自校验处理:
查看进程目录,没有发现我们刚才运行的程序,说明该程序并不是出现内存方面的错误,应该是已经自动退出了。于是用OD装载脱壳后的程序,bp ExitProcess,F9运行,断在这里:
7C81CAA2 > 8BFF MOV EDI,EDI
7C81CAA4 55 PUSH EBP
7C81CAA5 8BEC MOV EBP,ESP
7C81CAA7 6A FF PUSH -1
7C81CAA9 68 B0F3E877 PUSH 77E8F3B0
7C81CAAE FF75 08 PUSH DWORD PTR SS:[EBP+8]
7C81CAB1 E8 46FFFFFF CALL kernel32.7C81C9FC
7C81CAB6 E9 29CF0100 JMP kernel32.7C8399E4
堆栈:
0012FA80 100298AD /CALL 到 ExitProcess 来自 krnln.100298A7
0012FA84 00000000 \ExitCode = 0
看到krnln了,原来是易语言程序。
我们转到100298A7这里去(在堆栈处按回车):
10029892 55 PUSH EBP
10029893 8BEC MOV EBP,ESP
10029895 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
10029898 50 PUSH EAX
10029899 B9 10DB0E10 MOV ECX,krnln.100EDB10
1002989E E8 4DC40200 CALL krnln.10055CF0
100298A3 8B4D 08 MOV ECX,DWORD PTR SS:[EBP+8]
100298A6 51 PUSH ECX
100298A7 FF15 D4230C10 CALL DWORD PTR DS:[100C23D4] ; kernel32.ExitProcess (这里)
100298AD 5D POP EBP
100298AE C3 RETN
我们在10029892 55 PUSH EBP下硬件执行断点。
重新开始,F9,停在这里:
10029892 55 PUSH EBP
10029893 8BEC MOV EBP,ESP
10029895 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
10029898 50 PUSH EAX
10029899 B9 10DB0E10 MOV ECX,krnln.100EDB10
1002989E E8 4DC40200 CALL krnln.10055CF0
100298A3 8B4D 08 MOV ECX,DWORD PTR SS:[EBP+8]
100298A6 51 PUSH ECX
100298A7 FF15 D4230C10 CALL DWORD PTR DS:[100C23D4] ; kernel32.ExitProcess
100298AD 5D POP EBP
100298AE C3 RETN
为了知道程序是从哪里CALL到这里的(观察堆栈也行),我们把这两句
100298A6 51 PUSH ECX
100298A7 FF15 D4230C10 CALL DWORD PTR DS:[100C23D4] ; kernel32.ExitProcess
nop掉。接着我们按F8,由于那两句被nop掉了,程序并不会退出,程序会返回到这里:
0042B2AE EB 01 JMP SHORT 3.0042B2B1
0042B2B0 0FF972 01 PSUBW MM6,QWORD PTR DS:[EDX+1]
0042B2B4 8A83 7DF4FF0F MOV AL,BYTE PTR DS:[EBX+FFFF47D]
0042B2BA 8411 TEST BYTE PTR DS:[ECX],DL
0042B2BC 0000 ADD BYTE PTR DS:[EAX],AL
0042B2BE 00EB ADD BL,CH
0042B2C0 0178 F8 ADD DWORD PTR DS:[EAX-8],EDI
0042B2C3 73 01 JNB SHORT 3.0042B2C6
0042B2C5 0F6A00 PUNPCKHDQ MM0,QWORD PTR DS:[EAX]
0042B2C8 E8 DC0C0200 CALL 3.0044BFA9
0042B2CD 83C4 04 ADD ESP,4 (返回到这里)
上面的代码显然是花指令,我们处理一下后,得到如下代码:
0042B2AE /EB 01 JMP SHORT 3.0042B2B1
0042B2B0 |90 NOP
0042B2B1 \F9 STC
0042B2B2 72 01 JB SHORT 3.0042B2B5
0042B2B4 90 NOP
0042B2B5 837D F4 FF CMP DWORD PTR SS:[EBP-C],-1
0042B2B9 0F84 11000000 JE 3.0042B2D0
0042B2BF EB 01 JMP SHORT 3.0042B2C2
0042B2C1 90 NOP
0042B2C2 F8 CLC
0042B2C3 73 01 JNB SHORT 3.0042B2C6
0042B2C5 90 NOP
0042B2C6 6A 00 PUSH 0
0042B2C8 E8 DC0C0200 CALL 3.0044BFA9
0042B2CD 83C4 04 ADD ESP,4 (返回到这里)
显然这一句0042B2B9 0F84 11000000 JE 3.0042B2D0可以跳过0042B2C8 E8 DC0C0200 CALL 3.0044BFA9(这个CALL导致程序退出),于是我们把JE改成JNZ即可!修复保存,运行,一切OK!
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)