宝峰科技

 找回密码
 注册

QQ登录

只需一步,快速开始

智能终端设备维修查询系统注册会员邮箱认证须知!
查看: 4218|回复: 1

促进钢蛋壳升级-简单分析及脱VProtect1.72demo版加密VB程序

[复制链接]

该用户从未签到

破解狼人 发表于 2010-10-31 23:48:02 | 显示全部楼层 |阅读模式

欢迎您注册加入!这里有您将更精采!

您需要 登录 才可以下载或查看,没有账号?注册

x
【软件名称】: vprotect1.72DEMO
【下载地址】: upk就有
【详细过程】
      今天闲来无事就看了看钢蛋壳的 IAT加密,在1.62和1.63的时候 就看过那个时候的IAT加密比较简单,当然在VM中的加密还是不好搞的 因为有太多的垃圾代码,一直没有搞定,所以就一直放下不看了,今天老是感觉应该看看VM中的加密是如何修复的,于是就有了这篇文章了。
      开始吧!
      为了方便研究,我直接用VProtect1.72DEMO版给VB程序加壳分别选取最大速度,中等强度和最高强度!呵呵,为什么选VB程序呢?因为VB的简单修复方式也容易些,用其他IAT被处理的会更复杂一些修复也难,还是先从最简单的看看吧!
      准备好了加壳的软件就可以开始了!
      在1.62、1.63的时候到OEP是很简单的,直接在CODE段下内存访问断点,然后F9,过了NAG窗口后,就挺停在了解码的位置,然后F7、F8、F9各一次就到达OEP了!但是这次1.72的好像对内存断点进行了处理,也不知道是不是我的系统的问题,用上面的方法就不行了,到达解码位置后,按F7软件就出错了!所以我们换个方法吧!这个软件的大流程是不变的,只要断在解码的地方,然后CODE段下断点,F9就到OEP了,既然壳不然下内存断点,那我们就在CODE段下个硬件写入断点吧,这样解码的时候照样能段下来,断在解码位置后,这次再按F7、F8就没有事了,然后再在CODE段下F2或者内存访问都行,F9一次直接到达OEP!
      好了我们正式开始吧
  
  1.先看下最大速度吧


0043A180 >  3BC0            CMP EAX,EAX                              ; OD载入后停在这里
0043A182    74 1C           JE SHORT 0043A1A0
0043A184    EB 00           JMP SHORT 0043A186
0043A186    DB2D 8CA14300   FLD TBYTE PTR DS:[43A18C]
0043A18C    FFFF            ???                                      ; Unknown command
0043A18E    FFFF            ???                                      ; Unknown command
0043A190    FFFF            ???                                      ; Unknown command
0043A192    FFFF            ???                                      ; Unknown command



然后在CODE段下硬件写入断点


003C0000   00001000                                       Priv   RW        RW
00400000   00001000   vb例子_V                PE header     Imag   R         RWE
00401000   00009000   vb例子_V     .text      code          Imag   R         RWE        ;在这里双击进去后下硬件写入断点
0040A000   00002000   vb例子_V     .data      data          Imag   R         RWE
0040C000   00002000   vb例子_V     .rsrc      resources     Imag   R         RWE
0040E000   0002B000   vb例子_V     VProtect                 Imag   R         RWE
00439000   00071000   vb例子_V     VProtect   SFX,imports   Imag   R         RWE
004B0000   00005000                                         Map    R E       R E



我们在CODE段双击进去


00401000   00009000   vb例子_V     .text      code          Imag   R         RWE        ;在这里双击进去后下硬件写入断点



来到这里


00401000    0000            ADD BYTE PTR DS:[EAX],AL   ;在这里下硬件写入断点
00401002    0000            ADD BYTE PTR DS:[EAX],AL
00401004    0000            ADD BYTE PTR DS:[EAX],AL
00401006    0000            ADD BYTE PTR DS:[EAX],AL
00401008    0000            ADD BYTE PTR DS:[EAX],AL
0040100A    0000            ADD BYTE PTR DS:[EAX],AL
0040100C    0000            ADD BYTE PTR DS:[EAX],AL



然后F9运行,出现了NAG窗口,关掉NAG窗口后,停在了这里


