.NET 6 使用 Obfuscar 进行代码混淆

本文来安利大家 Obfuscar 这个好用的基于 MIT 协议开源的混淆工具。这是一个非常老牌的混淆工具,从 2014 年就对外分发,如今已有累计 495.5K 的 nuget 下载量。而且此工具也在不断持续迭代更新,完全支持 dotnet 6 版本,对 WPF 和 WinForms 等等的支持也是非常好,支持多个不同混淆方式和等级的配置,支持混淆之后生成符号文件。本文将来告诉大家如何使用此混淆工具,以及此工具能达成的效果和此工具混淆的原理

开源

此工具是由 Lex Li 主导开发的,在 GitHub 上使用 MIT 最友好协议开源,开源地址是 https://github.com/obfuscar/obfuscar

使用方法

此工具的使用方式有多个不同的方式,比较推荐的是采用 dotnet tool 的方式进行使用。因为使用 dotnet tool 可以非常方便接入自己已有的 CI CD 上,而且也可以实现非常方便的更新逻辑

按照约定,使用 dotnet tool 的第一步是进行安装,安装的方法就是在命令行输入以下代码

dotnet tool install --global Obfuscar.GlobalTool

如此即可完成安装。安装完成之后的使用方法是调用 obfuscar.console 命令,传入混淆配置 Obfuscar.xml 文件即可,如下面命令行例子

obfuscar.console Obfuscar.xml

也就是说最关键的只有两点,第一个就是命令行的工作路径,另一个就是混淆配置 Obfuscar.xml 文件

假定我有一个项目是 HeenerholiCeleehano 项目,此项目我需要对他进行混淆。此项目输出的是 HeenerholiCeleehano.dll 文件,放在 C:\lindexi\Code\lindexi\HeenerholiCeleehano\HeenerholiCeleehano\bin\Release\net6.0-windows\ 文件夹下

那么在混淆之前,请设置好命令行的工作路径,如使用 cd 命令进入到输出文件夹,如以下命令

cd C\lindexi\Code\lindexi\HeenerholiCeleehano\HeenerholiCeleehano\bin\Release\net6.0-windows\

接下来是要在 C:\lindexi\Code\lindexi\HeenerholiCeleehano\HeenerholiCeleehano\bin\Release\net6.0-windows\ 文件夹下放一个混淆配置 Obfuscar.xml 文件,文件内容可以是如下

<?xml version='1.0'?>
<Obfuscator><Var name="InPath" value="." /><Var name="OutPath" value=".\Obfuscar" /><Var name="KeepPublicApi" value="true" /><Var name="HidePrivateApi" value="true" /><Var name="HideStrings" value="false" /><Var name="UseUnicodeNames" value="true" /><Var name="ReuseNames" value="true" /><Var name="RenameFields" value="true" /><Var name="RegenerateDebugInfo" value="true" /><Module file="$(InPath)\HeenerholiCeleehano.dll" /><AssemblySearchPath path="C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\6.0.1\" /><AssemblySearchPath path="C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.1\" />
</Obfuscator>

以上配置文件的含义如下,我一一带上注释标识

