惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 叶小钗
O
OpenAI News
V
V2EX
大猫的无限游戏
大猫的无限游戏
博客园 - 聂微东
S
Schneier on Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
小众软件
小众软件
L
LINUX DO - 热门话题
C
Cybersecurity and Infrastructure Security Agency CISA
博客园 - Franky
Security Latest
Security Latest
S
SegmentFault 最新的问题
Project Zero
Project Zero
Spread Privacy
Spread Privacy
K
Kaspersky official blog
J
Java Code Geeks
V
Vulnerabilities – Threatpost
C
Cisco Blogs
C
CERT Recently Published Vulnerability Notes
月光博客
月光博客
T
The Exploit Database - CXSecurity.com
L
Lohrmann on Cybersecurity
人人都是产品经理
人人都是产品经理
博客园 - 三生石上(FineUI控件)
Scott Helme
Scott Helme
WordPress大学
WordPress大学
量子位
T
Threat Research - Cisco Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
宝玉的分享
宝玉的分享
Hugging Face - Blog
Hugging Face - Blog
AWS News Blog
AWS News Blog
Help Net Security
Help Net Security
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Simon Willison's Weblog
Simon Willison's Weblog
S
Secure Thoughts
博客园 - 【当耐特】
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
V
Visual Studio Blog
Last Week in AI
Last Week in AI
T
Tailwind CSS Blog
腾讯CDC
Cyberwarzone
Cyberwarzone
IT之家
IT之家
GbyAI
GbyAI
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
云风的 BLOG
云风的 BLOG
T
Troy Hunt's Blog
D
Docker

博客园 - H5开发技术

恒盾C#混淆加密大师1.5.0:EXE保护增强与.NET 10适配 EXE加密原生内核使用:解决系统环境兼容问题 EXE一机一码加密后无法运行?兼容模式使用指南 HTML打包EXE多实例共享进程:多开加速与状态共享 免费绿色JS混淆加密工具 - 离线版本分享 5分钟学会HTML打包AP本地文件加密 HTML打包EXE后桌面图标不更新?刷新缓存方法 HTML打包EXE 2.3.0更新详解(附最新版本下载地址-含免费内核) HTML打包EXE离线一机一码新增试用功能(附2026最新版下载地址) PDF加密转APK大师最新版本1.1.0更新, 附快速上手教程 极速图标设计大师 — 不会 PS 也能 3 秒做出专业 App 图标(附免费下载) HTML打包EXE导出配置文件教程:使用 .html2exe 文件备份、迁移和复用打包设置 BZ全景漫游可视化编辑器: 零代码制作360全景漫游H5作品 苹果手机快速开启开发者模式教程(iOS 16+) Windows平台生成苹果开发者测试证书教程 苹果签名安装助手 - 用 Apple ID 一键生成开发者测试证书教程 HTML打包EXE使用附件功能调用外部程序扩展你的EXE - 附实战演练实现录频功能 HTML打包EXE安装包配置教程 - 自定义安装目录和桌面快捷方式名 HTML打包/EXE加密的一机一码网络验证常见问题汇总 HTML打包EXE透明窗口教程 - 打造炫酷无边框透明桌面应用 HTML打包EXE工具启动图设置 - 为打包程序添加启动画面 HTML打包EXE网络验证管理后台使用指南 - 激活码生成、管理与日志查看 HTML打包快速配置使用网络验证后台 HTML打包EXE工具自定义菜单功能详解 - 为打包程序添加个性化菜单栏 HTML 一键打包 EXE 工具 API 完整参考与示例 HTML打包EXE工具数据加密功能详解 - 加密保护HTML/JS/CSS资源 HTML打包EXE工具四种弹窗方式图文详解 - 单窗口/新窗口/标签页/浏览器打开 HTML打包EXE工具标签页模式详解 - 像浏览器一样管理多个页面 HTML打包EXE三种加密方式对比:静态密码、离线一机一码、网络验证 HTML一键打包EXE工具 加密设置静态密码功能详解 Windows系统UTF-8编码设置教程:解决HTML打包EXE乱码/出错问题 HTML打包EXE配置管理教程:多项目打包设置一键保存、加载与切换 极速文字转语音大师 - 多语言高品质TTS配音工具免费下载 HTML一键打包EXE工具打包生成EXE完整快捷键一览 恒盾C#混淆加密大师1.4.5更新介绍(2026最新版本 - 附下载地址) HTML打包EXE工具内核详细介绍 - 各种内核的优缺点, 使用场景分析 KRPano的VR全景项目如何打包成Pico设备的APP并支持全屏分镜播放 HTML一键打包APK更新2.0.0 (附2026最新版下载地址) - 轻松把HTML, 网址转成安卓APP程序 KRPano解密大师1.5.0发布(2026最新版本) - 附5分钟学会KRPano全景解密 PDF一机一码加密大师1.1.0更新, 强力加密PDF, 附免费版下载地址 HTML打包EXE工具2.2.0版本重磅更新 - 2026年最新版本稳定性大幅提升 HTML打包APK中的文件下载功能详解 公众号推荐机制整理:科技号怎么把社交流量做起来 HTML一键打包APK工具使用指南 - 为什么APP安装时会覆盖 HTML一键打包APK工具免认证版本正式上线!轻松打包离线应用 - 支持全景VR, RPG Maker游戏 极速AI助手快速接入免费腾讯混元大模型教程
在.NET项目集成混淆加密:自动化保护DLL和EXE
H5开发技术 · 2026-07-26 · via 博客园 - H5开发技术

