当前位置: 首页 > news >正文

使用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文件中添加引用。

<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 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 renamedhttps://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文件

	<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流程麻烦、简单配置就行。但是通过发布形式,生成单体可执行文件踩了不少坑,不过都通过查阅资料解决。

相关文章:

使用Obfuscar 混淆WPF(Net6)程序

Obfuscar 是.Net 程序集的基本混淆器&#xff0c;它使用大量的重载将.Net程序集中的元数据&#xff08;方法&#xff0c;属性、事件、字段、类型和命名空间的名称&#xff09;重命名为最小集。详细使用方式参见&#xff1a;Obfuscar 在NetFramework框架进行的WPF程序的混淆比较…...

高中数学:数列-基础概念

一、什么是数列&#xff1f; 一般地&#xff0c;我们把按照确定的顺序排列的一列数称为数列&#xff0c;数列中的每一个数叫做这个数列的项&#xff0c;数列的第一项称为首项。 项数有限个的数列叫做有穷数列&#xff0c;项数无限个的数列叫做无穷数列。 二、一般形式 数列和…...

linux中dd命令以及如何测试读写速度

dd命令详解 dd命令是一个在Unix和类Unix系统中非常常用的命令行工具&#xff0c;它主要用于复制文件和转换文件数据。下面我会详细介绍一些dd命令的常见用法和功能&#xff1a; 基本语法 dd命令的基本语法如下&#xff1a; bash Copy Code dd [option]...主要选项和参数 if…...

centos官方yum源不可用 解决方案(随手记)

昨天用yum安装软件的时候&#xff0c;就报错了 [rootop01 ~]# yum install -y net-tools CentOS Stream 8 - AppStream 73 B/s | 38 B 00:00 Error: Failed to download metadata for repo appstream: Cannot prepare internal mirrorlis…...

langchian_aws模块学习

利用langchain_aws模块实现集成bedrock调用模型&#xff0c;测试源码 from langchain_aws.chat_models import ChatBedrock import jsondef invoke_with_text(model_id, message):llm ChatBedrock(model_idmodel_id, region_name"us-east-1")res llm.invoke(messa…...

归并排序-成绩输出-c++

注&#xff1a;摘自hetaobc-L13-4 【任务目标】 按学号从小到大依次输入n个人的成绩&#xff0c;按成绩从大到小输出每个人的学号&#xff0c;成绩相同时学号小的优先输出。 【输入】 输入第一行为一个整数&#xff0c;n&#xff0c;表示人数。&#xff08;1 ≤ n ≤ 100000…...

✔️Vue基础+

✔️Vue基础 文章目录 ✔️Vue基础computed methods watchcomputed计算属性methods计算属性computed计算属性 VS methods方法计算属性的完整写法 watch侦听器&#xff08;监视器&#xff09;watch侦听器 Vue生命周期Vue生命周期钩子 工程化开发和脚手架脚手架Vue CLI 项目目录介…...

基于VS2022编译GDAL

下载GDAL源码&#xff1b;下载GDAL编译需要依赖的必须代码&#xff0c;proj&#xff0c;tiff&#xff0c;geotiff三个源码&#xff0c;proj需要依赖sqlite&#xff1b;使用cmake编译proj&#xff0c;tiff&#xff0c;geotiff&#xff1b;proj有版本号要求&#xff1b;使用cmake…...

C语言之字符函数总结(全部!),一篇记住所有的字符函数

前言 还在担心关于字符的库函数记不住吗&#xff1f;不用担心&#xff0c;这篇文章将为你全面整理所有的字符函数的用法。不用记忆&#xff0c;一次看完&#xff0c;随查随用。用多了自然就记住了 字符分类函数和字符转换函数 C语言中有一系列的函数是专门做字符分类和字符转换…...

vite常识性报错解决方案

1.导入路径不能以“.ts”扩展名结束。考虑改为导入“xxx.js” 原因&#xff1a;当你尝试从一个以 .ts 结尾的路径导入文件时&#xff0c;ESLint 可能会报告这个错误&#xff0c;因为它期望导入的是 JavaScript 文件&#xff08;.js 或 .jsx&#xff09;而不是 TypeScript 文件&…...

2024.06.08【读书笔记】丨生物信息学与功能基因组学(第十二章 全基因组和系统发育树 第四部分)【AI测试版】