<?xml version='1.0'?>
<Obfuscator><!-- 输入的工作路径,采用如约定的 Windows 下的路径表示法,如以下表示当前工作路径 --><!-- 推荐使用当前工作路径,因为 DLL 的混淆过程,需要找到 DLL 的所有依赖。刚好当前工作路径下,基本都能满足条件 --><Var name="InPath" value="." /><!-- 混淆之后的输出路径,如下面代码,设置为当前工作路径下的 Obfuscar 文件夹 --><!-- 混淆完成之后的新 DLL 将会存放在此文件夹里 --><Var name="OutPath" value=".\Obfuscar" /><!-- 以下的都是细节的配置,配置如何进行混淆 --><!-- 使用 KeepPublicApi 配置是否保持公开的 API 不进行混淆签名,如公开的类型公开的方法等等,就不进行混淆签名了 --><!-- 语法的写法就是 name 表示某个开关,而 value 表示值 --><!-- 对于大部分的库来说,设置公开的 API 不进行混淆是符合预期的 --><Var name="KeepPublicApi" value="true" /><!-- 设置 HidePrivateApi 为 true 表示,对于私有的 API 进行隐藏,隐藏也就是混淆的意思 --><!-- 可以通过后续的配置,设置混淆的方式,例如使用 ABC 字符替换,或者使用不可见的 Unicode 代替 --><Var name="HidePrivateApi" value="true" /><!-- 设置 HideStrings 为 true 可以设置是否将使用的字符串进行二次编码 --><!-- 由于进行二次编码,将会稍微伤一点点性能,二次编码需要在运行的时候,调用 Encoding 进行转换为字符串 --><Var name="HideStrings" value="false" /><!-- 设置 UseUnicodeNames 为 true 表示使用不可见的 Unicode 字符代替原有的命名,通过此配置,可以让反编译看到的类和命名空间和成员等内容都是不可见的字符 --><Var name="UseUnicodeNames" value="true" /><!-- 是否复用命名,设置为 true 的时候,将会复用命名,如在不同的类型里面,对字段进行混淆,那么不同的类型的字段可以是重名的 --><!-- 设置为 false 的时候,全局将不会有重复的命名 --><Var name="ReuseNames" value="true" /><!-- 配置是否需要重命名字段,默认配置了 HidePrivateApi 为 true 将都会打开重命名字段,因此这个配置的存在只是用来配置为 false 表示不要重命名字段 --><Var name="RenameFields" value="true" /><!-- 是否需要重新生成调试信息,生成 PDB 符号文件 --><Var name="RegenerateDebugInfo" value="true" /><!-- 需要进行混淆的程序集,可以传入很多个,如传入一排排 --><!-- <Module file="$(InPath)\Lib1.dll" /> --><!-- <Module file="$(InPath)\Lib2.dll" /> --><Module file="$(InPath)\HeenerholiCeleehano.dll" /><!-- 程序集的引用加载路径,对于 dotnet 6 应用,特别是 WPF 或 WinForms 项目,是需要特别指定引用加载路径的 --><!-- 这里有一个小的需要敲黑板的知识点,应该让 Microsoft.WindowsDesktop.App 放在 Microsoft.NETCore.App 之前 --><!-- 对于部分项目,如果没有找到如下顺序,将会在混淆过程中,将某些程序集解析为旧版本,从而失败 --><AssemblySearchPath path="C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\6.0.1\" /><AssemblySearchPath path="C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.1\" />
</Obfuscator>

详细的配置,还请参阅官方文档

执行如上的命令行进行混淆,即可实现命名混淆效果

7e37dba56d0e0cf85a675531fc9a467b.png

使用 dotPeek 反编译可以看到字段被混淆为如下内容

private readonly int \u00A0;private readonly short \u00A0;

这里需要复习一下 IL 的知识,在 IL 里面,是允许不同的字段重名的,只要字段的类型不相同即可。因为使用的时候,是用类型名加字段名的方式使用的。这也能让代码更加混淆

以上就是我推荐的使用 dotnet tool 的方式

除了使用 dotnet tool 的方式之外,还可以自己将混淆过程嵌入到构建过程里面,如此可以实现在开发阶段对混淆的结果进行调试。也就是开发时调试的 DLL 就是混淆过后的

使用构建过程的方式需要编辑一下 csproj 项目文件,先在项目文件使用下面代码安装 Obfuscar 库,代码如下

<ItemGroup><PackageReference Include="Obfuscar" Version="2.2.33"><PrivateAssets>all</PrivateAssets><IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets></PackageReference></ItemGroup>

在需要写构建过程下,预计实际需求都是千奇百怪的,很难有统一的方式,本文只是提供一个简单的例子

完成安装之后,在项目上放一个混淆配置 Obfuscar.xml 文件,设置此文件如果较新则输出

<ItemGroup><None Update="Obfuscar.xml"><CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory></None></ItemGroup>

最后编写一个 Target 用来在构建完成之后调用命令行进行混淆,代码如下

<Target Name="ObfuscarTask" AfterTargets="AfterBuild"><PropertyGroup><ObfuscateCommand>$(Obfuscar) "Obfuscar.xml"</ObfuscateCommand></PropertyGroup><Exec WorkingDirectory="$(OutputPath)" Command="$(ObfuscateCommand)" /></Target>

如此即可实现在构建完成之后,自动调用

以上的代码放在 github 和 gitee 欢迎访问

可以通过如下方式获取本文的源代码,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin b0b402abe4f32008d383d984bff677ac45cccde8

以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git

获取代码之后,进入 HeenerholiCeleehano 文件夹

以上代码的混淆配置 Obfuscar.xml 文件里使用的程序集引用路径写的是 C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\6.0.1\ 路径,这是因为代码是之前写的,博客是鸽子很久才写的,还请大家自行更新

