📄 cn.txt
字号:
在Dump之前,右键单击“新”Olly中的所有段(也可用Peheader),设置访问->完整访问。
这样做的目的是因为:脱壳时,壳通过实际防护API保护内存区域的访问,造成Dump失败或错误的Dump文件。Imprec也一样,你无法从内存中读取进程,表明输入表的修正,占用了数据。
现在以004010C2-400000=10C2作为入口点偏移地址,不钩选输入表重建选项,用OllyDump 插件Dump加壳程序。我们取得了Dump后的程序。
我们不使用Olly重建输入表而只是查看一下代码,这是因为壳可以侦测出所有设置的软硬件断点的缘故。但是别担心,因为Dump后的代码不再自校验且我们需要的内存区域不再包含难解字节,因此Olly的使用是多此一举。Olly只作为DASM来使用。我们打开ImpRec,填入入口点偏移量10C2。选择“输入表自动搜索”(IAT autosearch),“获取输入表”(GET Imports)。选择“显示无效指针”(show invalid)。发现许多。选择其中一个右键单击->反汇编。我们可以在此处查看到指向有效API的代码。因此要使指针有效,我们需要调试这些代码并找出它们实际指向哪里的API。第一次进入API代码中,我们会发现首个操作码地址格式是7XXXXXXX(API皆是如此)。以此为依据,我们在Olly的所有模块中查找对应的API。然后补上有效的API指针。
但是我们怎样补上全部有效指针呢?我们可以查看一个无效指针的反汇编代码,例如:
00143B98H处:
00143B98 58 POP EAX
00143B99 50 PUSH EAX
00143B9A 60 PUSHAD
00143B9B 9C PUSHFD
00143B9C 68 02000000 PUSH 2
00143BA1 50 PUSH EAX
00143BA2 B8 32DEE44B MOV EAX,4BE4DE32
00143BA7 50 PUSH EAX
00143BA8 B8 2C1CB9C3 MOV EAX,C3B91C2C
00143BAD 50 PUSH EAX
00143BAE E8 BD5C3200 CALL sdprotec.00469870
00143BB3 9D POPFD
00143BB4 61 POPAD
00143BB5 B8 2C1CB9C3 MOV EAX,C3B91C2C
00143BBA 9C PUSHFD
00143BBB 2D 32DEE44B SUB EAX,4BE4DE32
00143BC0 9D POPFD
00143BC1 50 PUSH EAX
00143BC2 C3 RETN
00143BB5之前的代码是用来混淆视听的垃圾代码。00143BB5处,数值放入EAX,接着全部入栈(也是垃圾操作码,别在意),EAX在00143BBB处减去4BE4DE32,这时的值为77D43DFA。全部出栈来到77D43DFA(译注:PUSH EAX数值)。通过Olly搜索知道API原来是TransLateMessage。在ImpRec中双击此指针,从user32.dll中选择TransLateMessage。再次“显示无效指针”。很好,我们搞定了一个。通过这种方式,我们可以修正所有的无效指针。可是,我们仍然发现了一个指针(没有EAX返回API)无法修复。地址在468AB3处,通过Olly查看如下:
00468AB3 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4]
00468AB7 85C0 TEST EAX,EAX
00468AB9 7D 1D JGE SHORT sdprotec.00468AD8
00468ABB 83F8 F5 CMP EAX,-0B
00468ABE 7E 18 JLE SHORT sdprotec.00468AD8
00468AC0 8B4C24 10 MOV ECX,DWORD PTR SS:[ESP+10]
00468AC4 8B5424 0C MOV EDX,DWORD PTR SS:[ESP+C]
00468AC8 51 PUSH ECX
00468AC9 8B4C24 0C MOV ECX,DWORD PTR SS:[ESP+C]
00468ACD 52 PUSH EDX
00468ACE 51 PUSH ECX
00468ACF 50 PUSH EAX
00468AD0 E8 A1F7FFFF CALL sdprotec.00468276
00468AD5 C2 1000 RETN 10
00468AD8 8B5424 10 MOV EDX,DWORD PTR SS:[ESP+10]
00468ADC 8B4C24 0C MOV ECX,DWORD PTR SS:[ESP+C]
00468AE0 52 PUSH EDX
00468AE1 8B5424 0C MOV EDX,DWORD PTR SS:[ESP+C]
00468AE5 51 PUSH ECX
00468AE6 52 PUSH EDX
00468AE7 50 PUSH EAX
00468AE8 E8 BD3F0000 CALL sdprotec.0046CAAA
00468AED C2 1000 RETN 10
我们发现00468AE8处的CALL调用了API。之前都是垃圾代码。因此继续查看0046CAAA(译注: 00468AE8 E8 BD3F0000 CALL sdprotec.0046CAAA),如下:
0046CAAA E8 01000000 CALL sdprotec.0046CAB0
0046CAAF FF58 05 CALL FAR FWORD PTR DS:[EAX+5] ; Far call
0046CAB2 C9 LEAVE
0046CAB3 0A00 OR AL,BYTE PTR DS:[EAX]
0046CAB5 008B 008038CC ADD BYTE PTR DS:[EBX+CC388000],CL
0046CABB 74 0A JE SHORT sdprotec.0046CAC7
0046CABD 50 PUSH EAX
0046CABE C3 RETN
我们发现又调用了0046CAB0,这些层次使我们无法查看操作码(译注:就是7XXXXXXX一类的)。因此继续查看,如下:
0046CAB0 58 POP EAX
0046CAB1 05 C90A0000 ADD EAX,0AC9
0046CAB6 8B00 MOV EAX,DWORD PTR DS:[EAX]
0046CAB8 8038 CC CMP BYTE PTR DS:[EAX],0CC
0046CABB 74 0A JE SHORT sdprotec.0046CAC7
0046CABD 50 PUSH EAX
0046CABE C3 RETN
可以看出,0046CABE有我们需要的API(译注:根据上面的EAX返回数值查找API的方法)。由于0046CAAA处的CALL(这时EAX堆栈返回值为0046CAAA),EAX在0046CAB0处的值等于0046CAAF(译注:0046CAAF CALL FAR FWORD PTR DS:[EAX+5],所以
0046CAB0 POP EAX后EAX=0046CAAA+5=0046AAF)。增加0AC9后(译注:0046CAB1 ADD EAX,0AC9),EAX=0046D578。现在EAX的数值就是修正指针的API地址。此处设置了一个检验软件断点的陷阱(译注:0046CAB8处的比较),接着EAX入栈-返回。我们不研究这些。
我们研究的是EAX数值数地址里究竟有什么。查看0046D578处如下:
0046D578 76 64 JBE SHORT sdprotec.0046D5DE
0046D57A D6 SALC
0046D57B ^77 E3 JA SHORT sdprotec.0046D560
0046D57D A6 CMPS BYTE PTR DS:[ESI],BYTE PTR ES:[EDI]
0046D57E D4 77 AAM 77
注意前4个字节(译注:从0046D578的“76”到0046D57B的“77”)转换后的结果77D66476H。查看Olly后得知是MessageBoxA.我们修正最后一个无效指针。选择“显示无效指针”,无。修正Dump文件。
运行程序成功!!!我们漂亮地完成了称之为最新SDProtector壳的反击战!!
不过这确实是一个“硬”壳,花了我至少6个小时破解+写教程。这篇教程很有教益。
“是时候与大家分享了。。。”
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -