VProtect1.XX-1.84 unpacker
【文章标题】: VProtect1.XX-1.84 unpacker【文章作者】: wuqing1501(笨笨鼠)
【作者邮箱】: 木有
【作者主页】: 木有
【作者QQ号】: 木有
【下载地址】: 自己搜索下载
【保护方式】: VProtect默认加壳
【使用工具】: 老三样
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
在这里呢首先我先要感谢感谢NOOBY、KISSY和COOOLIE,因为KISSY和nooby 我学会了脱VMP用DLL修复的方法,通过研究NOOBY.DLL和kissy.dll我明白了这个DLL的原理,所以才有这篇文章。
今天说下VProtect1.84以下版本的脱壳方法,其实我感觉脱VP的话,nooby在脚本区公布的那个主程序1.82的脱壳脚本可以说是相当的无敌,应该可以通杀1.82以下所有的版本,但是对于高版本的话,可能需要一些修改,但是这个我没有研究过所以在这里就不多说了。我现在说另外一种方法,相信大家都看过kissy牛脱VMP的视频吧?其实我的方法就是学习kissy牛还有NOOBY牛脱VMP用DLL修复IAT的方法,但是VP和VMP有区别,因为VMP在IAT的处理过程中,只使用了一种算法就是加法,而VP为了防止kissy.dll还有nooby.dll的使用,所以在1.84以及以前的版本中都使用了三种算法,那就是:相加、异或、取反。所以我们直接用脱VMP的方法去脱VP是不行的,那两个DLL的算法都是加法,所以我们要自己写个DLL,其实这个DLL的原理,相信使用过DLL修复的人都明白的原理还是很简单的,但是我是个菜鸟,不会编程,用易语言写那个DLL最后总是因为有个问题没有解决最后没有成功,最后还是拿到了kissy.dll的源码进行了修改,在这里我先十分感谢KISSY 和COOOLIE,所以我们现在要做的工作就是:修改KISSY脱VMP的脚本,修改COOOLIE的kissy.dll的源码。
在这里我不公开kissy.dll的源码,只公开成品还有脚本,因为那个源码我基本上只修改了一下那个算法的地方所以其他的东西都还是原来的,在这里还请KISSY牛海涵。
脚本:/*
///////////////////////////////////////////////////////////////////////////////
脚本 : VP1.XX-Vprotect 1.84 Unpacker
调试选项 : 1.设置 OllyDbg 忽略所有异常选项
2.使用海风月影全选项.
3.去掉'选项-调试设置-地址-解析修饰符号名称' 前面的勾,然后重新打开OD.跑脚本.(必须)
4.使用PhantOm保护DRX。
工具 : OllyDbg1.1, ODBGScript 1.65
感谢 : 感谢KISSY 的脚本,感谢苦力的DLL源码,感谢那些曾经帮助我的人!
////////////////////////////////////////////////////////////////////////////////////
var getapi
var write
var addr
var dword
var vpro
var rapi
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
mov logfile,"FakIat.txt"
/////////////////////////
//配置区
/////////////////////////
mov vmexit,008D21ED //VM出口
mov oep,0069C168
mov write,008AC492 //填充函数
mov typeadd,008A8F41 //对IAT进行SUB处理的地址
mov typexor,008AA673 //对IAT进行xor处理的地址
mov typenot,008AC257 //对IAT进行not处理的地址
/////////////////////////
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
start:
bp vmexit
cmp eip,oep
je exit
cmp eip,write
je findkey
cmp eip,typeadd
je findkey
cmp eip,typexor
je findkey
cmp eip,typenot
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 typeadd
bp typexor
bp typenot
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
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
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,"\r\n"
jmp start
goon:
cmp eip,oep
je exit
bp typeadd
bp typexor
bp typenot
bp write
bp oep
esto
findkey:
cmp eip,oep
je exit
cmp eip,typeadd
je addkey
cmp eip,typexor
je xorkey
cmp eip,typenot
je notkey
jmp goon
addkey:
mov fixtype,0
mov dword,
gn edx
mov dllname,$RESULT_1
mov apiname,$RESULT_2
cmp $RESULT,0
je goon
bc eip
bp write
esto
bc eip
mov addr,edx
jmp writetxt2
xorkey:
mov fixtype,2
mov dword,
gn ecx
mov dllname,$RESULT_1
mov apiname,$RESULT_2
cmp $RESULT,0
je goon
bc eip
bp write
esto
bc eip
mov addr,edx
jmp writetxt2
notkey:
mov fixtype,1
mov dword,edx
gn edx
mov dllname,$RESULT_1
mov apiname,$RESULT_2
cmp $RESULT,0
je goon
bc eip
bp write
esto
bc eip
mov addr,edx
writetxt2:
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,"\r\n"
jmp goon
error:
msg "dll不支持."
RET
odbgver:
msg "ODSCR版本要大于1.65"
ret
exit:
bc
bphwc
ret脚本我就不多说了,这里要说明一下配置区的几个参数。
1、vmexit
也就是VP的VM出口,对于1.93以下的版本,VP加壳出来的VM出口基本上都是固定的。VM出口代码如下:58 POP EAX
8903 MOV DWORD PTR DS:,EAX
8B07 MOV EAX,DWORD PTR DS:
8B5F 0C MOV EBX,DWORD PTR DS:
8B4F 04 MOV ECX,DWORD PTR DS:
8B57 08 MOV EDX,DWORD PTR DS:
8B6F 14 MOV EBP,DWORD PTR DS:
8B77 18 MOV ESI,DWORD PTR DS:
FF77 24 PUSH DWORD PTR DS:
9D POPFD
8B67 10 MOV ESP,DWORD PTR DS:
C747 50 0000000>MOV DWORD PTR DS:,0
8B7F 1C MOV EDI,DWORD PTR DS:
C3 RETN二进制:
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
这段代码基本上是固定的所以要找VM出口的话 这段代码中的任意一些指令都可以作为VM出口的特征码。我们需要找的VM出口就是那个RETN的地方。
2、oep
对于VP加壳的程序,寻找OEP的话我在以前的文章也有说过,NOOBY牛的脱壳脚本中也有方法,我这里再说一个就是对VirtualProtect函数下断(注意VP的检测不要在段首下F2,可以在段尾或者中间F2),F9运行,然后取消VirtualProtect断点,CODE段下内存访问断点,F9运行一般都可以到OEP!
3、write
其实就是相当于VMP中的填充函数,代码如下8902 MOV DWORD PTR DS:,EAX至于这段代码怎么找的话,可以在代码中搜索所有的这个二进制,然后判断一下哪句代码是我们需要的当然这样是很麻烦的,说下稍微简单一点的方法吧。我们可以先找其他的特征码也就是下面的对IAT处理的代码都可以作为特征码,而且这个特征码一般在VP加壳的程序中只有一句,找到后我们下段,然后然后运行程序停下来后就是处于IAT处理的代码中,然后我们可以学习NOOBY牛的方法CTRL+T 在最后一项中打勾,并输入我们需要找的代码
MOV DWORD PTR DS:,EAX
NOT EDX
然后CTRL+F11就可以了这样停下来后我们就可以找到这个填充函数了。
4、typeaddtypexortypenot
在这里我们要先知道VP是如何处理iat的这个我在很早以前发过类似的文章都有说明的这里就不在说了,我只说对于IAT的处理算法,脚本中原来只有一个算法,所以只要知道填充地址和填充值,我们就可以用DLL计算出来API,但是VP有三种算法,所以我们要先搞清楚VP是如何处理IAT的,代码如下:typeadd :
2B5401 10 SUB EDX,DWORD PTR DS:
typexor:
334C10 10 XOR ECX,DWORD PTR DS:
typenot:
F7D2 NOT EDX 也就是VP中进行IAT处理的算法的时候用的就是这三条语句,所以我们需要在加壳的程序中找到这三条语句就可以了,对于ADD和XOR的两种很好找因为一般情况下,VP这个版本加壳的程序中这两句代码都只有一句,直接搜二进制就可以了,但是对于NOT类型的不好找不过我们可以使用找WRITE参数的方法一样找到。
找到了这些参数基本上就算是完工了,可以跑脚本了,在这里说下我自己的一点经验吧,如果用DLL修复VP也好VMP也好,使用脚本插件的时候一定要使用1.65或者比1.65稍微大一点点比如1.67的版本,不要使用高版本哦!高版本生成的都是多行的处理起来会非常苦难,如果使用1.65版本的话,生成的IAT文件中就会有很多的“黑块”,这个黑块就是空格吧,但是有这个的存在DLL就不能正常运行,所以我们在这里要处理“黑块”。对于处于每行中最后的几个黑块是不影响DLL使用的,影响DLL的是每行中间和“,”在一块的那个黑块,所以我们可以使用文本编辑器中的替换功能,具体你使用什么软件都可以,只要他能识别出IAT文件中的黑块就可以,可以同时选中“黑块”和“,”然后在替换框那里拷贝进去,而要替换的字符那里就填写“,”,这样的话就可以把所有的影响使用的黑块全都清除掉了。
最后因为VP1.8X版本貌似为了ANTIdump会申请三个大小为8000区段用来计算IAT,所以脱壳后要dump这三个区段补到脱壳后的程序中。修正OEP和CODE段修正为可写。
至此,基本上所有的功能就算完成了,给脱壳后的文件添加DLL就可以了!
在这里我就不提供样品了,大家可以拿DEMO主程序测试!
脚本和DLL:
http://u.115.com/file/f58c2d8b07#
VProtect1.XX-1.84_unpacker.rar
--------------------------------------------------------------------------------
【经验总结】
1、多动手分析比看文章强百倍。
2、以前脱壳修复IAT的时候只要找RETN或者返回找到真实的API填充到需要修复的地方就可以了,而这次这个方式却要分析IAT的加密算法,VP1.84以下版本的算法简单没有那么多的干扰和垃圾代码,对于高版本的就不一样了很多的垃圾代码干扰分析,所以整个分析下
来很累,但是对于分析算法来说还是让自己学到不少的东西!
3、谢谢KISSY、NOOBY、COOOLIE还有曾经帮助过我的所有人!
--------------------------------------------------------------------------------
【版权声明】: 本文原创,小菜一个, 转载请注明作者并保持文章的完整, 谢谢!
2011年03月01日 10:40:16
小白路过!~ 还是老样子 哎 不评论壳了
感谢了
膜拜一下{:1_918:} 非常的不错啊 !~膜拜大牛
原来有一丝心痛叫做无奈! 功力还是不够啊看得头痛 来晚了、 膜拜强大的楼主