/*
///////////////////////////////////////////////////////////////////////////////
脚本 : 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:[EBX],EAX
00AD5D96 8B07 MOV EAX,DWORD PTR DS:[EDI]
00AD5D98 8B5F 0C MOV EBX,DWORD PTR DS:[EDI+C]
00AD5D9B 8B4F 04 MOV ECX,DWORD PTR DS:[EDI+4]
00AD5D9E 8B57 08 MOV EDX,DWORD PTR DS:[EDI+8]
00AD5DA1 8B6F 14 MOV EBP,DWORD PTR DS:[EDI+14]
00AD5DA4 8B77 18 MOV ESI,DWORD PTR DS:[EDI+18]
00AD5DA7 FF77 24 PUSH DWORD PTR DS:[EDI+24]
00AD5DAA 9D POPFD
00AD5DAB 8B67 10 MOV ESP,DWORD PTR DS:[EDI+10]
00AD5DAE C747 50 0000000>MOV DWORD PTR DS:[EDI+50],0
00AD5DB5 8B7F 1C MOV EDI,DWORD PTR DS:[EDI+1C]
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:[ECX],EDX
*/
/*
///////////////////////////////////////////////////////////////////
处理过程IAT
008AA352 3B440A 04 CMP EAX,DWORD PTR DS:[EDX+ECX+4] ; 比较计算的KEY是否正确正确则处理不正确继续找
008ADC81 3B440A 08 CMP EAX,DWORD PTR DS:[EDX+ECX+8] 另外的比较
////////////////////////////////////////////////////////////////////////
获取IAT
008AB013 8B440A 0C MOV EAX,DWORD PTR DS:[EDX+ECX+C] ; kernel32.MulDiv 获取IAT
///////////////////////////////////////////////////////////////////////
*/
/*
///////////////////////////////////////////////////////////////////////////
处理的类型 iat
008A85B1 837C0A 14 00 CMP DWORD PTR DS:[EDX+ECX+14],0
////////////////////////////////////////////////////////////////////////////
0 not-->add-->not
///////////////////////////////////////////////////////////////////////////////
008AA8A8 F7D0 NOT EAX // iat 或地址 先取反
再ADD
008ACDC4 03440A 10 ADD EAX,DWORD PTR DS:[EDX+ECX+10] //取反后与数据段值相加
再取反
008AA422 F7D1 NOT ECX //上面的结果再取反
/////////////////////////////////////////////////////////////////////////////////////
008AE1A4 837C10 14 01 CMP DWORD PTR DS:[EAX+EDX+14],1
/////////////////////////////////////////////////////////////////////////////////////
1 not
008AE6A0 F7D1 NOT ECX ; GDI32.SelectPalette
/////////////////////////////////////////////////////////////////////////////////////
08AA4B0 837C10 14 02 CMP DWORD PTR DS:[EAX+EDX+14],2
2 not->or
008AB4F0 F71424 NOT DWORD PTR SS:[ESP] ; GDI32.DeleteDC
(008AB1E6 F71424 NOT DWORD PTR SS:[ESP] ; GDI32.DeleteDC)
上面就是把IAT取反
008AEAA7 090424 OR DWORD PTR SS:[ESP],EAX //相当于没有运行
008AEBE1 8B40 10 MOV EAX,DWORD PTR DS:[EAX+10] // 把下面的参数给EAX
008A9C21 8D0418 LEA EAX,DWORD PTR DS:[EAX+EBX]
008ACBD0 F71424 NOT DWORD PTR SS:[ESP] 把参数取反
008AFBE1 F71424 NOT DWORD PTR SS:[ESP] 获取IAT
008AE7E6 210424 AND DWORD PTR SS:[ESP],EAX //把参数和IAT分别取反后求余
008AC812 F7D0 NOT EAX 再取反
得到的IAT与下面的值求and 求反 然后结果与上面的最终结果求余
not 012D0865 FED2F79A
not 69525F90 96ADA06F
FED2F79A and 96ADA06F =9680A00A
not 9680A00A=697F5FF5
012D0865 and 69525F90=1250800
not 1250800 = FEDAF7FF
697F5FF5 and FEDAF7FF=685A57F5 填充值
///////////////////////////////////////////////////////////////////////////////////////
*/
/*
/////////////////////////////////////////////////////////////////////////////////////////
/*
00B4EE04 B09315F4 参与计算的KEY
00B4EE08 6AE69F02 这个貌似所有的位置都相同,可能是为了比较是否是要准备处理的开始,每次都会和这个比较只有计算的数值和这个相同才会处理IAT
00B4EE0C 0051A81C VProtect.0051A81C +00400000 =填充地址
00B4EE10 00000001 这里貌似都是1我理解是是否决定处理IAT的标志,如果是0可能代表没有处理
00B4EE14 00294823 这里的可能是KEY
00B4EE18 00000000 这里的值为0 1 2 分别代表不同的处理方式
*/
/////////////////////////////////////////////////////////////////////////////////////////
////////////////
//oep 0069C168
//getaddr 008ADB40 8911 MOV DWORD PTR DS:[ECX],EDX 固定代码
//getapi 008AB013 8B440A 0C MOV EAX,DWORD PTR DS:[EDX+ECX+C] 固定
//getkey 2 008AEBE1 8B40 10 MOV EAX,DWORD PTR DS:[EAX+10]
// 0 008ACDC4 03440A 10 ADD EAX,DWORD PTR DS:[EDX+ECX+10]
//gettype 008A85B1 837C0A 14 00 CMP DWORD PTR DS:[EDX+ECX+14],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, [imgbase+3C]
add tmp1, imgbase
mov signVA, tmp1
mov imgbasefromdisk, [signVA+34]
mov sizeofimg, [signVA+50]
mov tmp1, signVA
add tmp1, f8
mov tmp2, 0
mov tmp2, [signVA+6], 2
wrta logfile,tmp2
wrta logfile,"\r\n"
last:
mov secsize, [tmp1+8]
mov tmp3, [tmp1+0C]
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 [ecx]
cmp $RESULT,8
jb start
scmpi [ecx],"ole32.dll"
je loopfix
scmpi [ecx],"advapi32.dll"
je loopfix
scmpi [ecx],"user32.dll"
je loopfix
scmpi [ecx],"kernel32.dll"
je loopfix
cmp [ecx],"oleaut32.dll"
je loopfix
scmpi [ecx],"advapi32.dll"
je loopfix
cmp [ecx],"uxtheme.dll"
je loopfix
scmpi [ecx],"ws2help.dll"
je loopfix
cmp [ecx],"ws2_32.dll"
je loopfix
scmpi [ecx],"winspool.dll"
je loopfix
cmp [ecx],"MSCTFIME.dll"
je loopfix
scmpi [ecx],"shell32.dll"
je loopfix
cmp [ecx],"shlwapi.dll"
je loopfix
scmpi [ecx],"GDI32.dll"
je loopfix
cmp [ecx],"rpcrt4.dll"
je loopfix
scmpi [ecx],"secur32.dll"
je loopfix
cmp [ecx],"msvcrt.dll"
je loopfix
scmpi [ecx],"version.dll"
je loopfix
cmp [ecx],"comctl32.dll"
je loopfix
scmpi [ecx],"iphlpapi.dll"
je loopfix
cmp [ecx],"imagehlp.dll"
je loopfix
scmpi [ecx],"psapi.dll"
je loopfix
cmp [ecx],"msctf.dll"
je loopfix
scmpi [ecx],"msimg32.dll"
je loopfix
cmp [ecx],"imm32.dll"
je loopfix
scmpi [ecx],"comdlg32.dll"
je loopfix
scmpi [ecx],"ntdll.dll"
jne start
loopfix:
esto
bp oep
len [ecx]
cmp $RESULT,0
je loopfix
sub $RESULT,4
readstr [ecx],$RESULT
mov dllname,$RESULT
len [edx]
cmp $RESULT,0
je loopfix
readstr [edx],$RESULT
mov apiname,$RESULT
esto
esto
esto
add eax,ecx
add eax,7
mov addr,eax
mov dword,[addr+7]
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,[edx+ecx+14]
cmp fixtype,0
je getkey0pro
cmp fixtype,2
je getkey2pro
cmp fixtype,1
je getkey1pro
getkey0pro:
bp getkey0
esto
mov dword,[edx+ecx+10]
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: