当前位置:首页 > 教程 > 正文

.Net零基础逆向教程 —— 第十课(de4dot反混淆)

想了半天才想出这么一个案例,来一起看一看:

我们要做的操作是分析出人能读懂的源代码

查壳看一下:

首先是一个Agile .NET的壳,de4dot搞掉它

脱壳后显示如图:

丢入dnSpy看看,没脱干净

换个查壳工具看一下

还有一层.NET Reactor的壳

那么DIE无法查出这层壳的原因在于它对.NET Reactor的判断逻辑

// DIE's signature file

init("protector",".NET Reactor");

function detect(bShowType,bShowVersion,bShowOptions)

{

if(PE.section[".reacto"])

{

if(PE.section[1].FileSize==0&&PE.section[2].FileSize==0&&PE.section[3].FileSize==0)

{

sVersion="2.0-2.1";

bDetected=1;

}

}

else if(PE.compareEP("558becb90f0000006a006a004975f951535657b8........e8"))

{

sVersion="2.X-3.X";

bDetected=1;

}

else if(PE.resource["__"]&&PE.compareEP("e8$$$$$$$$8bff558bec83ec10"))

{

if(PE.compareEP("e8........e9........6a0c68"))

{

sVersion="4.2";

bDetected=1;

}

else if(PE.compareEP("e8........e9........8bff558bec83ec208b45085657"))

{

sVersion="4.5-4.7";

bDetected=1;

}

}

else if(PE.isNET())

{

if(PE.isSignatureInSectionPresent(0,"558becb90f0000006a006a004975f951535657b8........e8"))

{

sVersion="3.X";

bDetected=1;

}

else if(PE.section.length>=2)

{

if(PE.section[1].Characteristics==0xc0000040)

{

if(PE.isSignatureInSectionPresent(1,"5266686E204D182276B5331112330C6D0A204D18229EA129611C76B505190158"))

{

sVersion="4.8-4.9";

bDetected=1;

}

}

}

}

return result(bShowType,bShowVersion,bShowOptions);

}

再用de4dot来查一下壳看看:

使用快捷键Win+R打开运行窗口,输入cmd,点确定

接下来的操作我们需要在这个窗口里做,因为我电脑CMD莫名其妙奔溃,我就在PentestBox里写了,命令和效果是一样的。

如上图,将de4dot.exe直接拖拽到cmd窗口里,会自动生成一个"D:\Program Files (x86)\de4dot\de4dot\de4dot.exe"的路径,然后你需要敲一个空格,然后把要查壳的软件拖进去,再敲一个空格,然后输入-d

完整的命令为:

 "D:\Program Files (x86)\de4dot\de4dot\de4dot.exe" C:\Users\muruoxi\Desktop\EP10_Locked\Secured\EP10-cleaned.exe -d

回车执行后你可以看到Detected .NET Reactor的字样,说明是.NET Reactor的混淆。

那简单,直接拖入de4dot脱壳即可。

如上图,已经能看到源码了。

值得注意的是,上图中你能看到一个看起来很傻逼的IF语句,需要注意的是这并不是写程序的我傻逼,而是.Net在编译的时候自动优化了代码,之前这个函数体是switch结构。


de4dot除了查壳以外还有其他的参数可供使用,十分强大,我很不走心的把作者发布在github的文档机翻一下,有兴趣的可以自己翻译。网址:https://github.com/0xd4d/de4dot

描述

de4dot是一个用C#编写的开源(GPLv3).NET反混淆器和解包器。它将尽力将打包和混淆的程序集恢复到几乎原始程序集。大多数混淆都可以完全恢复(例如字符串加密),但符号重命名是不可能恢复的,因为原始名称(通常)不是混淆程序集的一部分。

它使用dnlib来读取和写入程序集,因此请确保获取它或者它不会编译。

二进制

构建服务器获取二进制文件。

它是免费的,但没有任何支持

没有支持。如果您无法使用它或者无法对使用更新的混淆器进行模糊处理的文件进行反混淆处理,请不要给我发电子邮件。

相反,尝试自己更新de4dot。这比你想象的容易得多。如果你不能,搜索互联网,你应该找到几个论坛,你可以问你的问题。

特征