为了保护C#程序, 在.NET项目交付DLL或EXE之前,通常需要先编译,再手动打开混淆工具、选择程序集、加载配置并导出结果。对于经常发布的项目,这套操作不仅重复,还容易漏选文件或使用错误配置。

更稳定的方式是把恒盾C#混淆加密大师的CLI接入MSBuild:Release构建完成后自动获取当前项目的真实输出路径,调用CLI生成保护版本。由于Visual Studio、Rider、dotnet build和多数CI平台最终都会调用MSBuild,因此只需在项目文件中维护一套规则。

C#混淆加密大师1.5.0截图

集成后的构建流程

本文实现的流程如下:

  1. 正常编译.NET项目,不修改原始构建产物。
  2. 仅在Release配置且已经配置CLI路径时执行混淆。
  3. .deps.json.runtimeconfig.json和依赖DLL复制到protected目录。
  4. 使用--input--output覆盖配置文件中的路径,由CLI生成受保护的主程序集。
  5. CLI返回非零退出码或未生成目标文件时让构建失败,避免误发布未保护的程序。

最终目录类似下面这样:

bin/Release/net8.0/
├─ DotNetObfuscationSample.dll          # 原始构建产物
├─ DotNetObfuscationSample.deps.json
├─ DotNetObfuscationSample.runtimeconfig.json
└─ protected/
   ├─ DotNetObfuscationSample.dll       # 已混淆的主程序集
   ├─ DotNetObfuscationSample.deps.json
   └─ DotNetObfuscationSample.runtimeconfig.json

原始目录可继续用于调试和问题定位,发布时只取protected目录即可。

第一步:准备CLI和混淆配置

安装恒盾C#混淆加密大师后,在安装目录中找到CLI.exe。然后在图形界面中配置需要启用的保护功能,通过“文件 > 导出配置”得到obfuscation.csop,并把它放在.csproj同一目录。配置文件中的ModulePathOutputPath可以保留示例值,因为构建时会通过CLI参数覆盖:

