脱壳经验谈之一----给脱壳新手的建议(更新预告)

转载自:http://www.unpack.cn/viewthread.php?tid=29039php

  学破解时间也不长了,也学了一些脱壳的技术,过程当中感触颇深。这里给你们分享一下,也算是给脱壳新手的一个指导。
  

  菜鸟心得,高手飘过~ 固然你要看,我也不反对~~
  
    Attention,Please!!
   感谢你们的关注及支持,最近正在准备经验谈的第二篇,结合本篇的内容以及你们的建议并结合实例来进一步说明~ 若是有什么建议的话,请你们提出~ 谢谢!!

  关于工具
   
  关于OD
  所谓工欲善其事,必先利其器。要想学习脱壳的话,有几种不一样的OD是很重要。由于有时在调试一些强壳的时候,有些改造过的OD能够躲过壳的深层检查,再配合一些OD插件就能够彻底让壳检测不到调试器的存在了。这里推荐几款比较好的OD:
  1,fly改造的OD。能够调试大多数壳,可是因为不能使用phanom 1.3版的插件,致使在调试某些强壳(如Aspr 2.x)的时候会被检测到。
  2,ImmunityDebugger.这款OD能够比较顺利的调试Aspr等其余强壳。国内也有了汉化版。只是界面背景是黑色的,我实在不习惯这种界面,喜欢的人能够试试。
  关于其余的工具
  1,LordPE。推荐你们在Dump程序的时候使用这个工具。或许你们在脱简单的压缩壳时习惯使用OD的脱壳插件来抓取内存镜像,可是若是你们有调试穿山甲等强壳的经验就会知道,若是用OD插件抓取内存镜像就会出现OD被卡死的状态,这或许是OD插件的Bug,也多是壳的反Dump方式,反正会影响到咱们正常的脱壳。因此这里推荐使用LordPE来抓取镜像文件。并且在须要补区段的时候,用LordPE能够很方便的进行区域抓取。此外,做为一款PE编辑器,LordPE也是很优秀的。相比之下,PEtools就有点儿差了,对于PE文件有些操做会致使文件损坏,不知道为何。你们仍是用LordPE吧。
  2,ImportReconstruction。这是一款专业级的输入表重建工具。因为它支持插件扩展,能够大大提升对于加密壳的脱壳成功率。可是请你们不要过于依赖这款软件,学会手动修复输入表是很必要的。在ImportREC不能修复的时候,咱们只能靠手动修复。手动修复一方面能够练习调试技术,另外一方面可让咱们更加深刻的去了解PE文件的工做方式。
  
  关于脱壳方法
  相信你们都像我同样看过一些脱文,在里面告诉咱们下这个API断点,而后走多少步,再怎么样怎么样就能够到OEP了。反正具体为何这么操做,做者都只字不提。当我看到这些脱文的时候,基本上是一头雾水。加上我这我的比较倔强,对于我不懂的方法是不会接受的,因此那段时间,脱壳的水平基本上止步不前。实践是最好的老师,本身亲手调试了些壳之后就明白为何了。当时我有个这样的顾虑,就是“我真的能调试这些壳,那但是前辈们干的事儿啊”,可是真正调试后才发现其实并无那么难的。当我第一次手脱了一个Aspr 1.23RC1的时候,真的好兴奋,那种感受就像一个初出茅庐的小贼利用本身学过的书本上的技能到**局偷出了一根**局长的头发,虽然没有值得炫耀的,可是对于自信心倒是很大的鼓励。因此加密壳没有好怕的,你只要想办法躲过壳的全部检验,而后乖乖的走到OEP就能够了!至于如何躲过这些检验,那就要你在调试中不断积累经验,以及借助别人的经验了。
  所谓授之以鱼,不如授之以渔。学习脱壳仍是理解方法,才能真正学会。
  因此我对于那些脱文的态度是这样的:
  1,对于所谓的方法先置之不理,本身手动调试一遍,了解壳的流程(通常来讲,当你调试到OEP的时候,这个壳你应该调试了10遍以上了)。
  2,当遇到实在过不去的检验的时候再看脱文,了解它是怎么过去的。这样印象深入一些。并在下次遇到这样情况的时候能本身解决。
  3,当本身彻底脱掉这个壳后,再看下脱文,这个时候你应该就能够明白为何下那些API断点了。下次就能够不用这样手脱了,照着脱文给的快捷方法脱壳就能够了。这个时候对于出现和脱文上不一样的状况,我想你应该也会处理了。
  再说说如何调试壳呢。
  1,首先要选择并配置好OD,尤为对于强壳必定要这么作。配置OD包括异常设置,删除int3断点(由于有些壳会检测Int3断点的),OD的标题隐藏等。当这些都设置好,要在OD中运行一次,确保你要脱壳的程序能在当前的OD中顺利的运行(对于有些带驱动的壳能够不这么作,由于必须在没有驱动的条件下才能调试。),这样能够在调试时省去很多躲避调试器检查的时间。(固然有些壳仍是要在调试中躲避检查的。)
  2,我的认为,基本的调试方法有:单步法,最后一次异常法。这两种方法在逻辑上都是比较好理解的。在调试的过程当中要配合内存断点,硬件断点,Int3断点以及F4来简化调试过程。如能够用F4来跳出循环;硬件断点能够用来记录调试进度,当程序不当心跑飞的时候,能够在相应的位置下硬件执行断点,从新来事后就能够直接到达跑飞的位置了;灵活运用内存断点可使得调试变得很容易,也是提升调试技巧的一种方法。
  当你能够熟练的运用这些方法的时候,任何的壳均可以搞定了,任何一个加壳的程序就像躺在床上的**,等着你脱了~ ^-^


  关于OEP的到达
  咱们脱壳的目的就是为了到达OEP,可是若是判断是否是到达了OEP了呢?前辈们告诉咱们一个方法,注意跨段跳转或转移。这确实是惟一判断标准。可是不少的教程中都把这句话误解为了:“注意大的跳转”,使得不少新手都被搞的云里雾里的,看到大跳转就兴奋。
  首先澄清一个误解,什么叫作“跨段转移或跳转”?这里面所谓的段指的是一个区段,是指被分割成一段段的内存。跨段跳转顾名思义,是指EIP指针从一个区段跳到了另外一个区段。而不是所谓的大的跳转。若是EIP所在的区段很大,段内跳转也能够很大,这里所谓大的跳转自己就是一个很模糊的概念。
  其次,并非出现跨段跳跃就是要到OEP了。通常加密壳在解码的时候会在内存中申请空间,并在那里实行解码。通常来讲是壳会申请不少段这样的空间,而后在解码的时候从这个段跳到那个段。这些段就是咱们在调试的时候在目标程序区段后面的那些没有名字的区段部分。因此说在这些段里面的跳跃通常不会到OEP的。
  再次,那么你会说了,那到底怎么判断呢?大多数壳把程序解码后会跳到目标程序的code段的进行执行。那么方法就出现了,在调试的时候能够先看下code段的地址范围,若是在调试过程当中出现了跳跃到这个地址范围内存的跳转或转移的话,那么十有**就是要去OEP了!
  此外,对于OEP的判断能够经过不一样语言编译的程序入口点特征来判断,固然这彻底就是经验的问题,须要你们不断的积累。就像天草说的,记住入口特征这句话我都说了八百遍了。
  不过,这里有个小技巧,就是经过查看资源类型来大体判断。由于壳不多资源列表进行处理,因此若是查看资源,发现存在RCData的话,就能够认为程序应该Delphi或者BC++的;若是资源中有对话框,菜单等资源,并且资源名称都比较规则的话(这主要是为了区分VB以及E语言),就能够判断是MS VC++的了;若是在程序安装目录中发现*.fnr等类型的文件话,基本能够认定是E语言的了(如今E语言的程序愈来愈多了);若是在程序的末尾发现附加数据的不少的话(通常要大小的数量级在KB以上),那应该也是E语言的(这个时候你们应该明白为何E语言程序查壳的时候为何显示的时候Microsoft VC++[OVERLAY]了吧)。


  关于学习方法
  这应该是老生常谈了。学习方法因人而异,没有必要强调某种方法,方法的目的只有一个,就是掌握你学到的东西东西并与之前的知识融汇贯通。论语中的那句话“温故而知新”,确实颇有道理。当你学到一些东西后,回过头来看之前学的东西,你会发不少新的东西,能够加深对某些知识点的理解。这点是没有任何方法能够替代的。这里推荐两种方法:
  1,录像。把你的脱壳学习过程录像,当你忘记的时候,回忆起来也会很快的。
  2,作好笔记。OD有个很好的插件Godup能够在调试的过程当中作好记录。从某种程度上讲,记录是你调试过这个壳惟一证据。
  
  关于到OEP的一些特征代码
  如今的壳变聪明了,不多再使用Jump **X这样的方式来到OEP了。下面介绍几种流行的方法。
   1,push 寄存器或者地址
      retn
   这种方法是利用retn来实现远跳转的,原理同call子程序的后返回的
