使用Obfuscar 混淆WPF(Net6)程序

Obfuscar 是.Net 程序集的基本混淆器,它使用大量的重载将.Net程序集中的元数据(方法,属性、事件、字段、类型和命名空间的名称)重命名为最小集。详细使用方式参见:Obfuscar

在NetFramework框架进行的WPF程序的混淆比较容易,因为由Visual Studio 编译生成的exe文件直接包含托管代码,可以直接进行混淆,当在Net5.0 或者Net6.0 等跨平台框架中编译生成的exe只是一个单纯的启动器,并不包含可以混淆的托管代码。与exe同时生成的还有一个xx.dll文件,该文件真正的包含了托管代码,只需要对该dll进行混淆即可。

新建一个基于Net6的Wpf项目,这个过程简单,不再描述具体过程。混淆程序的方式很多,网上一番搜索,大部分都是在项目生成或者发布之后,通过执行obfuscar.xxx.exe ,传入要混淆文件路径来进行混淆。这种方式能达到同样的效果,但效率不高。后经搜索发现使用Obfuscar.MsBuild包可以直接在Visual Studio编译时直接对代码进行混淆。

引入Obfuscar

打开项目依赖项->右键点击管理nuget程序包,在左侧面板中点击浏览,输入obfuscar.

依次安装Obfuscar和Obfuscar.MsBuild。安装成功之后会在csproj文件中添加引用。

cs 复制代码
<PackageReference Include="Obfuscar" Version="2.2.38">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Obfuscar.MsBuild" Version="2.2.38.1" />

创建 Obfuscar.xml文件

在项目根目录创建obfuscar.xml文件,将其属性中的复制到输出目录修改为"始终复制",编辑xml内容如下:

XML 复制代码
<?xml version='1.0'?>
<Obfuscator>
	<!-- https://docs.obfuscar.com/getting-started/configuration.html -->
	<Var name="InPath" value=".\bin\Debug\net6.0-windows" />
	<Var name="OutPath" value=".\bin\Debug\net6.0-windows\obfuscated" />
	<!--
  Turning this on will break assemblies that have [InternalsVisibleTo]
  -->
	<Var name="KeepPublicApi" value="true" />
	<Var name="HidePrivateApi" value="true" />
	<Var name="HideStrings" value="true" />
	<Var name="RenameProperties" value="true" />
	<Var name="RenameEvents" value="false" />
	<Var name="ReuseNames" value="false" />
	<!--
  Disabled because EFCore does not like when fields are renamed
  https://github.com/dotnet/efcore/issues/25720
  -->
	<Var name="RenameFields" value="true" />
	<Var name="UseUnicodeNames" value="true" />
	<Var name="RegenerateDebugInfo" value="true" />
	<Module file="$(InPath)\WpfApp1.dll" />
	<AssemblySearchPath path="C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\6.0.21" />
	<AssemblySearchPath path="C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.21" />
</Obfuscator>

注意:InPath路径要指定正确,处于什么编译模式就指定到相应文件夹,Debug就是Debug,Release就是Release。OutPath指定到你知道的位置,obfuscated就是混淆文件的存放目录,下边的各种配置参见文档配置说明

AssemblySearchPath 指定要使用的程序集,这个很重要,如果不指定则混淆不成功。

重新生成程序,在Visual Studio中打开输出窗口,出现obfuscate的输出提示,标识混淆成功。

使用ILSpy工具打开obfuscated文件夹下的WpfApp1.dll文件,查看变量名称或者其它属性为混淆后的字符格式。

重新生成程序,我们把obfuscated文件夹下的WpfApp1.dll复制到net6-windows文件夹下,与WpfApp1.exe同级,点击运行exe文件,程序启动成功。

发布成单体应用程序

一般情况下会将程序进行发布,发布方式大多为发布到成文件夹的形式,关于发布到文件夹的方式网上很多例子,可以搜查一下,下边是发布到本地的路径位置。

修改发布参数

右键选中项目名称,点击"发布"选项。

  1. 配置:默认,不修改。
  2. 目标框架:默认,不修改。
  3. 部署模式:依赖框架。(依赖框架:运行时独立安装,exe体积小,启动快;独立:运行时打包进exe文件,exe体积大,启动慢)
  4. 目标运行时:win-x64(根据需要选择)
  5. 文件发布选项:勾选"生成单个文件"

点击"保存"之后进行发布,发布成功之后发现WpfApp1.dll文件找不到了,此时的dll已经被VS打包进对应的exe文件中。但使用ILSpy对exe文件进行反编译时,发现文件并没有被混淆。说明我们的混淆的dll文件和打包进去的dll文件并不是同一个,那么如何把混淆之后的dll文件打包进exe呢?

自定义Build过程

Visual Studio 在发布项目之前会进行编译,如果有语法错误或者编译文件被占用的情况会进行提示,编译成功之后会进入Build过程,将程序打包进exe文件。那么要在打包进exe之前将dll文件替换为混淆之后的文件。通过查询,可以通过自定义PostBuildEvent(生成后事件)来达到该目的。

修改混淆后的dll位置

将xml文件中OutPath路径修改为Release文件夹下:

<Var name="OutPath" value="D:\Test\WpfApp2\WpfApp1\bin\Release\net6.0-windows\obfuscated" />

注意:项目以那种配置进行的编译就要修改OutPath的路径。

修改程序csproj文件

cs 复制代码
	<Target Name="PostBuild" AfterTargets="PostBuildEvent">
		<Exec Command="copy &quot;$(SolutionDir)WpfApp1\bin\Release\net6.0-windows\obfuscated\WpfApp1.dll&quot;  &quot;$(SolutionDir)WpfApp1\obj\Release\net6.0-windows\win-x64\WpfApp1.dll&quot;" Condition="'$(ConfigurationName)' == 'Release'"/>
	</Target>

注意发布成单体程序时,Visual Studio 会从obj中的Release文件夹中执行打包过程。如果在项目中找不到obj文件夹,可以选中项目,点击顶部工具栏中的显示所有文件:

发布程序,在ILSpy中打开WpfApp1.exe查看混淆后的代码。

总结

直接混淆Debug或者Release文件夹下的exe流程麻烦、简单配置就行。但是通过发布形式,生成单体可执行文件踩了不少坑,不过都通过查阅资料解决。

相关推荐
月落.16 小时前
WPF的<ContentControl>控件
wpf
就是有点傻16 小时前
WPF中的依赖属性
开发语言·wpf
wangnaisheng16 小时前
【WPF】把一个Window放在左上角/右上角顶格显示
wpf
WineMonk16 小时前
.NET WPF CommunityToolkit.Mvvm框架
.net·wpf·mvvm
月落.16 小时前
WPF中的INotifyPropertyChanged接口
wpf
界面开发小八哥17 小时前
界面控件DevExpress WPF中文教程:Data Grid——卡片视图设置
.net·wpf·界面控件·devexpress·ui开发
平凡シンプル17 小时前
WPF 打包
wpf
VickyJames17 小时前
基于XAML框架和跨平台项目架构设计的深入技术分析
wpf·开源分享·unoplatform·winui3·项目架构
冷眼Σ(-᷅_-᷄๑)20 小时前
WPF缩放动画和平移动画叠加后会发生什么?
wpf·动画
△曉風殘月〆1 天前
WPF MVVM入门系列教程(二、依赖属性)
c#·wpf·mvvm