【.NET】UnpackMe!Shielden+DNGuard,双层变异壳 - 脱壳详解

【.NET】UnpackMe!Shielden+DNGuard,双层变异壳 - 脱壳详解

前言:自从脱壳神器de4dot横空出世以来,我们可以看到几乎所有的.net破文中的第一部分就是不管三七二十一把程序丢进去脱壳以及反混淆。可是你真的明白de4dot背后做了些什么吗?你对.net文件格式真的了解吗?如果这么好的开源工具大家都不去研究代码,实在是令人惋惜,以至于还在有人在论坛询问 Reactor最新版怎么脱的问题,也有的在论坛上断言MaxtoCode可以难倒99%的人……我想善于从基础学起,善于研究大神源码,真正搞懂de4dot背后所做的工作,那么这些问题都不算什么问题。这篇文章有点长,希望你能细心读下去,而且我相信你一定会有很大的收获,请不要纠结于为什么照着我的教程做也不能脱掉类似的其他壳,你应该扪心自问,教程的每一步你都理解了吗?你能否利用这些知识进行变通?希望你不要做一个伸手党,而是去真正去理解工具背后的工作。 虽然de4dot很牛,但总有些壳它也是无论为力的,比如我们今天要讨论的这个。由于我很长时间都没有上论坛,因此错过了很多精彩的.net内容,还好希望现在还不晚。 ---------------------------------分割线,以下部分为原贴内容------------------------------- Hi.伙计们 我被保护于Shielden(全保护)+Dnguard(全保护)中. 尝试将我脱壳! 有一定难度,我仍然希望有人能够成功! 如果不能成功,写下你的分析思路,以及疑问,我会回答... good luck! 脱壳目的: 1.脱掉Shielden 难度系数分 ★ 2.修复脱掉Shielden之后一系列问题(如区段错乱,PE入口,乱码,程序体积过大等),使程序正常运行, 难度系数分 ★★★ 3.脱掉Dnguard Hvm,并修复其各种问题使之能正常运行,难度系数分★★★★★ 4.反编译能正常看到源码(仅限Reflector,别的反编译工具纠错能力较强,不适合练手....),难度系数分★★★ 下载地址:http://yunpan.cn/cZLVyh8eDDWWz 访问密码 5d44 注:If you got it ! Welcome to Join Matrix ! 这个壳的难度系数非常高,以至于画眉大侠对其寄予厚望,看介绍说:谁能脱掉的,就可以加入Matrix? 那么加入了这个Matrix,能否获得画眉大侠的Dnguard HVM企业版的使用权? 想想还是有点小激动呢。但是由于的难度极高,修复难度极大,以至于在原帖中没有人能及时提供一个明确的解决方案。那么现在请大家跟我一起来解密。 老办法,运行程序,用先在内存中抓。为什么要从内存中抓?因为有些加密的东西,总归会在内存中解密出来,这样可以最大限度的获得解密后的数据。 很不幸,刚打开程序就报了一个这样错误: 原来是DNGuard HVM试用版过期了,难道我们真的要像原帖中ghostfish描述的一样放弃了吗? 其实吧,我们还有系统自带的“月光宝盒”可以用。看看发帖时间是2015年3月17日,那么我们只需要把系统时间修改为3月17日,就可以顺利打开了。让程序跑起来后,我们准备在内存抓,其实这样的工具有很多,使用起来都大同小异,比如上一篇文章中我说的Task Explorer,还有WinHex也是可以的。今天我再推荐一款DOTNET专用的工具,因为我发现这个工具自带一定的修复功能。那就是DOTNET Dumper,其实吾爱论坛上也有http://www.52pojie.cn/thread-67257-1-1.html, 但是这个版本脱壳时会报错,其版本号是1.0.3936.41928。 我手上的是版本1.0.3938.31576,可以顺利脱壳,可以在附件中下载。其实用什么工具都是一样的,不过如果用Task Explorer需要自己再多修复些东西。 找到进程,然后点击右键Dump。 Dump了7个文件,我们来看看。 那个2.0.50727.42的描述字眼实在太显眼了,明显是系统的DLL文件,那么我们只保留dump1.exe 其他的全部删掉。然后记得把DNGuard的原始HVMRuntm.dll文件放到dump后的目录中。我们用CFF打开看看这个dump1.exe。 打开Section Headers[x]发现了.HVMRunt 这种奇怪的东西。记住了:.net一般就三个默认的 .text, . IDAta 和 .rsrc 以后发现不是这三个全部删掉!在相应的Section上点击右键使用 “Delete Section (Header And Data)“ 再看看Import Directory 记住了,.net默认就导入一个mscoree.dll,其他的全部删掉。如果换种场景,一个导入函数都没有怎么办?那么可以使用Universal Fixer勾选fix import修复。 将上面的删除后,保存。直接运行程序看看。啊哈哈哈,程序居然可以直接运行了!!!! 可是,不要高兴的太早。为什么是乱码??????不错,我可以确信90%的人会卡在这里,走不下去了。请参考原帖, 我惊奇的发现连二楼Falcon_2015这样的.net高手也卡在了这里…… 根据我对于DNGuard 的多年研究,出现上图右边所示的错误:“试图使用链地址信息(有2个以上的节或有一个TLS节的IAT)加载无法验证执行文件”,多半是由于入口点位置不正确引起的。而乱码则是由于dump过程中,没有处理好字符串解密函数导致的。因此上图中Falcon_2015在第3步解释的不准确,真实情况是:DNGuard脱壳和乱码没有任何关联,也就是说,就算是乱码,DNGuard也是可以被脱壳的。一个是字符串解密函数的问题,一个是入口点不正确的问题,这分别是两个问题,且没有关联。 我们来用CFF打开脱壳后的程序再次观察一下:

再研究研究字符串怎么解密。看原帖第三楼,画眉的回复:

画眉原文:“你需要Hook Jit 解码”。 我等菜鸟,被Hook Jit的字样已经吓尿…….是的,在dump过程中,由于没有考虑到字符串解密函数的原因导致dump后出现乱码。这也是DNGuard加载双壳的一大特征,根据我最近分析各种画眉大侠的unpackme的经验,他比较喜欢的做法就是先用DNGuard加一层强壳,且在此壳中使用字符串加密。然后外面再加一层壳,当你脱去外面这层壳的时候,打开程序后字符串就会变成乱码。不相信的人,你们自己去用DNGuard加两层壳试一试。 说句实话,我在这里也卡了很久。但是我不甘心,我想做剩下10%的人可以继续解密,我是一个工具党,但是我找遍网络也没有找到合适的工具来解决这个问题。每次当我找不到工具的时候,我就会决定自己写个工具,便把de4dot的源代码重温了一遍,终于基于de4dot源码开发出一个小工具。为了方便大家今后遇到同样的问题,我直接把工具奉上。 这个工具除了可以解决DNGuard的乱码问题外,还可以修复入口点,是的,可以修复任意.net程序被破坏的掉的入口点。我已经考虑到4种被破坏入口点的情况,所以通用性应该还是不错的。原理嘛,画眉也说了:

.NET运行原理之调试分析【一】 By:凉游浅笔深画眉

我在.NET平台诞生了12年后才接触到它,而国内.NET平台的逆向技术兴起于10年前。

我是不幸的,不幸的是起步比前辈们晚了10年左右,十分后悔当初把最好的学习时间奉献给了游戏。最后发现,玩再多游戏也并没什么卵用。

我也是幸运的,幸运的是前人已留下了太多对.NET平台的探索脚印。我只需要跟随着他们的脚步快速前进,而不会绕很多弯路和四处碰壁。

最后感谢那些写过文章供后人学习的前辈们,虽然很多文章都是七八年前的,但受用至今。

此文既不是破解,也不讲脱壳,只是逆向角度分析.NET程序执行原理。仅希望抛砖引玉,待各位大牛们帮我完善接下来的分析过程。

-----------------------------------------------------------------------------------------------------分割线------------------------------------------------------------------------------------------------------------------

调试环境:Windows XP SP3 注:调试环境请使用Win7之前的系统,Win7之后的系统有所变化。

目标对象:一个基于.NET Framework 2.0框架编写的EXE文件

所需工具:IDA,OllyDbg,WinDBG,CFFExplorer,Depends