这是一个伪随机列表,它将根据使用混淆器来混淆程序集所做的事情:

  • 内联方法。一些混淆器将方法的一小部分移动到另一个静态方法并调用它。
  • 静态或动态解密字符串
  • 解密其他常量。一些混淆器也可以加密其他常量,例如所有整数,所有双精度等。
  • 静态或动态解密方法
  • 删除代理方法。许多混淆器通过调用委托来替换大多数/所有呼叫指令。该委托反过来调用真正的方法。
  • 重命名符号。即使大多数符号无法恢复,它也会将它们重命名为人类可读的字符串。但有时候,一些原始名称可以恢复。
  • 虚拟化虚拟化代码
  • 解密资源。许多混淆器都可以选择加密.NET资源。
  • 解密嵌入文件。许多混淆器可以选择嵌入并可能加密/压缩其他程序集。
  • 删除篡改检测代码
  • 删除反调试代码
  • 控制流程反混淆。许多混淆器修改了IL代码,因此它看起来像意大利面条代码,因此很难理解代码。
  • 恢复类字段。一些混淆器可以将字段从一个类移动到另一个混淆器创建的类。
  • 将PE exe转换为.NET exe。一些混淆器将.NET程序集包装在Win32 PE中,因此.NET反编译器无法读取该文件。
  • 删除混淆器添加的大多数/所有垃圾类。
  • 修复了一些peverify错误。许多混淆器都是错误的,并且错误地创建了无法验证的代码。
  • 恢复方法参数和字段的类型

支持的混淆器/打包器

  • Agile.NET(又名CliSecure)
  • Babel.NET
  • CodeFort
  • CodeVeil
  • CodeWall
  • CryptoObfuscator
  • DeepSea混淆器
  • Dotfuscator的
  • .NET Reactor
  • Eazfuscator.NET
  • Goliath.NET
  • ILProtector
  • MaxtoCode
  • MPRESS
  • 临检
  • Skater.NET
  • SmartAssembly
  • Spices.Net
  • Xenocode

上面的一些混淆器很少使用(例如Goliath.NET),所以它们的测试要少得多。通过报告您发现的错误或问题来帮助我。

警告

有时,混淆的程序集及其所有依赖项将加载到内存中以供执行。如果您怀疑程序集或程序集是恶意软件,请使用安全的沙箱环境。

即使当前版本的de4dot没有将某个程序集加载到内存中执行,未来的版本也可能。

如何使用de4dot

N00b用户

将文件拖放到de4dot.exe并等待几秒钟。

一次反复处理多个文件

如果对多个程序集进行了模糊处理,除非禁用符号重命名,否则很可能必须同时对它们进行反混淆处理。原因是如果程序集A在程序集B中引用了类C,并且只在程序集B中重命名符号,则可以将类C重命名为例如。Class0但程序集A中的引用仍然引用程序集B中名为C的类。如果同时对两个程序集进行反混淆处理,则所有引用也将更新。

找到所有混淆的文件并对其进行反混淆处理

以下命令行将对由支持的混淆器进行模糊处理的所有程序集进行反混淆处理,并将程序集保存到 c:\output

de4dot -r c:\input -ru -ro c:\output

-r意味着递归搜索。-ru意味着它应该忽略未知文件。-ro意味着它应该将输出文件放在以下目录中。通常,您首先复制c:\inputc:\output,然后运行该命令。这样所有文件都将进入c:\output,甚至是非组件和非处理组件。当de4dot完成后,你只需双击主程序集就可以了c:\output,它应该有希望开始。

检测混淆器

使用该-d选项可以在不对任何程序集进行反混淆处理的情况下检测混淆器。

查找所有.NET程序集并检测混淆器。如果它是一个不受支持的混淆器,或者它没有被混淆,它将打印“Unknown obfuscator”。

de4dot -d -r c:\input

与上面相同,只是它只显示受支持的混淆器对哪些文件进行了模糊处理。

de4dot -d -r c:\input -ru

检测混淆器

de4dot -d file1.dll file2.dll file3.dll

保留元数据令牌

有时在极少数情况下,您需要保留元数据令牌。使用--preserve-tokens--preserve-table。还要考虑使用,--keep-types因为它不会删除混淆器添加的任何类型和方法。另一个有用的选择是--dont-create-params。如果使用,重命名器将不会为没有Param行的方法参数创建Param行。这样,ParamPtr表将不会添加到您的程序集中。Peverify有一个bug并且不支持它(你会看到很多“错误”)。

的#Strings,#US和#Blob堆也可以通过使用保存--preserve-strings--preserve-us--preserve-blob分别。其中三个--preserve-us是自ldstr指令以来最有用的一个并module.ResolveString()直接引用#US堆。

--preserve-sig-data如果混淆器在其用于其自身目的的签名末尾添加额外数据,则应使用,例如。作为解密密钥。Confuser是一个这样做的混淆器。

--preserve-tokens保留所有重要的令牌,但也会启用--preserve-us--preserve-blob--preserve-sig-data

如果它被检测为未知(不支持)的混淆器(或者如果强制它-p un),则会保留所有令牌,包括#US堆和签名末尾的任何额外数据。此外,不会删除混淆器类型,字段或方法。

保留所有重要的令牌,#US,#Blob,额外的sig数据。

de4dot --preserve-tokens file1.dll

保留所有重要的令牌,#US,#Blob,额外的sig数据,不要删除混淆器添加的类型/字段

de4dot --keep-types --preserve-tokens file1.dll

保留所有重要的令牌,#US,#Bubb,额外的sig数据,不要创建额外的Param行以防止创建ParamPtr表。

de4dot --dont-create-params --preserve-tokens file1.dll