读书笔记&#xff1a;《生物信息学与功能基因组学》第十二章 - 第四部分 目录 基因组测序的生物信息学工具 1.1 常用生物信息学软件介绍1.2 基因组数据的管理和分析 基因组序列的比较分析 2.1 基因组之间的相似性与差异性2.2 比较基因组学的应用 基因组学在医学和健康科学中…...

IO进程线程(八)线程

文章目录 一、线程(LWP)概念二、线程相关函数&#xff08;一&#xff09;创建 pthread_create1. 定义2. 使用&#xff08;不传参&#xff09;3. 使用&#xff08;单个参数&#xff09;4. 使用&#xff08;多个参数&#xff09;5. 多线程执行的顺序6. 多线程内存空间 &#xff0…...

Linux基础指令网络管理003

本章主要讲述如何进行网络诊断。 操作系统&#xff1a; CentOS Stream 9 操作步骤&#xff1a; 操作指令 ping&#xff1a; 测试网络连接的连通性和延迟。 [rootlocalhost ~]# ping 192.168.80.111 PING 192.168.80.111 (192.168.80.111) 56(84) 比特的数据。 64 比特&a…...

在Android中使用 MQTT 服务实现消息通信

1.摘要 MQTT&#xff08;Message Queuing Telemetry Transport&#xff0c;消息队列遥测传输&#xff09;是一种轻量级的、基于发布/订阅&#xff08;Publish/Subscribe&#xff09;模式的通信协议&#xff0c;最初由 IBM 在1999年开发。它设计用于在低带宽、不稳定的网络环境下…...

qsort函数

学习c语言的过程中少不了的就是排序&#xff0c;例如冒泡排序&#xff08;不清楚的同学可以翻找一下之前的文章&#xff09;&#xff0c; 我们这里将冒泡排序作为一个自定义函数来呈现一下 #include<stdio.h>void bubble_sort(int arr[], int len) {for (int i 0; i &…...

你可以直接和数据库对话了!DB-GPT 用LLM定义数据库下一代交互方式,数据库领域的GPT、开启数据3.0 时代

✨点击这里✨&#xff1a;&#x1f680;原文链接&#xff1a;&#xff08;更好排版、视频播放、社群交流、最新AI开源项目、AI工具分享都在这个公众号&#xff01;&#xff09; 你可以直接和数据库对话了&#xff01;DB-GPT 用LLM定义数据库下一代交互方式&#xff0c;数据库领…...

数据结构笔记2 栈和队列

为什么在循环队列中&#xff0c;判断队满的条件是&#xff08;Q.rear1&#xff09;模maxqsize? 取模运算&#xff08;%&#xff09;在循环队列中起到关键作用&#xff0c;主要是因为它能确保索引值在数组的有效范围内循环。具体来说&#xff0c;取模运算有以下几个重要作用&am…...

Python | 刷题笔记

继承 class Father:__secret"you are your own kid"stroy"iam a handsome boy..."def tellstory(self):print("我的故事:",self.stroy)def __tellstory(self):print("我的秘密:",Father.__secret) class Son(Father):def tell(self…...

软件三班20240605

文章目录 1.创建工程和模块2.添加 web支持3.创建前端代码4.添加servlet 依赖5. 代码6.案例2 1.创建工程和模块 2.添加 web支持 方法1 方法2 3.创建前端代码 4.添加servlet 依赖 5. 代码 <!DOCTYPE html> <html lang"en"> <head><meta c…...

http和https数据传输与协议区分

目录 1. 数据传输安全性2. 端口号3. URL 前缀4. SSL/TLS 证书5. 性能6. SEO 和用户信任7. 应用场景总结 HTTP&#xff08;HyperText Transfer Protocol&#xff09;和 HTTPS&#xff08;HyperText Transfer Protocol Secure&#xff09;是用于在客户端&#xff08;如浏览器&…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

快刀集(1): 一刀斩断视频片头广告

一刀流&#xff1a;用一个简单脚本&#xff0c;秒杀视频片头广告&#xff0c;还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农&#xff0c;平时写代码之余看看电影、补补片&#xff0c;是再正常不过的事。 电影嘛&#xff0c;要沉浸&#xff0c;…...

深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向

在人工智能技术呈指数级发展的当下&#xff0c;大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性&#xff0c;吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型&#xff0c;成为释放其巨大潜力的关键所在&…...

如何配置一个sql server使得其它用户可以通过excel odbc获取数据

要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据&#xff0c;你需要完成以下配置步骤&#xff1a; ✅ 一、在 SQL Server 端配置&#xff08;服务器设置&#xff09; 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到&#xff1a;SQL Server 网络配…...