1.首先我们用CFF打开一个.NET程序,找到可选头,这里有个AddressOfEntryPont域,它的值是000030CE,这是一个RVA(相对虚拟地址)。这个AddressOfEntryPont标志着加载器要运行加载PE文件时执行的第一个指令的地址。

2.我们再找到ImageBase这个域,它的值是00400000,ImageBse标志着程序载入内存的理想初始地址(基地址),这里也是为什么采用XP系统来调试.NET程序的原因,有兴趣的朋友可以研究下。

3.我们可以看到AddressOfEntryPont位于.text区段上,我们来计算一下这个000030CE在文件中的物理地址是多少:

物理地址=RVA-Visual Address+Raw Address

由图可知 Visual Address=2000,Raw Address = 200

所以: 物理地址=000030CE-2000+200=12CE

4.我们切换到十六进制编辑界面,找到12CE位置,下图可以看到这几个字符 FF 25 00 20 40 00

5.FF 25 00 20 40 00是什么意思,我们打开OD来看看。在OD中,我们按Ctrl+B,然后输入FF 25可以看到,FF25代表的是汇编指令中的JMP,也就是无条件跳转。后面的00 20 40 00,其实是一个内存地址00402000,所以整句代码连起来就是 jmp 00402000 (意思就是程序加载后直接跳转到00402000这里来执行)。

6.为了验证我们刚才所分析的是否正确,我们现在需要借助WinDBG来进行分析。首先将目标程序载入WinDBG,程序会自动断下来。我们在Command窗口中可以看到如下信息,程序主模块从00400000处开始加载,也就是我们刚才在CFF中看到的ImageBase(基地址)。

7.配合我们刚才的偏移地址000030CE,我们在下面的命令栏中输入指令“u 00400000+000030CE”,这条指令的意思是从地址00400000+000030CE处反编译8条机器码。

8.回车之后看到了一个让我们心动的结果,004030CE处的前6个字节反编译对应的汇编代码为 Jmp 00402000,正好验证了我们前面的分析。

9.证实了前面的分析完全正确,接下来我们我们去探索一下00402000究竟什么。下一步我们在命令栏中输入dps WindowsFormsApplication3+0x2000 也可以输入dps 00402000

10.回车之后看到如下信息mscoree!CorExeMain,可以看到00402000这个地址代表的是mscoree.dll这个模块的_CorExeMain函数,位置在79004ddb处。

11.如果WinDBG看上去并不是那么直观,那我们继续借助OD来分析吧。我们用OD中载入程序,Ctrl+G转到我们在WinDBG中看到的地址79004ddb处,然后F2在这个地址下断点。

12.重新载入并运行当前程序,程序执行到我们刚才下断点的地方就会自动断下来。这时候留心观察寄存器里EIP的值(为什么要观察EIP,因为EIP标志着程序将执行的下一句指令),我们可以很清楚地看到,程序下一句将要执行的是mscoree.dll这个模块中的_CorExeMain函数。

13.既然程序的加载需要调用到mscoree.dll中的_CorExeMain函数,那么我们很容易猜想到,_CorExeMain函数会被保存到程序的导入表中,程序运行的时候进行调用。我们在CFF中切换到到程序IAT(导入表),可以很清晰地看到,.NET程序导入了mscoree.dll的_CorExeMain函数,这也是.NET程序唯一的导入函数。

14.当然我们也可以借助于别的分析工具来分析当前程序依赖的DLL。

我们把目标程序用Depends载入,可以很清晰地看到该程序仅仅只依赖mscoree.dll中的_CorExeMain函数。

15.综上所述,PE Loader加载了.NET镜像文件之后,首先会执行一句JMP mscoree. _CorExeMain(这里特别指明是mscoree中的_CorExeMain是有原因的,今后有时间再讲述为什么特别指明mscoree这个模块),借助微软的mscoree.dll来启动我们的.NET托管运行环境。

_CorExeMain这个函数究竟做了哪些工作,如何一步一步启动托管运行环境的,等有时间继续写吧。

很多人问我SE+DNG壳脱壳时脱壳机报错如何修复。

以上文字如果你完全看懂了,足够用来解决SE壳+DNGuard壳脱壳时候报错,需要修复入口点的问题。

