wuqing1501 发表于 2011-3-3 20:44

Vprotect1.85-1.86 Unpacker脚本

有些累了就不写详细的分析了,有一些分析可以看我的上一篇文章VProtect1.XX-1.84 unpacker脚本http://www.52pojie.cn/thread-81680-1-1.html
   因为1.85和1.86升级后比1.84相比只有IAT的加密方式有所区别,但是区别不大,因为当时分析的DEMO主程序,现在时间有点长了,记得不是清楚了,也懒得再去分析一遍了,不过我把当时分析的一些过程已经放到了脚本中(我记得脚本中那些分析的过程都是vp1.86DEMO主程序的),所以想学习研究的,就自己再分析一下吧!
   在这里说一点,在这个版本的研究中发现VP处理IAT的时候在内存会生成一个表,而且这个表在到达OEP以后没有销毁,所以呢,其实还有个更简单的办法就是先到OEP然后在内存中找到这个表,因为VP加密IAT也是根据这个表来处理的,所以我们只要搞清楚VP是如何处理表中的数据的,以及处理IAT的算法,那么我们完全可以根据这个表来逆向计算出我们需要的数据,不过这个我没有去做,因为当时已经写好了这个脚本了,就懒得去研究那个表了,不过高版本中那个表就被和谐了,这个表只在1.86以下的版本中存在。