原理同样,即经过push一个值到堆栈顶,而后用retn指令便可返回到堆栈顶指向的地址。
   2,mov dword ptr[**],**X  
      jnz  **XX
      retn
      push 0  这个地址是上面的mov指令动态填写的
      retn   
     这样的条转在ASPac和ASprotect中使用过。
   3,mov 寄存器,**X
      call 寄存器
    这个在穿山甲的壳中能够看到。
   4,还有使用Leave指令进行跳转的,你们也能够注意下。
   5,使用SEH。后面会提到。


   关于SEH
   SEH,Structure Exceptions Handle,结构化异常处理,是加密壳程序常用的桥段。主要用这种方法来实现非正常跳转(可能还有其余做用,我如今只理解到这里)。对于SEH的具体技术细节我也搞不明白,也不用管它,OD给了咱们一个很好用的功能,就是在堆栈会显示SE句柄。这是什么意思呢?你只要知道当出现异常后,系统处理完异常就会跳到这里来继续执行。 那么咱们能够经过在这个地方下好断点,而后Shift+F9,就能够继续调试了!
  
   关于自校检
   如今带有脱壳自检验的程序仍是不少的。自校验类型大体分为如下几个类型。
   1,CreateFile型。这种自检验通常都会调用CreatFileA(W)函数来对于自身。而后
   经过GetFileSize获取文件大小,由于通常脱壳后文件大小会变,经过比较文件的大小来检测是否被脱壳。
   经过SetFilePointer来设置文件指针,而后经过ReadFile读取文件中的一些数据,来判断是否被脱壳(通常来讲读取的时候附加数据)
   2,内存型。这种自检通常是对程序在内存中镜像进行CRC,MD5等检验,若是不相等则认为已脱壳或被修改。
   3,脚本语言型。脚本编程语言指的是像autoit,autohotkey等语言。这种语言编译出来的程序通常都是天生带壳的,并且自校验是对附加数据进行屡次细致的检查,若是不弄清楚检验过程,即便更改跳转也不能让程序正常运行。有机会你们能够试试。
   4,壳校检型。这种校验是在主程序中插入一些跳到壳地址中的代码,并返回一些可有可无的数据或作可有可无的操做。若是程序被脱壳了,这些代码执行的时候就会出现异常。
   还有一些其余类型,可是如今还有总结出比较好的说法,之后再补充。
   相应的处理方法。
   1,直接对API下断,基本就能够到达解密点。
   2,用PEID插件能够查看算法的所在位置,就能够到达解密点了。
   3,没有别的方法,运用API断点耐心调试吧
   4,在OD运行程序,出现异常后,在堆栈中找到返回的位置,nop掉相应的指令便可。
   
   关于脱壳脚本
   脚本应该是前辈没有留给咱们最好的财富了,有了这些东西,咱们能够在不了解任何脱壳细节的状况下脱掉壳。可是若是想学脱壳技术的话,那么请把它看成你的老师。由于脚本中包含着你遇到问题的全部答案~ 并且当你了解了之后,还能够本身改进脚本的功能。借用达朗贝尔的一句话:多读读高斯,他是咱们每一个人的老师~
   
   关于花指令
   可能有些新手看到壳那些乱七八糟的指令会发怵的,这些都是壳为了阻止调试者所设的花指令,或许你不知道这些指令怎么执行,可是壳是是知道的,它不可能去执行一坨不能执行的指令的,有些指令是动态解码的,有些是花指令。你在调试的时候只要看着当前指令F8(7)就能够了,不用管别的。再借用达朗贝尔的一句话(怎么又是他?):前进吧,你会有信心的!
   
   关于心态
   调试壳是须要很大耐心的,就像破解同样! 因此若是你已经下好决心的话,那么请同时作好内心准备!
   
   最后送你们一句话,关键是要对她有爱~ 只有真正对这个东西感兴趣,你才能真正学到东西!
   
   Begging For A Way Back Into Love!!!

                                                                                            BY HyperChem
html

转载于:https://www.cnblogs.com/9422e/archive/2009/06/26/1511950.html算法