本帖最后由 Pnmker 于 2012-12-23 14:27 编辑
首先这里要感谢一下yangand朋友,他在看了我关于使用工具De4Dot(我把它视为神器)脱壳/反混淆的帖子之后,立刻就使用De4Dot去试验脱壳各种加壳工具处理过的NET程序,把我想做没有做的事情给补充上了,非常感谢他。在他的试验过程中,发现有不少加壳工具处理后的程序,确实是De4Dot无法正常脱壳/反混淆的,包括Themida.NET, Safengine等等。 发现这些问题让我很兴奋,因为我觉得我有事可做了,因此就有了今天这么一篇文章,希望对大家也能有所帮助。 在开始正文之前,我想明确一下我对脱壳/反混淆.NET程序所需要达到的目标,应该说有两个: 第一,拿到程序的完整源代码,C#或者MSIL,C#的最佳; 第二,脱壳/反混淆后的程序能够运行。对我来讲,第一个目标是极具振奋力的,能够拿到别人辛辛苦苦才完成的程序的源代码对于一个从事软件开发的人来讲还有其他比这更让他激动吗,因此每当那些源代码终于完整无缺地呈现在我的眼前的时候我都感到十分地满足。这也降低了 破解程序的难度。第二个目标,对我来说是次要的,但有些时候也是必须的,为什么这么说呢?有些时候虽然拿到了源代码但如果脱壳/反混淆之后的程序不能运行的话,对于需要爆破的程序来讲就是极为麻烦得事情,程序都无法运行如何爆破呢? 接下来我还得啰嗦一件事情,请不要嫌我啰嗦,这也是一个极为重要的事情,因为在脱壳的过程中我们可能不止一次地要用到。这件事就是关于程序数据在PE文件中的文件偏移与其在内存中的RVA之间的转换公式,这里只列出公式,对于为什么不解释(包括文中涉及到任何跟PE文件格式有关的知识都不作解释,如果要讲那真的是一个很大话题,这不是我们本文的目的),不懂得可以私底下讨论或参考网上其他的讲解。这公式是:(公式中的”节”也称作”段”,Section) 数据的文件偏移 = (数据的内存RVA-数据所在节的RVA)+数据所在节的文件偏移
下面可以开始正文了,这里我们以yangand同学发我的程序为例,程序只有一个文件WindowsApplication1.exe。一个好的习惯(当然还是我认为的)就是拿到一个陌生程序之后首先要判定是哪种语言写的,确定所能使用的工具的大概范围,然后再检测该程序是否加壳/反混淆,如果是加壳/反混淆过后是使用什么工具处理的。由于这些yangand同学事先都已经告诉了我,所以我直接就用De4Dot尝试是否可以脱壳/反混淆,发现确实不能之后,还是用DotNet Id确认了一下它的加壳/混淆方式为TMD(Themida.NET简称,下同).然后,又使用各种Unpacker工具处理无果之后,参考网上一些资料将程序从内存Dump出来之后再修复的方法成功地完成了该程序的脱壳并且脱壳之后的程序是可运行的。 这里使用的工具是WinHex和CFF Explorer。WinHex用来将程序从内存Dump出来以及完成大部分的PE文件数据修复工作,CFF Explorer是一款相当优秀的PE文件格式查看工具,当然也可以用来编辑PE文件,这里之使用到了它少量的编辑功能,主要是增加与删除段. 首先,将程序运行起来,然后使用WinHex将程序数据从内存中Dump出来),点击菜单[工具]->[打开RAM ],弹出Dump界面如下:
选择我们的程序后点击确定,Dump成功!将Dump出来的数据保存为文件,这里命名为WADump.exe。Dump出来的内存数据开始的一部分如下图所示:
然后,使用CFF Explorer打开WADump.exe,显示如下图:
上图我已经将信息显示定位到了节头部,在那里我们看到的是有2个节,但第一个节的Raw地址不是0x00001000,我们要修复它,即在现在的值0x00002000基础上减去0x00001000,同时下面的.rsrc节的Raw地址也要减去该值0x00001000。这个修复工作我是在WinHex里完成的,CFF似乎应该也可以,但是我不会使用,如果下面的修改工作我没有注明在哪个工具里改的话,默认是WinHex. 这个修改的结果如下所示:
然后此时再到CFF Explorer里看,两个节的Raw地址就发生了变化,如下所示:
接下来,我们要做的一件事情就是要修复程序的重定位信息,一般来讲.NET程序有3个节,.text、.rsrc和.reloc,我们看到的只有两个节,那个没名字的显然就是.text节,也就是说程序少了.reloc节及重定位信息,这是因为TMD加壳或程序运行时将该节删除掉了,我们要重建该.reloc节。 但在重建之前,我们有两件小小的事情要做,当然不做应该也没有影响。细心的同志们,已经注意到了我们Dump出来的程序有1.5M之大,但实际上的程序确只有671k相差太远了,那是程序中存在很多无用的节,我们可以将它们删除掉,可以使用一个非常简单的方法:在CFF 的查看节头部界面中,右键->添加段(空白处),弹出的对话框中随便输入一个16进制整数,点确定后然后再右键->删除段(头部数据),即可。操作完不要忘记保存哦。这样子文件大小就骤降到31k了。 第二件小事,就是节.rsrc的字符特征C0000040是错误的,我们要修正为40000040,可以在WinHex中完成。
然后,我们就可以在CFF中来添加一个.reloc节了,大小为0Ch,(因为纯.NET程序只有一个定位项,就是程序的入口点_CorExeMain,可参考《NET揭秘-MISL权威指南》第54页最后一段话) ,字符特征为42000040.添加节的方法是 右键->添加段(空白处),弹出的对话框中输入0Ch,点击确定。剩下的字符特征和节名称可以在WinHex中完成,修改结果如下所示:
然后,需要做得就是PE可选头的数据目录中的重定位信息目录的RVA和Size的修复,从CFF查找到重定位目录的文件偏移00000120,将上图中红色圈出来的虚拟地址和虚拟大小填写在对应得位置上,WinHex修改如下图所示:
CFF的显示结果:
重定位节.reloc已经建好,那么接下来就是为重定位目录添加重定位项了,又由于只有一个入口点的重定位项,因此在CFF 中的Hex 编辑器中搜索_CorExeMain找到以下位置:
因此只需将FF25 00402000即JMP DWORD PTR:[00402000]中的00402000进行重定位即可,首先将其文件偏移4BF0转化为RVA,记该RVA为addr(利用文章一开始给出的公式),由4BF0得知其位于第一个节内,该节的RVA=00002000,文件偏移为00001000,则00004BF0=(addr-00002000)+10000,则addr=5BF0,然后将其写入到.reloc节的文件偏移位置00007C00处如下图:
然后保存程序.
至此程序已经完全脱壳,其运行界面如下:
在Reflector 里查看其源代码如下:
相关程序:
相关程序.rar
(664.77 KB, 下载次数: 1123)
|