这里仅贴出我当时对这个表的分析:
00B4EE04B09315F4参与计算的KEY         
00B4EE086AE69F02这个貌似所有的位置都相同,可能是为了比较是否是要准备处理的开始,每次都会和这个比较只有计算的数值和这个相同才会处理IAT
00B4EE0C0051A81CVProtect.0051A81C+00400000 =填充地址
00B4EE1000000001这里貌似都是1我理解是是否决定处理IAT的标志,如果是0可能代表没有处理
00B4EE1400294823这里的可能是KEY
00B4EE1800000000这里的值为0 1 2 分别代表不同的处理方式
根据这个表再根据IAT具体的算法就可以用DLL来修复IAT了,其实在1.85和1.86的IAT处理中还是和1.84版本以前的处理方式一样分别是ADD ,not,XOR不过这次作者增加了一些难度,把这些简单的命令都给拆分了增加了一些逻辑AND 和NOT的运算,但是最终的运算结果还是没有变,所以我们只要按原来的算法分析就可以了,不过这次处理的代码发生了变化,具体是怎么样变化的呢,大家还是看下面脚本中记录,还有参数的特征码,就是计算过程中的指令。
    最后记着只要是用DLL修复VP的话一定要DUMP那几个区段,已及CODE段的读写属性(尤其对于主程序),还有主程序需要PATH的 一个地方详看我的上篇文章或者看NOOBY大牛的VP1.82demo脱壳主程序的脚本b中的代码然后自己程序中那个地址的代码作为特征码来修复吧。
    不说了就这样吧,想详细理解文章意思的建议还是自己拿起OD载入脚本,跟着脚本研究一下很容易就搞明白了。/*
///////////////////////////////////////////////////////////////////////////////
脚本   : Vprotect1.85-Vprotect 1.86 Unpacker
调试选项 : 1.设置 OllyDbg 忽略所有异常选项
2.使用海风月影全选项.
3.去掉'选项-调试设置-地址-解析修饰符号名称' 前面的勾,然后重新打开OD.跑脚本.(必须)
                4.使用PhantOm保护DRX。
         5.如果使用了第四点后,发现OD不能正常运行VP加壳的软件,请去掉所有对DRX的保护。
工具 : OllyDbg1.1, ODBGScript 1.65
感谢 : 感谢KISSY 的脚本,感谢苦力的DLL源码,感谢曾将帮助我的人!
////////////////////////////////////////////////////////////////////////////////////
*/
/////////////////////////////////////////////////////////////////////////////////////////////
/*
vm EXIT 特征码
00AD5D93    58            POP EAX                                 vmexits
00AD5D94    8903            MOV DWORD PTR DS:,EAX
00AD5D96    8B07            MOV EAX,DWORD PTR DS:
00AD5D98    8B5F 0C         MOV EBX,DWORD PTR DS:
00AD5D9B    8B4F 04         MOV ECX,DWORD PTR DS:
00AD5D9E    8B57 08         MOV EDX,DWORD PTR DS:
00AD5DA1    8B6F 14         MOV EBP,DWORD PTR DS:
00AD5DA4    8B77 18         MOV ESI,DWORD PTR DS:
00AD5DA7    FF77 24         PUSH DWORD PTR DS:
00AD5DAA    9D            POPFD
00AD5DAB    8B67 10         MOV ESP,DWORD PTR DS:
00AD5DAE    C747 50 0000000>MOV DWORD PTR DS:,0
00AD5DB5    8B7F 1C         MOV EDI,DWORD PTR DS:
00AD5DB8    C3            RETN                              vmexite
58 89 03 8B 07 8B 5F 0C 8B 4F 04 8B 57 08 8B 6F 14 8B 77 18 FF 77 24 9D 8B 67 10 C7 47 50 00 00
00 00 8B 7F 1C C3
*/
////////////////////////////////////////////////////////////////////////////////////////////////
/*
填充函数
008ADB40    8911            MOV DWORD PTR DS:,EDX
*/
/*
///////////////////////////////////////////////////////////////////
处理过程IAT
008AA352    3B440A 04       CMP EAX,DWORD PTR DS:         ; 比较计算的KEY是否正确正确则处理不正确继续找
008ADC81    3B440A 08       CMP EAX,DWORD PTR DS:         另外的比较
////////////////////////////////////////////////////////////////////////
获取IAT
008AB013    8B440A 0C       MOV EAX,DWORD PTR DS:         ; kernel32.MulDiv      获取IAT
///////////////////////////////////////////////////////////////////////
*/
/*
///////////////////////////////////////////////////////////////////////////
处理的类型 iat
008A85B1    837C0A 14 00    CMP DWORD PTR DS:,0
////////////////////////////////////////////////////////////////////////////
0not-->add-->not
///////////////////////////////////////////////////////////////////////////////
008AA8A8    F7D0            NOT EAX// iat 或地址                           先取反
再ADD
008ACDC4    03440A 10       ADD EAX,DWORD PTR DS: //取反后与数据段值相加
再取反
008AA422    F7D1            NOT ECX//上面的结果再取反
/////////////////////////////////////////////////////////////////////////////////////
008AE1A4    837C10 14 01    CMP DWORD PTR DS:,1      
/////////////////////////////////////////////////////////////////////////////////////
1not
008AE6A0    F7D1            NOT ECX                                  ; GDI32.SelectPalette
/////////////////////////////////////////////////////////////////////////////////////
08AA4B0    837C10 14 02    CMP DWORD PTR DS:,2
2not->or
008AB4F0    F71424          NOT DWORD PTR SS:                   ; GDI32.DeleteDC
(008AB1E6    F71424          NOT DWORD PTR SS:                   ; GDI32.DeleteDC)
上面就是把IAT取反
008AEAA7    090424          OR DWORD PTR SS:,EAX //相当于没有运行
008AEBE1    8B40 10         MOV EAX,DWORD PTR DS: // 把下面的参数给EAX
008A9C21    8D0418          LEA EAX,DWORD PTR DS:
008ACBD0    F71424          NOT DWORD PTR SS: 把参数取反
008AFBE1    F71424          NOT DWORD PTR SS: 获取IAT
008AE7E6    210424          AND DWORD PTR SS:,EAX //把参数和IAT分别取反后求余
008AC812    F7D0            NOT EAX再取反
得到的IAT与下面的值求and   求反然后结果与上面的最终结果求余
not 012D0865   FED2F79A
not 69525F90   96ADA06F
FED2F79Aand96ADA06F =9680A00A
not 9680A00A=697F5FF5
012D0865 and 69525F90=1250800
not 1250800   = FEDAF7FF
697F5FF5 and FEDAF7FF=685A57F5 填充值
///////////////////////////////////////////////////////////////////////////////////////
*/
/*
/////////////////////////////////////////////////////////////////////////////////////////
/*
00B4EE04B09315F4参与计算的KEY         
00B4EE086AE69F02这个貌似所有的位置都相同,可能是为了比较是否是要准备处理的开始,每次都会和这个比较只有计算的数值和这个相同才会处理IAT
00B4EE0C0051A81CVProtect.0051A81C+00400000 =填充地址
00B4EE1000000001这里貌似都是1我理解是是否决定处理IAT的标志,如果是0可能代表没有处理
00B4EE1400294823这里的可能是KEY
00B4EE1800000000这里的值为0 1 2 分别代表不同的处理方式
*/
/////////////////////////////////////////////////////////////////////////////////////////
////////////////
//oep0069C168
//getaddr 008ADB40    8911            MOV DWORD PTR DS:,EDX   固定代码
//getapi 008AB013    8B440A 0C       MOV EAX,DWORD PTR DS:固定
//getkey 2 008AEBE1    8B40 10         MOV EAX,DWORD PTR DS:
//            0 008ACDC4    03440A 10       ADD EAX,DWORD PTR DS:
//gettype 008A85B1    837C0A 14 00    CMP DWORD PTR DS:,0
////////////////////////////////////////////////////////////////////////////

