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
沙发。还是用115下载。不要钱。哈哈 看看啦 阁下对Vprotect 的脚本太牛了~ {:1_931:}膜拜...
期待大牛能早点出个Vp 1.8.9-1.9.3 脱壳脚本~{:1_930:} 谢谢楼主提供。。。。 115下载不用钱滴。。。 马上下载用用 找个地方坐下来好好看看 这个脚本好长 搞不懂彻底的蒙
页:
[1]
2