.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,一经查实,立即删除!

相关文章

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图片消息、窗口抖动、语音发送、语音播放、语音播放问题、玩…

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

一、设计思路 &#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分析…

物理专线流量平滑切换

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

怎么实现动态设置静态文件存储目录?

前言文章名字有点绕口&#xff0c;举例说明一下&#xff1a;多用户使用同一个网站上传文件&#xff0c;但是因为一些原因&#xff0c;文件需要存储到服务器的不同目录下。比如用户 A 对应 c:\abc&#xff0c;用户 B 对应 d:\xyz\123。并且&#xff0c;文件需要以静态文件方式提…

编写函数判断一个数是否是回文数_程序员面试金典 - 面试题 01.04. 回文排列

题目难度: 简单原题链接 题目描述给定一个字符串&#xff0c;编写一个函数判定其是否为某个回文串的排列之一。回文串是指正反两个方向都一样的单词或短语。排列是指字母的重新排列。回文串不一定是字典当中的单词。示例 1&#xff1a;输入&#xff1a;"tactcoa" 输出…

Facebook为Messenger应用添加群组付款功能

Facebook在2015年为Messenger应用添加了好友免费转账功能。这个使得用户可以方便安全地向朋友转账&#xff0c;但是如果用户需要向多人支付&#xff0c;可能会耗费时间。幸运的是&#xff0c;Facebook已经通过其最新的Messenger应用更新解决了这个缺点。扩展付款功能现在允许用…

Xamarin.Forms 5.0 项目实战发布!

活动介绍本次活动主要是 .NET Xamarin.Forms 移动端项目开发实战教程, 与以往相同, 本次的收入(其它部分会另行说明) 将用于社区公益活动, 不限于:公益性质的个人/组织机构捐赠开源社区个人/项目捐赠内部投票活动本次的活动费用为:399元, 相对于去年组织的WPF公益实战视频而言,…

unity webgl读写txt文件_VB 读写txt文件

No.7 读写txt文件​mp.weixin.qq.com许多程序需要读写数据&#xff0c;比如商品管理&#xff0c;图书管理&#xff0c;学生档案等&#xff0c;当需要查询的时候&#xff0c;就是读取数据&#xff0c;新增或者更改就需要写数据&#xff0c;VB来讲&#xff0c;中小型的数据一般用…

地图投影系列介绍(一)----地球空间模型

1、现实世界和坐标空间的联系 任何空间特征都表示为地球表面的一个特定位置,而位置依赖于既定的坐标系来表示。 通过统一的坐标系和高程系,可以使不同源的GIS数据叠加在一起显示,以及执行空间分析。 2、地球空间模型描述

layui 数字步进器_图解全新奔驰S级:从“传统豪华”向“数字豪华”转型

全新奔驰S级的全球首发&#xff0c;中国这次也同步进行亮相。而且在全球首发之前的6个小时&#xff0c;就邀请了中国媒体提早进行品鉴。讲真&#xff0c;虽然之前我也不看好新S级&#xff0c;尤其是此前不知道在哪里泄露出来的图片&#xff0c;看着这台车的气场远不及W222来得强…

C# 一个基于.NET Core3.1的开源项目帮你彻底搞懂WPF框架Prism

--概述这个项目演示了如何在WPF中使用各种Prism功能的示例。如果您刚刚开始使用Prism&#xff0c;建议您从第一个示例开始&#xff0c;按顺序从列表中开始。每个示例都基于前一个示例的概念。此项目平台框架&#xff1a;.NET Core 3.1Prism版本&#xff1a;8.0.0.1909提示&…

地图投影系列介绍(二)----地理坐标系

3、地理坐标系 地球的形状与大小确定之后,还必须确定椭球体与大地水准面的相对关系,这项工作称为椭球定位与定向。与大地水准面符合得最好的一个地球椭球体,称为参考椭球体,是地球形体三级逼近。 说到这里,我们需要对这几个词汇做区分:

同一个工作组无法查看计算机,win7系统在同一个工作组看不到其他电脑的解决方法...

很多小伙伴都遇到过win7系统点击右键保存图片时没有另存为选项该的困惑吧&#xff0c;一些朋友看过网上零散的win7系统点击右键保存图片时没有另存为选项该的处理方法&#xff0c;并没有完完全全明白win7系统点击右键保存图片时没有另存为选项该是如何解决的&#xff0c;今天小…

bootstrap 开源框架demo_5 个接私活必备的 Java 开源项目!

公众号关注 “GitHubDaily”设为 “星标”&#xff0c;每天带你逛 GitHub&#xff01;大家好&#xff0c;我是 Guide 哥&#xff0c;一个三观比主角还正的技术人。今天推荐几个 Java 项目快速开发脚手架&#xff0c;解放双手 ✋ 从现在开始。以下推荐项目都是码云上的优质项目&…

C#隐藏桌面图标和任务栏

最近因为项目需要需要实现桌面图标和任务状态栏的隐藏功能&#xff0c;实现的方式很多&#xff0c;比如修改注册表值&#xff0c;调用windows API函数等。经过一番的查阅&#xff0c;这个功能暂时实现了&#xff0c;或许不是很好的方法&#xff0c;但是我预期的效果达到了&…

CacheManager - 用 C# 编写的 .NET 的开源缓存抽象层

简介CacheManager 是用 C# 编写的 .NET 的开源缓存抽象层。它支持各种缓存提供程序并实现了许多高级功能CacheManager 是用 C# 编写的 .NET 的开源缓存抽象层。它支持各种缓存提供程序并实现了许多高级功能。CacheManager 包的主要目标是让开发人员的生活更容易处理&#xff0c…