0043BB3A >  F3:A5           REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]        ;这里就是VP解码的地方
0043BB3C    FF2495 54BC4300 JMP DWORD PTR DS:[EDX*4+43BC54]
0043BB43    90              NOP
0043BB44    8BC7            MOV EAX,EDI
0043BB46    BA 03000000     MOV EDX,3



然后F7一次,F8一次,然后在CODE段下F2或者内存访问断点,F9运行来到这里,就是FLY说的光明之巅:


004014B0    68 28264000     PUSH 00402628            ;终于看到了光明之巅了,OEP
004014B5    E8 F0FFFFFF     CALL 004014AA
004014BA    0000            ADD BYTE PTR DS:[EAX],AL
004014BC    0000            ADD BYTE PTR DS:[EAX],AL
004014BE    0000            ADD BYTE PTR DS:[EAX],AL
004014C0    3000            XOR BYTE PTR DS:[EAX],AL
004014C2    0000            ADD BYTE PTR DS:[EAX],AL
004014C4    3800            CMP BYTE PTR DS:[EAX],AL



看下IAT吧


0040148C  - E9 17D70000     JMP 0040EBA8
00401491    90              NOP
00401492  - E9 39D70000     JMP 0040EBD0
00401497    90              NOP
00401498  - E9 5BD70000     JMP 0040EBF8
0040149D    90              NOP
0040149E  - E9 7DD70000     JMP 0040EC20
004014A3    90              NOP
004014A4  - E9 9FD70000     JMP 0040EC48
004014A9    90              NOP
004014AA  - E9 C1D70000     JMP 0040EC70
004014AF    90              NOP



都被处理成照样了,然后JMP到壳段,具体的加密方式自己看下加密后软件吧,我们主要看下IAT的解码,主要是下面这几句:


00414B20    B8 7FDE09C4     MOV EAX,C409DE7F
00414F80    BB AD16373C     MOV EBX,3C3716AD
0042ABD0    03C3            ADD EAX,EBX
0041BCE0    8B00            MOV EAX,DWORD PTR DS:[EAX]
00419430    8D0418          LEA EAX,DWORD PTR DS:[EAX+EBX]
00413480    874424 24       XCHG DWORD PTR SS:[ESP+24],EAX



      上面这几句就是解密IAT的,中间穿插了很多的垃圾指令,当程序运行到过这条 LEA EAX,DWORD PTR DS:[EAX+EBX] 指令的时候,真实的IAT地址就存放在EAX中。感觉这个地方和VMP有些相似!
      本人菜鸟不会些解码,但是,既然程序运行过程中在EAX中出现了真实的IAT,那么我们可以写个脚本,在程序中查找被处理的IAT 也就是 E9???????? 这样类型的,然后判断下是不是被处理的IAT,如果不是就查找下一个,如果是的话,就单步,一直到EAX中出现真实的IAT地址,我们就把EAX的值写回到原来调用的地方,最后再后UIF处理一下就可以了。
      贴出我写的脚本吧,用以前的脚本修改的,可能有些乱,脚本也写的难看,最主要的是针对这种加密方式,这种处理方式可以说效率特别低,但是我太菜了,没有找到好的处理方式。


var neicuncodebase            
var neicuncodesize   
var oep
var ptr
var ip1
var addr
var refaddr
var temesp
var ptr1
var code
var kebase1
var kebase2
var iataddr

mov kebase1,0040e000
mov oep,eip
mov temesp,esp
mov eip,kebase1

start:              
               mov esp,temesp
               mov eip,00401000 //???????
               mov ptr1,eip

tzm3iatfind:
               
               mov temesp,esp
               find  ptr1, #e9????????#   
               je    exit                     
               mov   ptr,$RESULT   
               mov   ptr1,ptr
               mov   eip,ptr
               mov   refaddr, ptr
               sti
               mov ip1, eip
               mov ip1, [ip1]
               and ip1, 0ff
               cmp ip1, e9
               jnz nextfind
               sti
               mov ip1, eip
               mov ip1, [ip1]
               and ip1, 0ff
               cmp ip1, 68
               jnz nextfind            
               cmp eip,kebase2
               ja tzm3iataddrfind
               cmp eip,kebase1
               jb tzm3iatfind              
               
