【文章标题】: EXECryptor 脱壳(一) OEP查找
【文章作者】: hnhuqiong
【作者邮箱】: hnhuqiong@126.com
【下载地址】: 自己搜索下载
【使用工具】: OLLYICE 1.10(0716)
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  看见大家对EXECryptor兴趣很高,这里我就跟随大家一起玩玩。
  
  首先EXECryptor从出现到被各路大侠破解还是抗住很长一段时间,其中的anti和VM都是值得我们深入研究的。
  本人对EXECryptor没有什么特殊的研究,都是跟随大侠的步伐画瓢,见笑。
  
  好了,我们开始吧。
  
  EXECryptor一般要过3关:
  1.寻找OEP
  2.IAT修复
  3.stolen code修复
  
  一:我们先从寻找OEP处开始。
      网络上流行的脚本Bypass AntiDBG OEP.txt我们来研究一下,毕竟EXECryptor版本众多,我们来看看这个脚本的
  奥妙在什么地方,这个脚本的成功率非常高。
  
  //Bypass AntiDBG OEP.txt
  
  data:
      var hInstance
      var codeseg
      var vmseg
      var ep
      var oep
      var temp
  code:
      gpa "VirtualFree","kernel32.dll"                 //取VirtualFree的API地址
      bphws $RESULT,"x"                                //下VirtualFree的硬件断点
      run                                            
      bphwc $RESULT
      rtu                                    
      gmi eip,MODULEBASE                               //取当前EIP的模块基地址,实际就是取代码段地址base
      mov hInstance,$RESULT                            
      mov temp,$RESULT
      add temp,3c                                   //base+3c   
      mov temp,[temp]                               // [base+3c]
      add temp,hInstance                            // base+[base+3c]
      add temp,28                                   // (base+[base+3c])+28 
      mov temp,[temp]                               // [(base+[base+3c])+28]
      add temp,hInstance                            // base+[(base+[base+3c])+28]   奥妙出来了
                                                    //    这里计算出来的就是原来EP处的CC断点
      bc temp                                       //去掉上面巧妙的计算出EP断点,这里得来的有点技巧,希望大家
                                                    //大家能学习,很多文章首先要求去掉EP的断点,而中断在系统断点
                                                    //而这个脚本巧妙的实现了这点.至于为什么是这个算法,大家可以
                                                    //去查阅一下资料,开卷有益.(温馨提示-加解密第二版268页)
      mov ep,temp                                      
      gmemi eip,MEMORYBASE                          //取当前EIP的信息,也就是代码段的信息
      mov codeseg,$RESULT                           
  
      find $RESULT,#2ECC9D#                           
      mov [$RESULT],#2ECC90#                        //这2句有点不明就里,希望各路大侠指正,我实验过程中,这
                                                    //两句始终没有起作用.
  
      gpa "EnumWindows","user32.dll"                 //取EnumWindows的API地址
      mov [$RESULT],#8BC09C85C09D0578563412C20800#   //这里就是要改这个API了,如何改呢?如下
                                                     //(这里是原API)
                                                     //77D1CD97 >  8BFF            mov     edi, edi
                                                     //77D1CD99    55              push    ebp
                                                     //77D1CD9A    8BEC            mov     ebp, esp
                                                     //77D1CD9C    33C0            xor     eax, eax
                                                     //77D1CD9E    50              push    eax
                                                     //77D1CD9F    50              push    eax
                                                     //77D1CDA0    FF75 0C         push    dword ptr [ebp+C]
                                                     //
                                                     //(改成)
                                                     //77D1CD97 >  8BC0            mov     eax, eax
                                                     //77D1CD99    9C              pushfd
                                                     //77D1CD9A    85C0            test    eax, eax
                                                     //77D1CD9C    9D              popfd
                                                     //77D1CD9D    05 78563412     add     eax, 12345678
                                                     //77D1CDA2    C2 0800         retn    8
                                                     //呵呵高手级别就是厉害,直接把这个API给整残废啦,没天理! 
                                                     //照这个趋势,kernel32,user32会被被N多大侠替换,壳壳们
                                                     //这个冬天有点冷.
                                                     
      gpa "CreateThread","kernel32.dll"
      find $RESULT,#FF7518#
      mov [$RESULT],#6A0490#                          //同上
                                                      //7C81063F    FF75 18         push    dword ptr [ebp+18]
                                                      //被替换成了
                                                      //7C81063F    6A 04           push    4
                                                      //7C810641    90              nop
  
      gpa "ZwCreateThread","ntdll.dll"
      bp $RESULT                                      //在ZwCreateThread处下CC断点,ANTI被一路扫过.
  loop1:
      run                                             //其实,这个run有点不太好,会在过ANTI的时候,SEH给拦住
                                                      //如果改成ESTO,以下的都改成ESTO,那么就不用手工SHIFT+F9了
      cmp eip,$RESUL
      jne loop1
      bc $RESULT                                     //到达ZwCreateThread处,去掉断点
      bp ep                                          //下断点到EP处,呵呵,绕开了ANTI,前路一片光明
  loop2:
      run                                            //可改ESTO
      cmp eip,ep
      jne loop2
      bc ep                                          //到达EP处,EXECryptor给扒的就差内裤了
      mov temp,codeseg
      sub temp,1                                     //原来codeseg楼上就是VM机!哈
      gmemi temp,MEMORYBASE
      mov vmseg,$RESULT                              
      gmemi temp,MEMORYSIZE
      bprm vmseg,$RESULT                             //下内存断点到虚拟机中
      run                                            //
      bpmc                
      mov oep,eax                                    //哈哈,从虚拟机中偷出了OEP,尽管可能是伪OEP
      sti
      bprm oep,1
  loop3:
      run                      
      cmp eip,oep                                    //猪八戒抢亲,不管三七二十一了。
      jne loop3  
      bpmc
      ret                                            //到家,关门,放狗,成亲,熟米做成生饭。
  
  
  在simonzh2000的《ExeCryptor 2.2.X 的 Anti Ollydbg 小结》中,
  1.  OEP 处的 CC 检查
  2.  AntiDump
  3.  IsDebuggerPresent
  4.  [Heap+10h]
  5.  PEB.NtGlobalFlag
  6.  GetTickCount
  7.  FindWindow
  8.  OutputDebugString
  9.  ReadProcessMemory(004B1C86, 004C91A0)
  10. 对 API 的检查很严格, 几乎每一句都不能下 CC 断点, 不能修改
  11. 对 Softice 也有一些检查.
  12. 利用 OpenProcess("CSRSS.EXE") 来检测 OD
  
  OLLYICE避开了4,6,8,11,12
  剩下的就是利用脚本躲避1,5,7的ANTI,上面脚本完整的实现了它,并且一并躲过了新版本的ANTI。
  在感叹前人的艰辛中,我们成长着。
  
  在这个过程中,大家只要掌握了躲避好OEP处的CC检查,并且在CreateThread和EnumWindows处绕开,这个壳基本
  就可以完整的跑起来了,后面至于脚本怎么写,怎么对付各种不同的版本,我相信大家动手起来,丰衣足食!!!
  
  
  
  
  
  
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2007年03月01日 0:51:22