分享

脱壳基础知识入门之Dump内存映像

 quasiceo 2013-12-21

脱壳基础知识入门之Dump内存映像

 

现在加解密发展己形成2个分支了,一个就是传统的算法,另一个就是加密壳。越来越多的软件采用了密码学相关算法,现在要做出一个软件注册机己不象前几年那么容易,这就要求解密者必须要有

  现在加解密发展己形成2个分支了,一个就是传统的算法,另一个就是加密壳。越来越多的软件采用了密码学相关算法,现在要做出一个软件注册机己不象前几年那么容易,这就要求解密者必须要有一定的数学功底和密码学知识,而这些在短时间内是不容易掌握的。除了密码学的应用,越来越多的软件加壳了,因此要求解密者必须掌握一些脱壳技术,这就使得壳成了解密必须迈过的一个门槛。壳发展到今天,强度越来越高了,将许多人挡在门外,使得大家望壳兴叹。另外,论坛现在两极分化比较严重,高手讨论的脱壳技术新手看不懂,很多人想学脱壳,但看到壳这么难,只好放弃了,造成新手与高手间一个断档,为了鼓励更多新人加入脱壳的行列,很有必要将壳有关知识总结一下。www.主页提供的教学确实有点过时了,己到非更新不可了。为此,整理这篇脱壳入门指导的文章,方便脱壳新手们学习。相对于密码学算法,脱壳并不难,只要肯花时间,短期内还是比较容易取得成绩的。

  但是,不建议那些加解密刚入门,调试一个普通软件都费劲的朋友来脱壳。至少要等你有一定的调试技能再来学脱壳。也就是说必须掌握这篇文章所讲的东西:

第一课PE格式

  要想学脱壳,第一步就得掌握PE格式,PE是PortableExecutableFileFormat(可移植的执行体)简写,它是目前Windows平台上的主流可执行文件格式。

  MicrosoftVisualC++提供的WINNT.H里有PE数据结构的完整定义。

  学习PE格式的方法是自己先准备一个十六进制工具,如HexWorkshop,WinHex,用这些工具打开一个EXE文件对照着学。强烈推荐你用

  Stud_PEv.2.2.0.5这款工具辅助学习PE格式。PE格式学习的重点是在输入表(ImportTable)这块。

  Stud_PE工具界面:

  

  PE结构图:


 

外壳程序解压还原后就会跳到OEP处执行,此时内存映像文件是己解压的程序。这时就可抓取内存映像文件了(该过程称为Dump)。当然不一定非要在程序原入口点抓取,只要能保证内存映像

  外壳程序解压还原后就会跳到OEP处执行,此时内存映像文件是己解压的程序。这时就可抓取内存映像文件了(该过程称为Dump)。当然不一定非要在程序原入口点抓取,只要能保证内存映像文件是己还原的就行了。

  继续上一个实例notepad.upx.exe,到OEP后就可以Dump取内存映像文件:

004010CC  55      push  ebp
004010CD  8BEC     mov  ebp,esp
004010CF  83EC44    sub  esp,44
  运行LordPE.EXE,点击Options,默认选项如下:

  

  默认选上“Fulldump:pasteheaderfromdisk”,PE头的信息直接从磁盘文件获得。设置好后,在LordPE的进程窗口选择notepad.upx.exe,点击右键,执行“dumpfull”菜单命令。如图:

  

  将内存抓取的文件另存为dumped.exe,此时程序还不能运行,接下来就是重建输入表。

外壳程序解压还原后就会跳到OEP处执行,此时内存映像文件是己解压的程序。这时就可抓取内存映像文件了(该过程称为Dump)。当然不一定非要在程序原入口点抓取,只要能保证内存映像

  外壳程序解压还原后就会跳到OEP处执行,此时内存映像文件是己解压的程序。这时就可抓取内存映像文件了(该过程称为Dump)。当然不一定非要在程序原入口点抓取,只要能保证内存映像文件是己还原的就行了。

  继续上一个实例notepad.upx.exe,到OEP后就可以Dump取内存映像文件:

004010CC  55      push  ebp
004010CD  8BEC     mov  ebp,esp
004010CF  83EC44    sub  esp,44
  运行LordPE.EXE,点击Options,默认选项如下:

  

  默认选上“Fulldump:pasteheaderfromdisk”,PE头的信息直接从磁盘文件获得。设置好后,在LordPE的进程窗口选择notepad.upx.exe,点击右键,执行“dumpfull”菜单命令。如图:

  

  将内存抓取的文件另存为dumped.exe,此时程序还不能运行,接下来就是重建输入表。

一般的压缩壳,如Aspack等都有专用的脱壳机 。而加密壳(如ASProtect,Armadillo)一般很少有脱壳机,必须手工脱壳。手工脱壳一般情况是分三步:一是查找程序的真正入口点(OEP);二是抓取内存映像文件;三是输入表重建。(当然现在的加密壳复杂些,要考虑更多的东西)

  OEP是OriginalEntryPoint缩写,即程序加壳前的真正的入口点。

  外壳初始化的现场环境(各寄存器值)与原程序的现场环境是相同的。加壳程序初始化时保存各寄存器的值,外壳执行完毕,会恢复各寄存器内容。其代码形式一般如下:

  PUSHFD    ;将标志寄存器入栈保存
  
PUSHAD    ;pusheax,ecx,edx,ebx,esp,ebp,esi,edi
   ……     ;外壳代码部分
  
POPAD     ;popedi,esi,ebp,esp,ebx,edx,ecx,eax
  
POPFD     ;恢复标志寄存器
  