tzm3iataddrfind:

               sti
               mov iataddr,eax
               gn iataddr
               cmp   $RESULT,0
               je tzm3iataddrfind
tzm3iatfix:
            
               sub eax,refaddr
               SUB eax,5
               mov refaddr,ptr
               mov [refaddr],#e9#
               add refaddr,1
               mov [refaddr],eax,4
               mov esp,temesp
nextfind:
               add ptr1,6
               jmp tzm3iatfind
exit:
              mov esp,temesp
              mov eip,oep
              ret



照样脚本处理好后,用UIF修复一下,然后LP,然后IR修复就可以了!

该用户从未签到

 楼主| 破解狼人 发表于 2010-10-31 23:49:18 | 显示全部楼层
2、接下来看些中等强度和最大强度吧

      流程和上面是一样的,到达OEP的方法一样,但是中等强度和最大强度,对IAT的加密采取了很WS的方式,代码里面全是垃圾代码,本来我想把垃圾代码全部清除,然后再单步跟的,发现那个不是一般的费劲啊,不过还是写了个脚本来清理垃圾指令。共发现5种,脚本如下:


var addr
var yeip
var temsep
var long
var addr1
huazhiliang1:
mov yeip,eip
mov addr,eip
mov addr1,eip
mov long,460000  //这里是处理的代码长度,可以自己根据实际情况修改,下面的这个参数都一样
add addr1,long

findhua1:

mov temesp,esp
find eip,#740EEB0E????????750E740C????????74F675F4#
cmp $RESULT,0
je exit1
mov eip,$RESULT
mov [eip],#909090909090909090909090909090909090909090909090#
mov esp,temesp
add eip,20
cmp eip,addr1
jg  exit1
jmp findhua1

exit1:
mov eip,yeip

huazhiilang2:

var addr
var yeip
var temsep
var long
var addr1

mov yeip,eip
mov addr,eip
mov addr1,eip
mov long,460000
add addr1,long

findhua2:

mov temesp,esp
find eip,#740A7508#
cmp $RESULT,0
je exit2
mov eip,$RESULT
mov [eip],#740A75089090909090909090#
mov esp,temesp
add eip,20
cmp eip,addr1
jg  exit2
jmp findhua2

exit2:
mov eip,yeip

huzhiiang3:

var addr
var yeip
var temsep
var long
var addr1

mov yeip,eip
mov addr,eip
mov addr1,eip
mov long,460000
add addr1,long

findhua3:

mov temesp,esp
find eip,#7403#
cmp $RESULT,0
je exit3
mov eip,$RESULT
mov [eip],#7403909090#
mov esp,temesp
add eip,20
cmp eip,addr1
jg  exit3
jmp findhua3

exit3:
mov eip,yeip


huazhiling4:

var addr
var yeip
var temsep
var long
var addr1

mov yeip,eip
mov addr,eip
mov addr1,eip
mov long,460000
add addr1,long

findhua4:

mov temesp,esp
find eip,#c3eb08#
cmp $RESULT,0
je exit4
mov eip,$RESULT
mov [eip],#9090909090909090909090#
mov esp,temesp
add eip,20
cmp eip,addr1
jg  exit4
jmp findhua4

exit4:
mov eip,yeip

var addr
var yeip
var temsep
var long
var addr1

mov yeip,eip
mov addr,eip
mov addr1,eip
mov long,460000
add addr1,long

findhua5:

mov temesp,esp
find eip,#740EEB0E????????750E740C????????????75F4????????#
cmp $RESULT,0
je exit5
mov eip,$RESULT
mov [eip],#909090909090909090909090909090909090909090909090#
mov esp,temesp
add eip,20
cmp eip,addr1
jg  exit5
jmp findhua5

exit5:
mov eip,yeip
ret



      既然清理垃圾指令的方法行不同,那我们只好换个方法吧,我的思路是,不管在VM中还是在垃圾指令里,程序总要返回IAT的真实地址的,也就是在垃圾指令或VM中运行过程中,寄存器中总会出现IAT的真实地址的,那我们就先看看在什么地方在那个寄存器里会出现真实的地址,寄存器是固定的还是随机的,写个小 脚本测试一下吧。