var addr
var dword
var vpro
var dllname
var apiname
var imgbase
var imgbasefromdisk
var sizeofimg
var tmp1
var tmp2
var tmp3
var secbase
var secsize
var logfile
var oep
var fixtype
var typeadd
var typexor
var typenot
var vmiataddr
var dllapi
var getaddr
var getapi
var gettype
var getkey0
var getkey2
var antidump
var vmexit
mov logfile,"FakIat.txt"

//////////////////////////////////////////////////////////////////
//配置区 --此处数据如果自己能找到就自己找,如果找不到就用脚本!
/////////////////////////
//mov vmexit,0
//mov getaddr,0
//mov getapi,0
//mov gettype,0
//mov getkey0,0
//mov getkey2,0
/////////////////////////////////////////////////////////////////
//只需要一个数据提供OEP即可
mov oep,0069C168
/////////////////////////////////////////////////////////////////
cmp $VERSION, "1.64"
jb odbgver
GMI eip, MODULEBASE
mov imgbase, $RESULT
mov tmp1,
add tmp1, imgbase
mov signVA, tmp1
mov imgbasefromdisk,
mov sizeofimg,
mov tmp1, signVA
add tmp1, f8
mov tmp2, 0
mov tmp2, , 2
wrta logfile,tmp2
wrta logfile,"\r\n"
last:
mov secsize,
mov tmp3,
add tmp3, imgbase
mov secbase, tmp3
wrta logfile,secbase
wrta logfile,"\r\n"
wrta logfile,secsize
wrta logfile,"\r\n"
cmp tmp2, 1
je lab1
add tmp1, 28
sub tmp2, 1
jmp last
lab1:
cmp imgbasefromdisk, imgbase
je lab1_1
jmp error
lab1_1:
bc
cmp vmexit,0
jnz start
findvmexit:
find eip,#5889038B078B5F0C8B4F048B57088B6F148B7718FF77249D8B6710C74750000000008B7F1CC3#
cmp $RESULT,0
je nofind
mov vmexit, $RESULT
add vmexit,25
bp vmexit
cmp getaddr,0
jnz start
findgetaddr:
find eip,#8911#
cmp $RESULT,0
je nofind
mov getaddr, $RESULT

cmp getapi,0
jnz start
findgetapi:
find eip,#8B440A0C#
cmp $RESULT,0
je nofind
mov getapi, $RESULT
bp getapi
cmp gettype,0
jnz start
findgettype:
find eip,#837C0A1400#
cmp $RESULT,0
je nofind
mov gettype, $RESULT

cmp getkey0,0
jnz start
findgetkey0:
find eip,#03440A10#
cmp $RESULT,0
je nofind
mov getkey0, $RESULT

cmp getkey2,0
jnz start
findgetkey2:
find eip,#8B4010#
cmp $RESULT,0
je nofind
mov getkey2, $RESULT