你没看懂也没关系,用了我这个工具你再也不用为无法修复.net入口点而苦恼了。 如下图,把两个勾都选上,注意在修复乱码过程中,需要选择未脱壳的原始文件。 点击开始修复,修复完成后,再用CFF打开看看。 但是注意,打开Data Directories[x]项看看,此处还有一处错误: 请按照上图所示,将Debug Directory RVA的值直接修改为0,然后保存。 运行再次修复的程序看看。 乱码问题解决了,入口点问题也解决了。但是,别忘了,我们才刚刚把第一层壳脱完。好在这个程序是DNGuard的试用版,因此直接用已有的工具脱壳DNGuard HVM Unpacker。http://www.52pojie.cn/thread-320711-1-2.html 啊,脱壳失败了,报错。一个新的错误,但是已经不是“试图使用链地址信息(有2个以上的节或有一个TLS节的IAT)加载无法验证执行文件”的错误了。 这个问题比较好修复,直接用Universal Fixer,只修复.net那块的: 再拿出DNGuard HVM Unpacke来脱再次修复的文件。 成功了!!!!!!!赶紧拿出ILSpy来看看,源码出现了!!! 激动!!!!!太激动了!!! 运行程序看看: 出错了!!!!What’s the Fuck!!!!!!!对不起,我骂人了,因为被折腾的受不了!!!! 经常搞.net开发的人应该知道,这个问题多半是由于配置文件或者资源不正确引起的。用CFF看看资源情况: 脱壳工具将部分资源弄丢了,导致无法运行。修复这里的资源很麻烦,还需要重新定位RVA地址。本文将介绍一种快捷的办法,那就利用微软自带的ILDASM和ILASM,先进行反编译,再编译回去。 但是我们发现在编译回去的过程中,遇到了如下错误。 xxx.il(553) : error : syntax error at token '[' in: IL_0002: newobj [ERROR: INVALID TOKEN 0x0A80003A] 于是代开il文件,找到553行。因为已经脱壳,因此直接把这些非法的地址全部在代码中注释掉,不会对程序有影响: 继续用ilasm编译,发现新的错误 xxx.il(605) : warning : Non-nested class has nested visibility (0x001035A7), changed to non-nested (0x001035A0) xxx.il(606) : error : Base class in interface 于是找到第606行 把下面整个这段代码删掉: .class interface abstract import serializable sealed nested famorassem beforefieldinit specialname rtspecialname $TD$7 extends [mscorlib]System.Object { } // end of class $TD$7 保存后再用ilasm编译,就可以编译成功了。 运行,完美,没有错误!!至此脱壳完成。 脱壳前大小:793KB,需要HVMRuntm.dll运行库。脱壳后8K,不需要运行库。 好了,看完本教程的人都可以拿着脱壳后的文件去找画眉加入Matrix了。 文中所有工具列表: 1. CFF: http://www.ntcore.com/exsuite.php 2. Universal Fixer :http://www.52pojie.cn/thread-82492-1-1.html 3. DNGuard HVM Unpacker。http://www.52pojie.cn/thread-320711-1-2.html 4. ILDASM/ILASM 微软VS2010以上版本自带 DOTNET4.0的反编译/编译工具。 5. Donet Dumper, 乱码及入口点修复工具(本人作品),脱壳后的文件:

Tools.rar (1006.26 KB, 下载次数: 92) (有bug会再更新,最后更新时间2015-11-28 19:34) 6. unpackme原文件:

UnpackMe.rar (1023.97 KB, 下载次数: 57) (注意,原始unpackme杀毒软件报毒,为安全起见,请在虚拟机下运行。非本人软件,不能保证其安全性)

文件下载请参看左下角原文链接。

--官方论坛

www.52pojie.cn

============================================

微信官方开源UI库-WeUI https://github.com/weui/weui

在线演示:http://weui.github.io/weui/

Gulp实战:http://i5ting.github.io/stuq-gulp/

本文分享自微信公众号 - 我为Net狂(dotNetCrazy),作者:吾爱

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2015-12-02

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

posted @ 2020-08-26 11:44  特洛伊-Micro  阅读(1549)  评论(0编辑  收藏  举报