var addr
Find:
sti
mov addr,eax
mov addr,[addr]
gn addr
cmp $RESULT,0
jne zt
mov addr,ecx
mov addr,[addr]
gn addr
cmp $RESULT,0
jne zt
mov addr,ebx
mov addr,[addr]
gn addr
cmp $RESULT,0
jne zt
mov addr,edx
mov addr,[addr]
gn addr
cmp $RESULT,0
je Find
mov addr,esp
mov addr,[addr]
gn addr
cmp $RESULT,0
je Find

zt:
pause



      具体的代码我就补写了,全是垃圾指令而且很多很多,当寄存器中出现IAT的真实地址的时候OD就会停下来,我们就可以分析到底最关键的出现IAT的代码是那些了!在VM中跑照样的脚本,那不是一般的慢,我都不知道今天晚上电脑跑了多长的时间才跑完的! 最后经过测试中等强度的加密方式会在壳段中以下代码的时候出现真实的地址:
  
      对于中等强度:


0041EE71    C3              RETN
0041EE72    50              PUSH EAX
0041EE73    53              PUSH EBX  ;中等强度的加密方式,在壳段中只有一处这个代码,也就是所有的IAT都要经过这里,而当程序运行到这条指令的时候,EBX中就是真实的IAT。   
0041EE74    51              PUSH ECX



对于最大强度,和中等强度一样,只是关键代码和寄存器不一样而已;


0041EE71    59              POP ECX
0041EE72    5B              POP EBX
0041EE73    58              POP EAX
0041EE74    8BC1            MOV EAX,ECX
0041EE76    8B4F 24         MOV ECX,DWORD PTR DS:[EDI+24]
0041EE79    51              PUSH ECX
0041EE7A    9D              POPFD
0041EE7B    03C3            ADD EAX,EBX
0041EE7D    8B5F 44         MOV EBX,DWORD PTR DS:[EDI+44]
0041EE80    8903            MOV DWORD PTR DS:[EBX],EAX
0041EE82    9C              PUSHFD                              ;//最大强度的加密方式,在壳段中只有一处这个代码,也就是所有的IAT都要经过这里,而当程序运行到这条指令的时候,EAX中就是真实的IAT。
0041EE83    58              POP EAX



      而且经过测试,对于加密后的VB程序,中等强度和最大强度都存在了这个特征码,而且利用的寄存器是固定的,照样也方便写脚本了。好了有了上面的分析就可以写个脚本来查找IAT了。没有太多的分析大家看脚本吧,最好用脚本跑一下就能明白了!脚本如下:


var neicuncodebase            
var neicuncodesize   
var oep
var ptr
var ip1
var addr
var refaddr
var temesp
var ptr1
var code
var kebase1
var kebase2
var iataddr

mov kebase1,0040e000   //第一个壳段
mov kebase2,00507000   //第二个壳段
mov oep,eip
mov temesp,esp

findkebase1tzm2:

              mov eip,kebase1
              find  eip, #C3505351#  //中等强度的特征码,最大强度特征码为“#595B588BC18B4F24519D03C38B5F4489039C58#”
              cmp   $RESULT,0
              je findkebase2tzm2
              add  $RESULT,2         //因为中等强度代码当运行到PUSH EBX 这条指令的时候,EBX是真实的地址所以这里加2,同理,对于最大强度这里应该加11
/*                                   0041EE71    C3              RETN
                                     0041EE72    50              PUSH EAX
                                     0041EE73    53              PUSH EBX  ;EBX 中就是真实的IAT。   
                                     0041EE74    51              PUSH ECX
*/         
              bp $RESULT

findkebase2tzm2:

               mov eip,kebase2
               find  eip, #C3505351#   //中等强度的特征码,最大强度特征码为“#595B588BC18B4F24519D03C38B5F4489039C58#”
               cmp   $RESULT,0
               je exit
               add  $RESULT,2          //这里同上面,好像这段脚本就没有用,因为只是用了第一个壳段
               bp $RESULT
               
               mov esp,temesp
               mov eip,00401000 //查找的起始位置
               mov ptr1,eip