混淆原理

此混淆工具底层使用 Mono.Cecil 进行程序集的读取和编织,使用 Mono.Cecil 可以读取出程序集的信息,从读取到的信息进行更改,更改也就是混淆的核心逻辑,更改完成之后,再通过 Mono.Cecil 生成新的程序集文件,如此即可完成混淆

此工具在 GitHub 上完全开源,请看 https://github.com/obfuscar/obfuscar

更多细节逻辑还请自己去阅读源代码

更多阅读

其他的混淆工具还有非常多,可以从 https://github.com/NotPrab/.NET-Obfuscator 找到更多的混淆工具列表

当然,有混淆工具,也就有反混淆工具。可以从 https://github.com/NotPrab/.NET-Deobfuscator 找到更多反混淆列表

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/289428.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

html的canvas标签用法,html5中关于canvas标签用法(绘图)

标签只是图形容器&#xff0c;您必须使用脚本来绘制图形。用canvas配合javascript可以直接在html页面动态绘图&#xff0c;无需调用jquery。代码如下&#xff1a;var my_canvasdocument.getelementbyid("canvas"); //获取canvas的idvar contextmy_canvas.getcontext(…

C#生成二维码(含解码)

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms;using System.Collections; using com.google.zxing;//需要从网上下载 using S…

Android之在TextView里面部分文字变颜色并且可以点击

1、问题 在TextView里面部分文字变颜色并且可以点击 2、借助SpannableString SpannableString和String一样,是一种字符串类型 public void setSpan(Object what, int start, int end, int flags) {super.setSpan(what, start, end, flags);} what表示设置格式是,可以是可点…

springmvc 传对象报400_那么火的SpringMVC到底有什么过人之处呢

先简单聊聊SpringMVC如果你们玩知乎&#xff0c;很可能会看到我的身影。我经常会去知乎水回答。在知乎有很多初学者都会问的一个问题&#xff1a;「我学习SpringMVC需要什么样的基础」我一定会让他们先学Servlet&#xff0c;再学SpringMVC的。虽然说我们在现实开发中几乎不会写…

matlab cftool代码_Matlab工具箱之拟合算法

和插值算法相比&#xff0c;拟合算法的优势在于拟合曲线不需要经过所有样本点&#xff0c;所以能降低函数的复杂程度。我们可以通过观察散点图目测拟合函数的大致形式&#xff0c;然后用最小二乘法计算待估参数。这时候Matlab就能发挥作用了&#xff0c;因为它提供了非常强大的…

WPF效果第一百七十八篇ItemsControl旋转

在前面分享的几篇中咱已经玩耍了Popup、ListBox多选、Grid动态分、RadioButton模板、控件的拖放效果、控件的置顶和置底、控件的锁定、自定义Window样式、动画效果、Expander控件、ListBox折叠列表、聊天窗口、ListBox图片消息、窗口抖动、语音发送、语音播放、语音播放问题、玩…

计算机安全专家建议:尽快为电脑升级打补丁

新型“蠕虫”式勒索病毒爆发&#xff0c;国家网络与信息安全中心紧急通报 5月13日下午&#xff0c;国家网络与信息安全信息通报中心紧急通报&#xff1a;12日20时左右&#xff0c;新型“蠕虫”式勒索病毒爆发&#xff0c;目前已有100多个国家和地区的数万台电脑遭该勒索病毒感染…

大型网站技术架构02 网站的高性能架构、网站的可用性架构

大型网站核心架构要素 1. 性能 2. 可用性 3. 伸缩性 4. 扩展性 5. 安全性 瞬时响应&#xff1a;网站的高性能架构 1. 网站性能测试&#xff1a; 1). 不同视角下的网站性能 a. 用户视角的网站性能&#xff1a;用户计算机&#xff0c;网站服务器通信时间&#xff0c;网站服务器处…

DateTime.Now.Ticks.ToString()说明

一个以0.1纳秒为单位的时间戳&#xff0c;就是一个long型的数&#xff0c;其实DateTime本质上就是一个long型的&#xff0c;通过0.1纳秒的单位&#xff0c;换算成各种时间&#xff0c;如果分&#xff0c;秒&#xff0c;年月日等等这些组合起来就是一个DateTime类型了 举例&…

linux之 !!命令

