首页
社区
课程
招聘
[旧帖] [原创]VC++7程序Themida脱壳之VM-OEP的代码还原 0.00雪花
发表于: 2008-5-29 22:09 7267

[旧帖] [原创]VC++7程序Themida脱壳之VM-OEP的代码还原 0.00雪花

2008-5-29 22:09
7267
前段在UNPACK.CN看到个Delphi程序Themida脱壳之VM-OEP的代码还原的文字教程,感觉讲的非常的好,也许是碰巧吧,今天在新世纪网安基地论坛上,看到有人求破解软件,于是乎下下来看了看,一查壳是TMD1.92的壳,于是拿起工具开工了


程序载入后的代码:
http://i.namipan.com/files/f22bc100ba6719234e6fdc044e4616efee6098aae0b100003438/3/1.jpg

这里不手动搞了,直接用fxyang大侠的TMDScript-1.9.1+_1.0 final_修正集成版来进行脱壳,运行完脚本之后的代码:
00475E8C    PUSH SYV2_22.00474328    ① 这里的地址要记下来,也就是00475E8C,这个就是VC++7的第一个CALL的地址,我们在这里要注意堆栈
00475E91    MOV EAX,DWORD PTR FS:[0]
00475E97    PUSH EAX
00475E98    MOV EAX,DWORD PTR SS:[ESP+10]
00475E9C    MOV DWORD PTR SS:[ESP+10],EBP
00475EA0    LEA EBP,DWORD PTR SS:[ESP+10]
00475EA4    SUB ESP,EAX
00475EA6    PUSH EBX
00475EA7    PUSH ESI
00475EA8    PUSH EDI
00475EA9    MOV EAX,DWORD PTR SS:[EBP-8]
00475EAC    MOV DWORD PTR SS:[EBP-18],ESP
00475EAF    PUSH EAX
00475EB0    MOV EAX,DWORD PTR SS:[EBP-4]

--------------------------------------------------------------------------------------------------------堆栈的代码如下:
0012FF8C   007B4D35  SYV2_22.007B4D35
0012FF90   004BB680  SYV2_22.004BB680 ②注意这里有2个数据我们要纪录下来,也就是60和004BB680,这2个数据就是VC++7入口的2个PUSH的数据0012FF94   00000060                    ③
-------------------------------------------------------------------------------------------------------
我们F8单步走,走出这个CALL来到VM代码处,这个时候我们在代码段下F2断点,SHIFT+F9运行,

来到了第2个CALL的代码处,代码如下,

00474430    CMP EAX,1000   ④  这里我们仍然要纪录一个数据,即00474430,这个就是VC++7入口的第2个CALL
00474435    JNB SHORT SYV2_22.00474445
00474437    NEG EAX
00474439    ADD EAX,ESP
0047443B    ADD EAX,4
0047443E    TEST DWORD PTR DS:[EAX],EAX
00474440    XCHG EAX,ESP
00474441    MOV EAX,DWORD PTR DS:[EAX]
00474443    PUSH EAX
00474444    RETN
00474445    51             PUSH ECX
00474446    8D4C24 08      LEA ECX,DWORD PTR SS:[ESP+8]

这里我们暂时可以写一些代码了,我们参照VC++7的入口特征来补代码,对照的文本我会打包给大家的,
PUSH 60                                    
PUSH 004BB680                               ②
CALL 00475E8C                                ①
mov edi,94                               //这里原封不动
mov eax,edi                              //这里原封不动
call 00474430                              
mov dword ptr ss:[ebp-18],esp          //这里原封不动
mov esi,esp                             //这里原封不动
mov dword ptr ds:[esi],edi              //这里原封不动
push esi                                //这里原封不动
------------------------------------------------------------------------------------------------------
暂时就只能补这么多了,然后我们继续F8单步走出这个CALL来到VM地方,仍然在代码段下F2断点,SHIFT+F9
00E6E9F2    PUSH DWORD PTR DS:[EAX]  ; kernel32.GetVersionExA ⑤ 这里看到有个API看上去很眼熟,对了他就是VC++7入口的API的函数,我们要记下EAX的值004AE350,以后要用到。
00E6E9F4    JMP 00E6ECBD
00E6E9F9    MOV CL,82
00E6E9FB    SUB CL,0AA
00E6E9FE    ADD CL,93
00E6EA01    ADD AH,CL
00E6EA03    XOR CL,CL
00E6EA05    ADD CL,CL
00E6EA07    PUSH CX
00E6EA09    JMP 00E7B168
00E6EA0E    80F2 6E        XOR DL,6E
00E6EA11    20F9           AND CL,BH

我们在00E6E9F2这个地址右击----数据窗口跟随---内存地址,来查找下IAT,
004ADFFC //IAT的启始地址
..........
...........
004AE6C4 //IAT的结束地址
   