保留除Param令牌之外的所有重要令牌。

de4dot --preserve-table all,-pd file1.dll

动态解密字符串

虽然de4dot支持很多混淆器,但仍有一些它不支持。要解密字符串,首先需要确定哪些方法可以解密字符串。要获取这些字符串解密器的方法标记,可以使用ILDASM并启用“show metadata tokens”选项。方法令牌是32位数字,以06开头,例如。06012345。

此命令将通过调用将程序集file1.dll加载到内存中Assembly.Load()。当它检测到对两个字符串解密器(06012345和060ABCDE)的调用时,它将通过创建动态方法来调用它们,并保存结果(解密的字符串)。将删除对字符串解密器的调用,并且解密的字符串将在其位置。

de4dot file1.dll --strtyp delegate --strtok 06012345 --strtok 060ABCDE

由于程序集已加载并执行,因此如果您怀疑该文件是恶意软件,请确保在沙箱中运行此程序集。

强制检测某个混淆器

de4dot并不完美。如果它无法检测到混淆器,您可以使用该-p选项强制它假定它已被混淆。

强制SmartAssembly

de4dot file1.dll -p sa

强制不支持的混淆器

de4dot file1.dll -p un

对于其他混淆器类型,请参阅帮助屏幕。

禁用符号重命名

重命名符号并不像在涉及反射时将A重命名为B一样容易。de4dot目前不支持重命名XAML,因此如果您怀疑它使用WPF(或者如果它是Silverlight应用程序),则应该在程序集无法运行时禁用重命名。

de4dot --dont-rename file1.dll file2.dll

--keep-names也可以用来告诉de4dot不要重命名某些符号,例如。“不要重命名字段”。

重命名除属性,事件和方法之外应重命名的所有内容。

de4dot --keep-names pem file1.dll

使用不同的重命名正则表达式

默认正则表达式应该足够,除了可能是检测到不支持的混淆器时使用的正则表达式。要查看所有默认正则表达式,请在de4dot不带任何参数的情况下启动,它将列出所有选项和所有默认值。

例如,目前以下是检测到Dotfuscator时使用的默认正则表达式

!^[a-z][a-z0-9]{0,2}$&!^A_[0-9]+$&^[\u2E80-\u9FFFa-zA-Z_<{$][\u2E80-\u9FFFa-zA-Z_0-9<>{}$.`-]*$

正如您所看到的,它不仅仅是一个正则表达式,它不止一个。每一个都被分开&,每个正则表达式都可以通过!在它前面使用来否定。为了更清楚地显示它们,使用了这些正则表达式:

(negated) ^[a-z][a-z0-9]{0,2}$(negated) ^A_[0-9]+$^[\u2E80-\u9FFFa-zA-Z_<{$][\u2E80-\u9FFFa-zA-Z_0-9<>{}$.`-]*$

要更改正则表达式,您必须知道混淆器的短类型名称(请参阅帮助屏幕)。例如。它是saSmartAssembly,un如果它是一个不受支持/未知的混淆器。使用的选项是--TYPE-name(例如,--sa-name对于SmartAssembly和--un-name未知/不支持的混淆器):

de4dot --un-name "^[a-zA-Z]\w*$" file1.dll

其他选择

de4dot没有任何参数开始,它将显示所有选项。


dnSpy这个软件我已经交代的差不多了,今天再补一课de4dot的。

基础课就这十课,以后如果有实战课的话会发在知识星球,希望低调阅读不要转载。毕竟实战涉及到其他人软件的版权之类乱七八糟的事儿,这几年我好处没捞到各公司法务部的函件收了一堆。

祝各位有所收获。

慕若曦  2019/04/27


课件下载:https://articles.zsxq.com/id_xsqu5w2zvumf.html


 

本博客资源若无特殊说明,均为和谐版本,无需付费,我不搞软件的会员,也不接受指定的和谐业务。

软件无法下载/安装/其它电脑问题,免费加QQ群(500人):949039296

有问题加上面的群,直接群里问,在线的时候有问必答,私聊一般都不看

想打赏微信扫右边的二维码,不建议超过10元,没指望靠这个养活我

 
文章标题:.Net零基础逆向教程 —— 第十课(de4dot反混淆)
本文作者:慕若曦
发表日期:2019-04-29 02:50 星期一    首发于    暮若夕
本文固定链接: https://www.muruoxi.com/jiaocheng/4111.html
 
文章标签:
上一篇: 下一篇:

1 条评论

评论加载中...
  1. 沙发
    小飞雪  

    学会了,感谢美女博主

    2019年4月29日 下午4:03 评论

发表评论

╮( ̄▽ ̄)╭ | (= ̄ω ̄=) | (>﹏<) | Σ( ° △ °|||)︴ | Σ(っ °Д °;)っ | X﹏X | (╯-_-)╯╧╧

小提示:提交评论后刷新本页面即可看到隐藏的文件哦~
十年之约
加载中……