1、问题 在linux终端&#xff0c;我们知道快速用上一个命令&#xff0c;我们可以是用”上“键&#xff0c;但是这个键是键盘的右边的键&#xff0c;那还有其建有这个效果吗&#xff1f; 2、解决 我们可以使用下面的命令 &#xff01;&#xff01; 是刚一个毕业的应届生跑到…

sq工程师是做什么的_算法工程师为什么成天做数据,都做哪些数据?

大家好&#xff0c;前几天群里有小伙伴说希望看到更多的算法工程师的日常。其实对于算法工程师而言&#xff0c;最大的日常就是做数据了&#xff0c;所以给大家分享一下做数据的那些事。为什么很少做模型在大家想象当中&#xff0c;可能算法工程师做的事情是今天看paper&#x…

编写html要注意,编写XHTML需要注意的问题以及和HTML的区别

文档必须是编排良好的元素必须嵌套&#xff0c;尽管SGML规定层叠非法&#xff0c;但现有的浏览器普遍允许层叠。正确&#xff1a;嵌套元素。here is an emphasized paragraph.不正确&#xff1a;层叠元素。here is an emphasized paragraph.嵌套与层叠元素和属性名必须小写对所…

结对开发Ⅴ——循环一维数组求和最大的子数组

一、设计思路 &#xff08;1&#xff09;数据的存储结构是链表&#xff0c;最后一个结点的next指向第一个元素的结点&#xff1b; &#xff08;2&#xff09;数据个数为n&#xff0c;则最多有n*(n(n-1)...1)种情况&#xff08;包括重复&#xff09;&#xff1b; &#xff08;3&…

微软 MVP 福利大赏

前言成为微软 MVP 后, 可以获得微软提供的诸多福利。那具体有哪些福利呢&#xff1f;让我们一起来看看。行政表彰信行政表彰信宣布你的 MVP 身份&#xff0c;并恭祝你对技术社区的贡献。同时&#xff0c;概述了 MVP 项目的影响和意义。可以设置为 PDF 下载&#xff0c;也可以选…

canoco5主成分分析步骤_R语言 PCA主成分分析

微信公众号&#xff1a;生信小知识关注可了解更多的教程及生信知识。问题或建议&#xff0c;请公众号留言;R语言 PCA主成分分析前言统计学背景知识协方差相关系数函数总结实例讲解1.载入原始数据2.作主成分分析3.结果解读4.画主成分的碎石图并预测5.PCA结果绘制后记前言PCA分析…

地理术语

1、无霜期:指一年中终霜后至初霜前的一整段时间。在这一期间内,没有霜的出现。农作物的生长期与无霜期有密切关系。无霜期愈长,生长期也愈长。无霜期的长短因地而异,一般纬度、海拔高度愈低,无霜期愈长。 2、返青(turn green):指植物的幼苗移栽或越冬后,由黄色变为绿…

物理专线流量平滑切换

在从传统IDC向云上迁移过程中&#xff0c;物理专线作为连接云上和云下的桥梁&#xff0c;在混合云架构中占有绝对重要的地位。作为基础设施&#xff0c;在伴随业务不断发展的过程当中&#xff0c;也会进行相应的更换升级。本文将介绍在物理专线特定情况下进行流量切换时&#x…

Android之使用PopupWindow让背景变黯但是华为手机出现屏幕一闪一闪问题解决办法

1、问题 我们使用PopupWindow设置背景变黯(代码如下)&#xff0c;但是部分华为手机出现屏幕一闪一闪 //设置背景透明度public void setBackgroundAlpha(float bgAlpha) {WindowManager.LayoutParams lp CurrentActivity.this.getWindow().getAttributes();lp.alpha bgAlpha;…

利用计算机窃听,observer模拟监听器的实现

observer模拟监听器的实现考试吧(Exam8.com) 2008-10-14 08:00:00 评论(0)条学过awt,尤其是swing的就知道&#xff0c;swing中observer模式被大量的使用。比如&#xff0c;button.addActionListener(...)后&#xff0c;一旦你点击button后就能触发相应的事件。很多人一定想知道…

linux桌面版排行2019_新兴的桌面发行版 Septor Linux 发布 2019 版

导读Septor Linux 是一个新兴的桌面 GNU/Linux 发行版&#xff0c;基于 Debian “Testing” 分支&#xff0c;支持以 live 模式启动。其以 Tor 加密网络流量来匿名地访问网络&#xff0c;并搭载了一些常见的日用或匿名性软件。Septor Linux 是日益增多的关注于英特网访问时的匿…