最近在学习脱壳,找各种各样的教程看,看天草大大的,二哥的,fly的,volx的等等,自己也写了个简单的小壳,引入表和tls都处理好了,准备写代码替换的时候不小心把工程给shift+delete了,那个后悔啊,恢复回来都是乱码.扯完了,进入正文,tElock很老的壳了,菜鸟学习用,高手漂吧,呵呵
这个壳采用的是多次异常来anti跟踪,所以采用最后一次异常法到达OEP
首先忽略非法内存访问选项,其他的都不要勾上。这里有个主意的地方就是用异常法插件里面不能有strong od插件,我发现一带有这个插件异常就不管用,不知道是哪设置不对。把这个插件去掉就正常。
载入程序后,停在0040DBD6 处
代码:
0040DBD6 >^\E9 25E4FFFF JMP Note_tEl.0040C000 0040DBDB 0000 ADD BYTE PTR DS:[EAX],AL 0040DBDD 0038 ADD BYTE PTR DS:[EAX],BH 0040DBDF A4 MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] 0040DBE0 54 PUSH ESP
......
狂按shift+f9忽略异常,第一次不知道哪是最后一次异常,可以shift+f9多次运行后,记住最后一次的位置和特征,然后重新载入程序shift+f9.
这里最后一次异常停在0040D817 处
代码:
0040D80E 810C24 00010000 OR DWORD PTR SS:[ESP],100 0040D815 9D POPFD 0040D816 F8 CLC 0040D817 ^ 73 DC JNB SHORT Note_tEl.0040D7F5 ----------->停在这了 0040D819 CD20 64678F06 VxDCall 68F6764 0040D81F 0000 ADD BYTE PTR DS:[EAX],AL 0040D821 58 POP EAX 0040D822 61 POPAD 0040D823 85E4 TEST ESP,ESP
此时看堆栈
SE处理程序那里就是本次异常的处理程序地址=0x40d7fb
Ctrl+G输入40d7fb,然后F2下断点,shift+f9运行到断点处
取消断点,单步走,遇到call就是F7进入
代码:
0040D81B 64:67:8F06 0000 POP DWORD PTR FS:[0] 0040D821 58 POP EAX 0040D822 61 POPAD 0040D823 85E4 TEST ESP,ESP 0040D825 79 03 JNS SHORT Note_tEl.0040D82A .... 0040D834 98 CWDE 0040D835 23C3 AND EAX,EBX 0040D837 8B3C24 MOV EDI,DWORD PTR SS:[ESP] 0040D83A 58 POP EAX 0040D83B 81EF 9F144100 SUB EDI,41149F 0040D841 EB 02 JMP SHORT Note_tEl.0040D845 .... 0040D8BF F5 CMC 0040D8C0 83E8 91 SUB EAX,-6F 0040D8C3 51 PUSH ECX 0040D8C4 8BC9 MOV ECX,ECX 0040D8C6 E3 03 JECXZ SHORT Note_tEl.0040D8CB---------->走到这就直接在0040D8CB 下断点,f9运行到0040D8CB,然后取消断点,继续单步走 0040D8C8 59 POP ECX 0040D8C9 ^ EB B3 JMP SHORT Note_tEl.0040D87E 0040D8CB 59 POP ECX 0040D8CC F9 STC 0040D8CD 72 02 JB SHORT Note_tEl.0040D8D1 ......... 0040D7AF 61 POPAD------------------->快到OEP了 0040D7B0 - FF6424 D0 JMP DWORD PTR SS:[ESP-30] ; Note_tEl.004010CC 到达OEP处 004010CC 55 PUSH EBP 004010CD 8BEC MOV EBP,ESP 004010CF 83EC 44 SUB ESP,44 004010D2 56 PUSH ESI 004010D3 FF15 E4634000 CALL DWORD PTR DS:[4063E4]//全是这样的 004010D9 8BF0 MOV ESI,EAX 004010DB 8A00 MOV AL,BYTE PTR DS:[EAX] 004010DD 3C 22 CMP AL,22 004010DF 75 1B JNZ SHORT Note_tEl.004010FC 004010E1 56 PUSH ESI 004010E2 FF15 F4644000 CALL DWORD PTR DS:[4064F4] 004010E8 8BF0 MOV ESI,EAX 004010EA 8A00 MOV AL,BYTE PTR DS:[EAX] 004010EC 84C0 TEST AL,AL 004010EE 74 04 JE SHORT Note_tEl.004010F4 004010F0 3C 22 CMP AL,22 004010F2 ^ 75 ED JNZ SHORT Note_tEl.004010E1 004010F4 803E 22 CMP BYTE PTR DS:[ESI],22 004010F7 75 15 JNZ SHORT Note_tEl.0040110E 004010F9 46 INC ESI 004010FA EB 12 JMP SHORT Note_tEl.0040110E 004010FC 3C 20 CMP AL,20 004010FE 7E 0E JLE SHORT Note_tEl.0040110E 00401100 56 PUSH ESI 00401101 FF15 F4644000 CALL DWORD PTR DS:[4064F4]
此时看到这些call 都有些蹊跷,看不见api的调用,这个是个记事本exe,oep处应该有一些api的调用啊如GetCommandLineA等.
先不管了,用loadpe dump出,然后用importrec修复下输入表
发现只能修复一个dll,其他的dll都看不见。用追踪级别三直接卡死了,此时修复抓取文件exe是不能运行的,记事本起码kernel32.dll和user32.dll这几个常用的dll有吧。
那怎么搞呢,我们此时在OEP处单步走到这些 CALL DWORD PTR DS:[4063e4]之类的看看。发现4063e4里面存放着920222,F7进入看见:
00920222 /EB 02 JMP SHORT 00920226
00920224 |FF20 JMP DWORD PTR DS:[EAX]
00920226 \F5 CMC
00920227 B8 9D069200 MOV EAX,92069D
0092022C 40 INC EAX
0092022D FF30 PUSH DWORD PTR DS:[EAX]------>
0092022F C3 RETN ---------->相当于jmp [92069E]
92069E里面是kernel32.GetCommandLineA的地址。继续去其他几个call dword ptr ds:[XXXX]看基本都是这样的调用API,MOV EAX,92069D
INC EAX
PUSH DWORD PTR DS:[EAX]
RETN //这是一段特征,都是一模一样的
输入表都被替换成壳中的代码,然后通过壳来跳到api处,手动修复太麻烦了。想到通过写个脚本来恢复,将获取的api地址在填回输入表中去。输入dd 4063e4看到
里面的0x09xxxxx都是壳的代码。在数据窗口往上翻看到
这个0x4062E4就是iat的起始地址了,(why?A字开头的dll都在最前面)
然后找到iat的结束位置
到这个0x406504处截止.在后面就全是0了。然后就是写脚本了
代码:
var iatstart var iatend var temp2 mov iatend,00406508 mov iatstart,004062FC lab1: mov temp2,[iatstart]//此时temp1为一个地址 log iatstart //这个temp2不能过大 cmp temp2,0 jz next cmp temp2,70000000 ja next find temp2,#FF30C3#//这个FF30C3就是PUSH DWORD PTR DS:[EAX] RETN mov temp2,$RESULT cmp temp2,0 je next sub temp2,5 mov temp2,[temp2] add temp2,1 mov temp2,[temp2] log temp2 mov [iatstart],temp2 log temp2 next: add iatstart,4//修复下一个函数 cmp iatstart,iatend jnz lab1 jmp end error: msg "错误" end: ret
看下输入表
此时在用loadpe dump 出来,用importrec 修复就OK了。
附上Notepad_Telock0.98.rar