start:
bp vmexit
cmp eip,oep
je exit
cmp eip,getapi
je findkey
esto
len
cmp $RESULT,8
jb start
scmpi ,"ole32.dll"
je loopfix
scmpi ,"advapi32.dll"
je loopfix
scmpi ,"user32.dll"
je loopfix
scmpi ,"kernel32.dll"
je loopfix
cmp ,"oleaut32.dll"
je loopfix
scmpi ,"advapi32.dll"
je loopfix
cmp ,"uxtheme.dll"
je loopfix
scmpi ,"ws2help.dll"
je loopfix
cmp ,"ws2_32.dll"
je loopfix
scmpi ,"winspool.dll"
je loopfix
cmp ,"MSCTFIME.dll"
je loopfix
scmpi ,"shell32.dll"
je loopfix
cmp ,"shlwapi.dll"
je loopfix
scmpi ,"GDI32.dll"
je loopfix
cmp ,"rpcrt4.dll"
je loopfix
scmpi ,"secur32.dll"
je loopfix
cmp ,"msvcrt.dll"
je loopfix
scmpi ,"version.dll"
je loopfix
cmp ,"comctl32.dll"
je loopfix
scmpi ,"iphlpapi.dll"
je loopfix
cmp ,"imagehlp.dll"
je loopfix
scmpi ,"psapi.dll"
je loopfix
cmp ,"msctf.dll"
je loopfix
scmpi ,"msimg32.dll"
je loopfix
cmp ,"imm32.dll"
je loopfix
scmpi ,"comdlg32.dll"
je loopfix
scmpi ,"ntdll.dll"
jne start
loopfix:
esto
bp oep
len
cmp $RESULT,0
je loopfix
sub $RESULT,4
readstr ,$RESULT
mov dllname,$RESULT
len
cmp $RESULT,0
je loopfix
readstr ,$RESULT
mov apiname,$RESULT
esto
esto
esto
add eax,ecx
add eax,7
mov addr,eax
mov dword,
sub eax,7
sub eax,ecx
cmp dword,0
je start
mov fixtype,0
mov antidump,0
wrta logfile,addr
wrta logfile,","
wrta logfile,dword
wrta logfile,","
wrta logfile,dllname
wrta logfile,","
wrta logfile,apiname
wrta logfile,","
wrta logfile,fixtype
wrta logfile,","
wrta logfile,antidump
wrta logfile,"\r\n"
jmp start

goon:
bp getapi
bp oep
cmp eip,oep
je exit
esto
findkey:
cmp eip,oep
je exit
cmp eip,getapi
je getapipro
cmp eip,getaddr
je getaddrpro
cmp eip,gettype
je gettypepro
cmp eip,getkey0
je getkey0pro
cmp eip,getkey2
je getkey2pro
jmp goon
getapipro:
sti
mov dword,eax
gn dword
mov dllname,$RESULT_1
mov apiname,$RESULT_2
cmp dllname,0
je goon
cmp apiname,0
je goon
bc
bp gettype
jmp goon
getaddrpro:
mov addr,ecx
mov antidump,1
jmp writetxt2
gettypepro:
mov fixtype,
cmp fixtype,0
je getkey0pro
cmp fixtype,2
je getkey2pro
cmp fixtype,1
je getkey1pro
getkey0pro:
bp getkey0
esto
mov dword,
bp getaddr
jmp goon
getkey2pro:
bp getkey2
esto
sti
mov dword,eax
bc
bp getaddr
jmp goon
getkey1pro:
mov dword,0
bc eip
bp getaddr
jmp goon

writetxt2:
cmp dllname,0
je goon
cmp apiname,0
je goon
wrta logfile,addr
wrta logfile,","
wrta logfile,dword
wrta logfile,","
wrta logfile,dllname
wrta logfile,","
wrta logfile,apiname
wrta logfile,","
wrta logfile,fixtype
wrta logfile,","
wrta logfile,antidump
wrta logfile,"\r\n"
jmp goon

error:
msg "dll不支持."
RET
odbgver:
msg "ODSCR版本要大于1.65"
ret
nofind:
msg "没有找到配置区参数请手动查找!"
ret
exit:
bc
bphwc
ret最后给出脱壳的脚本和DLL:
不再提供加壳的样本了,大家可以自己加壳测试,也可以拿主程序测试!

115盘下载地址:
http://u.115.com/file/f55f752d7d#
Vprotect1.85-1.86_Unpacker脚本.rar

xylguagua 发表于 2011-3-20 14:35

沙发。还是用115下载。不要钱。哈哈

whaqq 发表于 2011-3-20 21:18

看看啦

ares0534 发表于 2011-9-5 14:59

阁下对Vprotect 的脚本太牛了~ {:1_931:}膜拜...
期待大牛能早点出个Vp 1.8.9-1.9.3 脱壳脚本~{:1_930:}

辰龙飞飞 发表于 2011-6-4 11:14

谢谢楼主提供。。。。

wlcskf 发表于 2011-5-24 10:17

115下载不用钱滴。。。

mingming001 发表于 2011-5-23 18:15

马上下载用用

pwzh88 发表于 2011-9-29 11:09

找个地方坐下来好好看看

nightwish12075 发表于 2012-5-8 21:07

这个脚本好长

zyg1000 发表于 2012-7-5 18:22

搞不懂彻底的蒙
页: [1] 2
查看完整版本: Vprotect1.85-1.86 Unpacker脚本