【文章标题】: 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, [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
  
  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 [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 typeadd
  bp typexor
  bp typenot
  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
  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
  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,[eax+ecx+10]
  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,[eax+edx+10]
  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:[EBX],EAX
  8B07            MOV EAX,DWORD PTR DS:[EDI]
  8B5F 0C         MOV EBX,DWORD PTR DS:[EDI+C]
  8B4F 04         MOV ECX,DWORD PTR DS:[EDI+4]
  8B57 08         MOV EDX,DWORD PTR DS:[EDI+8]
  8B6F 14         MOV EBP,DWORD PTR DS:[EDI+14]
  8B77 18         MOV ESI,DWORD PTR DS:[EDI+18]
  FF77 24         PUSH DWORD PTR DS:[EDI+24]
  9D              POPFD
  8B67 10         MOV ESP,DWORD PTR DS:[EDI+10]
  C747 50 0000000>MOV DWORD PTR DS:[EDI+50],0
  8B7F 1C         MOV EDI,DWORD PTR DS:[EDI+1C]
  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:[EDX],EAX
至于这段代码怎么找的话,可以在代码中搜索所有的这个二进制,然后判断一下哪句代码是我们需要的当然这样是很麻烦的,说下稍微简单一点的方法吧。我们可以先找其他的特征码也就是下面的对IAT处理的代码都可以作为特征码,而且这个特征码一般在VP加壳的程序中只有一句,找到后我们下段,然后然后运行程序停下来后就是处于IAT处理的代码中,然后我们可以学习NOOBY牛的方法CTRL+T 在最后一项中打勾,并输入我们需要找的代码
  MOV DWORD PTR DS:[EDX],EAX
  NOT EDX 
  然后CTRL+F11就可以了这样停下来后我们就可以找到这个填充函数了。
  4、typeadd  typexor  typenot
      在这里我们要先知道VP是如何处理iat的这个我在很早以前发过类似的文章都有说明的这里就不在说了,我只说对于IAT的处理算法,脚本中原来只有一个算法,所以只要知道填充地址和填充值,我们就可以用DLL计算出来API,但是VP有三种算法,所以我们要先搞清楚VP是如何处理IAT的,代码如下:
代码:
  typeadd :
      2B5401 10       SUB EDX,DWORD PTR DS:[ECX+EAX+10]
  typexor:
      334C10 10       XOR ECX,DWORD PTR DS:[EAX+EDX+10]
  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
上传的附件 VProtect1.XX-1.84 unpacker.rar