脱壳基础知识入门之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
默认选上“Fulldump:pasteheaderfromdisk”,PE头的信息直接从磁盘文件获得。设置好后,在LordPE的进程窗口选择notepad.upx.exe,点击右键,执行“dumpfull”菜单命令。如图:
将内存抓取的文件另存为dumped.exe,此时程序还不能运行,接下来就是重建输入表。 外壳程序解压还原后就会跳到OEP处执行,此时内存映像文件是己解压的程序。这时就可抓取内存映像文件了(该过程称为Dump)。当然不一定非要在程序原入口点抓取,只要能保证内存映像 外壳程序解压还原后就会跳到OEP处执行,此时内存映像文件是己解压的程序。这时就可抓取内存映像文件了(该过程称为Dump)。当然不一定非要在程序原入口点抓取,只要能保证内存映像文件是己还原的就行了。 继续上一个实例notepad.upx.exe,到OEP后就可以Dump取内存映像文件: 004010CC 55 push ebp
默认选上“Fulldump:pasteheaderfromdisk”,PE头的信息直接从磁盘文件获得。设置好后,在LordPE的进程窗口选择notepad.upx.exe,点击右键,执行“dumpfull”菜单命令。如图:
将内存抓取的文件另存为dumped.exe,此时程序还不能运行,接下来就是重建输入表。 一般的压缩壳,如Aspack等都有专用的脱壳机 。而加密壳(如ASProtect,Armadillo)一般很少有脱壳机,必须手工脱壳。手工脱壳一般情况是分三步:一是查找程序的真正入口点(OEP);二是抓取内存映像文件;三是输入表重建。(当然现在的加密壳复杂些,要考虑更多的东西) OEP是OriginalEntryPoint缩写,即程序加壳前的真正的入口点。 外壳初始化的现场环境(各寄存器值)与原程序的现场环境是相同的。加壳程序初始化时保存各寄存器的值,外壳执行完毕,会恢复各寄存器内容。其代码形式一般如下:
为了讲述方便,本节用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种基本的状态产生:读取,写入,执行。
那么我们应该如何中断在上面的几行呢? 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窗口中运行程序相当不便,建议采用下面的技巧 |
|