tzm2iatfind:
               
               mov temesp,esp
               find  ptr1, #e9????????#    //这里查找的就是JMP  xxxx
               je    exit                     
               mov   ptr,$RESULT   
               mov   ptr1,ptr
               mov   eip,ptr
               mov   refaddr, ptr
               sti
               mov ip1, eip
               mov ip1, [ip1]
               and ip1, 0ff
               cmp ip1, e9
               jnz nextfind
               sti
               mov ip1, eip
               mov ip1, [ip1]
               and ip1, 0ff
               cmp ip1, 68
               jnz nextfind            
               cmp eip,kebase2
               ja tzm2iataddrfind
               cmp eip,kebase1
               jb tzm2iatfind            
              
tzm2iataddrfind:
               esto
               mov iataddr,ebx     ;//这里就是出现IAT真实地址的寄存器,对于中等加密是EBX,对于最大强度,这里是EAX.
               gn iataddr
               cmp   $RESULT,0
               je tzm2iataddrfind

tzm2iatfix:            
               sub ebx,refaddr
               SUB ebx,5
               mov refaddr,ptr
               mov [refaddr],#e9#
               add refaddr,1
               mov [refaddr],ebx,4
               mov esp,temesp
nextfind:
               add ptr1,6
               jmp tzm2iatfind
exit:
               mov esp,temesp
               mov eip,oep
               ret



这个脚本只适用于我自己加的VB程序的壳,但是处理的原理是一样的,好了分析就这么多吧,应该说没有怎么分析IAT具体是怎么加密的,只是找到了一个解密IAT的方法,由于脚本中没有做太多的判断,所以运行脚本的时候需要自己看着脚本跑,当修复完IAT后,就自己把脚本停下来,这个时候由于寄存器的值都被破坏了这样修复的程序是不能运行的,不过我们可以打开加壳的软件跑到OEP后根据没有破坏的寄存器把修复好的寄存器的值全都修改过来,然后 再用UIF修复 LP dump  IR修复就可以了,一定要记住一点哦,dump 以前一定要取消那些断点啊,尤其是F2断点,由于我刚开始没有取消断点,结果DUMP 修复后的程序不能运行,跟踪后发现是F2断点的原因,DUMP后的程序F2断点的 地方变成了CC 也就INT3 。好了VP的IAT分析就到这里了,提供一下我练习的加壳后以及脱壳后的软件吧,方便像我一样的菜鸟练习。
      
  
--------------------------------------------------------------------------------
【经验总结】
1、还是自己动手一遍比看别人的文章百遍都起作用。
2、一直以为在VM中或者垃圾指令中的关键代码自己跟踪不到,结果用最笨的方法还是找到了!这就说明不管做什么只要去努力去试试总有成功的机会!
3、建议苦力在下个版本中对于中等强度和最大强度加密中取消那两个特征码,或者F9运行的时候出错那样会增大修复难度,至少现在我感觉,最大速度的加密修复速度却是最慢的!修复的时候F9运行就出错,对于寄存器的使用,是否可以借鉴别的壳改为随机的那样也增加修复难度。
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于wuqing1501(笨笨鼠), 转载请注明作者并保持文章的完整, 谢谢!

                                                       2010年07月18日 AM 02:31:16
您需要登录后才可以回帖 登录 | 注册

本版积分规则

免责声明

本站中所有被研究的素材与信息全部来源于互联网,版权争议与本站无关。本站所发布的任何软件编程开发或软件的逆向分析文章、逆向分析视频、补丁、注册机和注册信息,仅限用于学习和研究软件安全的目的。全体用户必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。学习编程开发技术或逆向分析技术是为了更好的完善软件可能存在的不安全因素,提升软件安全意识。所以您如果喜欢某程序,请购买注册正版软件,获得正版优质服务!不得将上述内容私自传播、销售或者用于商业用途!否则,一切后果请用户自负!

QQ|Archiver|手机版|小黑屋|联系我们|宝峰科技 ( 滇公网安备 53050202000040号 | 滇ICP备09007156号-2 )

Copyright © 2001-2023 Discuz! Team. GMT+8, 2024-12-22 16:43 , File On Powered by Discuz! X3.49

快速回复 返回顶部 返回列表