{
    "ModulePath": "bin/Release/net8.0/MyApp.dll",
    "OutputPath": "bin/Release/net8.0/protected/MyApp.dll",
    "AntiILDasm": true,
    "StringConfusor": true,
    "IntConfusor": true,
    "FieldRename": true,
    "MethodRename": true,
    "ParamRename": true,
    "TypeRename": true,
    "RenameMode": 1,
    "Seed": "my-project-release",
}

实际使用时建议保留软件导出的完整配置,不要只复制上面的精简片段。可先启用少量保护选项,验证程序正常启动和主要功能后,再逐步增加保护强度。

第二步:在项目文件中加入MSBuild目标

打开需要保护的.csproj,在</Project>之前加入下面的内容:

<PropertyGroup>
  <ObfuscatorCliPath Condition="'$(ObfuscatorCliPath)' == ''">$(OBFUSCATOR_CLI_PATH)</ObfuscatorCliPath>
  <RunObfuscator Condition="'$(RunObfuscator)' == '' and '$(Configuration)' == 'Release' and '$(ObfuscatorCliPath)' != ''">true</RunObfuscator>
  <RunObfuscator Condition="'$(RunObfuscator)' == ''">false</RunObfuscator>
  <ObfuscatorConfigPath>$(MSBuildProjectDirectory)\obfuscation.csop</ObfuscatorConfigPath>
</PropertyGroup>

<Target Name="ObfuscateReleaseOutput"
        AfterTargets="Build"
        Condition="'$(Configuration)' == 'Release' and '$(RunObfuscator)' == 'true'">
  <PropertyGroup>
    <ObfuscatedOutputDir Condition="'$(ObfuscatedOutputDir)' == ''">$(TargetDir)protected\</ObfuscatedOutputDir>
    <ObfuscatedOutputPath Condition="'$(ObfuscatedOutputPath)' == ''">$(ObfuscatedOutputDir)$(TargetFileName)</ObfuscatedOutputPath>
  </PropertyGroup>

  <Error Condition="'$(ObfuscatorCliPath)' == ''"
         Text="RunObfuscator=true, but ObfuscatorCliPath or OBFUSCATOR_CLI_PATH is not configured." />
  <Error Condition="!Exists('$(ObfuscatorCliPath)')"
         Text="Obfuscator CLI was not found: $(ObfuscatorCliPath)" />
  <Error Condition="!Exists('$(ObfuscatorConfigPath)')"
         Text="Obfuscator config was not found: $(ObfuscatorConfigPath)" />

  <RemoveDir Directories="$(ObfuscatedOutputDir)" />
  <MakeDir Directories="$(ObfuscatedOutputDir)" />
  <ItemGroup>
    <ObfuscatorCompanionFile Include="$(TargetDir)**\*"
                                                                                                   Exclude="$(ObfuscatedOutputDir)**\*;$(TargetPath)" />
  </ItemGroup>
  <Copy SourceFiles="@(ObfuscatorCompanionFile)"
        DestinationFiles="@(ObfuscatorCompanionFile->'$(ObfuscatedOutputDir)%(RecursiveDir)%(Filename)%(Extension)')"
        SkipUnchangedFiles="true" />

  <Message Importance="high" Text="Obfuscating $(TargetPath)" />
  <Exec Command="&quot;$(ObfuscatorCliPath)&quot; obf --config &quot;$(ObfuscatorConfigPath)&quot; --input &quot;$(TargetPath)&quot; --output &quot;$(ObfuscatedOutputPath)&quot;" />
  <Error Condition="!Exists('$(ObfuscatedOutputPath)')"
         Text="Obfuscator did not create the expected output: $(ObfuscatedOutputPath)" />
  <Message Importance="high" Text="Protected output: $(ObfuscatedOutputDir)" />
</Target>

这里使用的都是MSBuild内置属性,因此不需要硬编码项目名称或目标框架:

  • $(MSBuildProjectDirectory)是当前项目目录。
  • $(TargetPath)是本次构建产生的主程序集完整路径。
  • $(TargetFileName)会自动适配不同项目名称。
  • AfterTargets="Build"确保只有编译成功后才执行CLI。
  • Exec检查CLI退出码,随后的Error还会确认目标文件确实已经生成。