JMPOEP    ;
OEP:……     ;解压后的程序原代码

  为了讲述方便,本节用UPX加壳的Win98记事本来演示。首先用PEid查看加壳前的记事本:

  

  PEid显示Notepad.exe程序是用MicrosoftVisualC++6.0编译的,接下来用UPX来加壳,方法是开个DOS窗口,用命令upxnotepad.exe。如下图所示:

在脱壳中输入表处理是很关键的一个环节,因此要求脱壳者对PE格式中的输入表概念非常清楚。在磁盘文件中,PE文件的输入表结构如下图所示:

  

  图8.1磁盘文件中的输入表

  PE文件运行时,Windows系统加载器首先搜索OriginalFirstThunk,如果存在,装载程序迭代搜索数组中的每个指针,找到每个IMAGE_IMPORT_BY_NAME结构所指向的输入函数的地址,然后用函数入口地址来替代由FirstThunk指向的IMAGE_THUNK_DATA数组里的元素值(即用真实的函数地址填充到IAT里)。因当PE文件装载内存后准备执行时,上图己转换成这种情况了:

  

  图8.2PE文件装载内存后的输入表

  此时输入表中其它部分就不重要了,程序依靠IAT提供的函数地址就可正常运行(图8.2红圈部分)。如果程序加壳了,那壳自己模仿Windows装载器的工作来填充IAT中相关的数据,此时内存中就一张IAT表,输入表的其他部分是不存的(当然不是绝对的,也有不少壳,如Aspack等,内存中会出现完整的输入表结构),如图8.3所示。

1.前言

  发现论坛中很多兄弟在询问:什么是二次内存断点,三次内存断点。还有很多人对内存断点的原理不是很明白。其实只要懂得壳是如何解压代码的,那么就完全可以按自己的喜欢来下断。

  本文要解决的问题是:

  1.什么是内存断点?

  2.如何在寻找OEP时使用内存断点。

  3.内存断点的局限性。

  2.内存断点寻找OEP的原理

  i.首先,在OD中内存断点,硬件断点和普通断点(F2下断)是有本质区别的。硬件断点等效与SoftICE命令bpm,他的中断要用到DR0-DR7的调试寄存器,也就是说OD通过这些DR0-DR7的调试寄存器来判断是否断下。

  普通断点(F2下断)等效于bpx,他是在所执行的的代码的当前地址的一个字节修改为CC(int3)。当程序运行到int3的时候就会产生一个异常,而这个异常将交给OD处理,把这个异常的regEIP-1以后就正好停在了需要的中断的地方(这个根据系统不同会不一样),同时OD在把上面的int3修改回原来的代码。

  而内存断点基本上使用的是对代码使用的保护属性来实现中断。

  内存断点分为:内存访问断点,内存写入断点。

  我们知道,在程序运行的时候会有3种基本的状态产生:读取,写入,执行。

004AE242  A100104000   moveax,dwordptrds:[004AE24C]      //004AE24C处的内存读取
004AE247  A300104000   movdwordptrds:[004AE24C],eax      //004AE24C处的内存写入
004AE24C  83C001     addeax,1                 //004AE24C处的内存执行

  那么我们应该如何中断在上面的几行呢?

  1.当我们对004AE24C下内存访问断点的时候,可以中断在004AE242也可以中断在004AE247。

  2.当我们对004AE24C下内存写入断点的时候,只能中断在004AE247。

  3.当我们对004AE24C下内存访问断点的时候,能中断在004AE24C。

  到这里你可能不明白了,为什么内存访问断点能中断在004AE247这一句对004AE24C的写入,而且还能中断在004AE24C的执行呢?

  其实很简单,我们只要仔细体会一下“内存访问”这四个字的含义遍可以知道,当我们对004AE24C进行读取的时候需要“访问”他吧,当我对004AE24C进行写入的时候也需要“访问”他吧!!当然我们要执行内存地址004AE24C的代码的时候也是还是要“访问”他的!

  所以我们不难得出下面的结论:

  1.内存写入中断的地方,一定是也可以用内存访问中断。

拿到一个壳,第一步就是用相关工具分析一下是什么壳,然后就可心中有数地跟踪分析。文件分析工具有PEID,FileInfo等。

  1.PEiD

  PEiD的GUI界面操作非常方便直观。它的原理是利用查特征串搜索来完成识别工作的。各种开发语言都有固定的启动代码部分,利用这点就可识别出是何种语言编编译的。同样,不同的壳也有其特征码,利用这点就可识别是被何种壳所加密。PEiD提供了一个扩展接口文件userdb.txt,用户可以自定义一些特征码,这样就可识别出新的文件类型。

  有些外壳程序为了欺骗PEiD等文件识别软件,会伪造启动代码部分,例如将入口代码改成与VisualC++6.0所编程程序入口处类似代码,即可达到欺骗目的。所以,文件识别工具所给出的结果只是个参考,文件是否被加壳处理过,还得跟踪分析程序代码才可得知。可参考这个文档了解如何伪装:让侦测工具把壳识别为VC++7.0的源代码 。目前Hying的壳PE-Armor伪装能力是最强的:

  

  PEiD分析不出类型的文件就报告是“Nothingfound*”,如出现这情况一般都是未知壳或新版的壳。

  下面PEiD识别出这个软件是用Asprotect1.2x加的壳。

  

  2.FileInfo

  FileInfo(简称Fi)另一款不错的文件检测工具。Fi运行时是DOS界面,在DOS窗口中运行程序相当不便,建议采用下面的技巧

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多