我们计算下RAV:ADFFC     RAV SIZE:6C8在这里我们又可以补一些代码了,代码如下:
call 004AE350                        // ⑤
mov ecx,dword ptr ds:[esi+10]        //原封不动
------------------------------------------------------------------------------------------------------
我们继续在代码段下断,SHIFT+F9运行,这里需要中断好几次,然后就来到了如下的程序段,这里分析下,免的代码混淆,我们往上看看,
00475868      DB C1    //这里就是OEP了,
00475869      DB 47                                 
0047586A      DB 70                                 
0047586B      DB DC
0047586C      DB 21                                
0047586D      DB F2
0047586E      DB 7C                                 
0047586F      DB 4C                                   
00475870      DB 65                                 
00475871      DB 4D                                   
00475872      DB B3
00475873      DB 4A                                   
00475874      DB 57                                 
00475875      DB 8D
00475876      DB B5
00475877      DB E3
00475878      DB 61                                   
00475879      NOP
0047587A      DB A2
0047587B      DB 14
0047587C      DB 25                                   
0047587D      DB 7C                                    
0047587E      DB A9
0047587F      DB 6F                                    
00475880      DB 18
00475881      DB 02
00475882      DB 8A
00475883      DB 27                                   
00475884      7DB 7F
00475885      DB 50                                    
00475886      DB 28                                   
00475887      DB 63                                
00475888      DB 34                              
00475889      DB 2B                           
0047588A      DB CE
0047588B      DB 1C
0047588C      DB 6D                                
0047588D      DB D0
0047588E      DB 59                              
00475890      DB A5
00475891      DB FE
00475892      DB 6B                        
00475893      DB A1
00475894      DB 31                           
00475895      DB D4
00475896      DB 37                          
00475897      DB B3
00475898      XOR AL,7B
0047589A   .  MOV DWORD PTR DS:[4D996C],EAX
0047589F   .  MOV EDX,DWORD PTR DS:[ESI+8]
004758A2   .  MOV DWORD PTR DS:[4D9970],EDX
004758A8   .  MOV ESI,DWORD PTR DS:[ESI+C]
004758AB   .  AND ESI,7FFF
004758B1   .  MOV DWORD PTR DS:[4D9964],ESI

在这里我们和VC++7的源程序进行对比,我们发现还有2行代码没有补上,
mov dword ptr ds:[7C36A4],ecx    这个7C36A4地址是怎么来的呢,根据前辈的经验知道,这个地址是在MOV DWORD PTR DS:[4D9964],ESI这个语句4D9964-4而来的,那么这里我们就要填成4D9960了,修改后的mov dword ptr ds:[4D9960],ecx
mov eax,dword ptr ds:[esi+4]    //这个原封不动
---------------------------------------------------------------------------------------------------
我们来补全代码吧 ,补好的OEP如下:
PUSH 60                                     ③
PUSH 004BB680                               ②
CALL 00475E8C                                ①
mov edi,94                               //这里原封不动
mov eax,edi                              //这里原封不动
call 00474430                              
mov dword ptr ss:[ebp-18],esp          //这里原封不动
mov esi,esp                            //这里原封不动
mov dword ptr ds:[esi],edi             //这里原封不动
push esi                                //这里原封不动
call 004AE350                        // ⑤
mov ecx,dword ptr ds:[esi+10]         //原封不动
mov dword ptr ds:[4D9960],ecx
mov eax,dword ptr ds:[esi+4]          //原封不动
MOV DWORD PTR DS:[4D996C],EAX
MOV EDX,DWORD PTR DS:[ESI+8]
MOV DWORD PTR DS:[4D9970],EDX
MOV ESI,DWORD PTR DS:[ESI+C]
AND ESI,7FFF
MOV DWORD PTR DS:[4D9964],ESI
------------------------------------------------------------------------------------------------------------------------------------------
看到补全刚刚好,好我们在00475868地址新建EIP,然后LORDPE脱壳,IR修复,IR修复的时候填上我们上面计算的RAV和SIZE,通过查找字符串可以看出来程序已经脱壳,PEID报的是VC++7,这个程序有自校验,程序运行后会消失,我搞了下自校验,虽然自校验没有了,但是程序被破坏了,有些功能无法使用,希望有大牛说下这个自校验怎么接触。

试练品下载地址如下:
http://www.namipan.com/d/4b95df1 ... 5d18faa19ec94881d00

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
斑竹那个试练程序下不了啊能给个连接下了学习一下么
2008-6-15 05:59
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
顶一下,最近完TMD的越来越多!~~
2008-6-17 07:58
0
游客
登录 | 注册 方可回帖
返回
//