复制主程序集以外的完整输出内容,再由CLI生成受保护的主程序集,是为了保留程序运行需要的配置和依赖文件。不要只把混淆后的DLL单独交付。排除原始主程序集也能确保后续文件检查不会把未经保护的副本误判为成功结果。

第三步:配置CLI路径

不建议把个人电脑上的绝对安装路径写入.csproj。可以使用环境变量,让不同开发机和CI环境使用各自的CLI位置。

在PowerShell中为当前终端设置:

$env:OBFUSCATOR_CLI_PATH = 'C:\Tools\CSharpObfuscator\CLI.exe'

如需永久写入当前Windows用户的环境变量:

[Environment]::SetEnvironmentVariable(
    'OBFUSCATOR_CLI_PATH',
    'C:\Tools\CSharpObfuscator\CLI.exe',
    'User'
)

永久设置后需要重新打开Visual Studio、Rider或终端。也可以在单次构建中直接传入路径:

dotnet build -c Release -p:ObfuscatorCliPath='C:\Tools\CSharpObfuscator\CLI.exe'

第四步:执行Release构建

在命令行中执行:

dotnet build -c Release

在Visual Studio中将解决方案配置切换为Release后执行“生成解决方案”,或者在Rider中构建Release配置,都会触发同一个MSBuild目标。Debug构建默认不会执行混淆。

如需临时跳过混淆,可以显式关闭开关:

dotnet build -c Release -p:RunObfuscator=false

构建日志中出现下面两行,表示集成目标已执行:

Obfuscating ...\bin\Release\net8.0\MyApp.dll
Protected output: ...\bin\Release\net8.0\protected\

在CI中使用

CI使用的仍然是相同命令,只需提前安装并注册CLI,再通过环境变量或MSBuild属性传入路径:

$env:OBFUSCATOR_CLI_PATH = "$env:OBFUSCATOR_HOME\CLI.exe"
dotnet restore
dotnet build -c Release --no-restore

建议把protected目录作为发布制品,并在上传前增加一个文件存在性检查:

$protectedFile = '.\bin\Release\net8.0\protected\MyApp.dll'
if (-not (Test-Path $protectedFile)) {
    throw "未生成混淆后的程序集: $protectedFile"
}

WPF、WinForms、类库和ASP.NET Core项目

这套写法不依赖控制台项目:

  • WPF和WinForms项目的$(TargetPath)会指向其主程序集。
  • 类库项目可以直接保护生成的DLL。
  • ASP.NET Core项目应在完整发布目录中保留依赖、配置文件和静态资源,仅替换需要保护的业务程序集。
  • 一个解决方案包含多个项目时,只在真正需要保护的项目中加入目标,或者把公共目标提取到单独的.targets文件后按条件导入。

使用反射、依赖注入扫描、JSON序列化、XAML绑定、插件加载或P/Invoke时,重命名可能影响运行。应通过忽略列表保留外部依赖的名称,并对启动、登录、核心业务、配置加载和自动更新等流程进行回归测试。

dotnet publish和单文件发布注意事项

本文示例挂接在Build目标之后,适合普通DLL、EXE构建。执行dotnet publish时,发布过程还会在publish目录重新整理文件,因此不要直接把未经检查的publish目录当成混淆结果。

常规发布可先执行dotnet publish -c Release,再用CLI的--input--output处理发布目录中的主程序集。启用PublishSingleFile时,应将发布得到的单文件EXE作为CLI输入,而不是构建阶段的DLL。建议为单文件项目单独建立发布后目标,并验证解包、混淆、重构后的程序能够在干净环境启动。

完整示例代码

可以访问GitHub获取完整项目代码: https://github.com/leapever/csharp-obfuscator-cli-integration