C# 混淆代码工具--ConfuserEx功能与使用指南

发布于:2025-04-14 ⋅ 阅读:(18) ⋅ 点赞:(0)

1 前言

代码混淆是一种通过故意模糊代码逻辑、隐藏其本意的技术,旨在提高逆向工程的难度,从而实现以下目标:

  1. 延缓破解与篡改速度:通过复杂化代码结构,增加攻击者分析和修改代码的时间成本。
  2. 保护知识产权:防止敏感算法或商业逻辑被轻易窃取或复制。

常见的混淆技术包括:

  • 名称混淆:缩短变量、函数名称,使其失去语义性。
  • 字符串加密:对字符串内容进行加密,避免明文暴露关键信息。
  • 控制流混淆:引入冗余逻辑或虚假分支,扰乱程序执行路径。
  • 控制流扁平化:将线性逻辑转化为复杂的状态机结构。
  • 不透明谓词:插入看似有意义但实际上不影响功能的条件判断。
  • 指令替换:用等价但更复杂的指令替代原有操作。

代码混淆不仅能有效保护程序逻辑,还能通过移除冗余信息、缩短标识符等方式减小编译后程序体积,提升分发效率。其核心价值在于平衡功能等价性与可读性之间的矛盾,为软件安全提供基础保障。

1.1 可能带来的问题

  1. 调试和维护困难:混淆后的代码难以理解,调试和修复问题时通常需要依赖未混淆的原始代码,否则可能难以定位问题。
  2. 反射冲突:代码混淆可能与反射机制产生冲突,尤其在未正确配置保留规则时,可能导致运行时错误。
  3. 安全性限制:代码混淆无法完全阻止反向工程,仅能提高其门槛。对于高安全性需求的场景,建议结合加密、完整性校验等多重保护措施。

2 ConfuserEx

2.1 简介

ConfuserEx 是一个开源的 .NET 应用程序保护工具,用于防止反编译和篡改。它支持多种混淆技术,包括控制流混淆、字符串加密、资源加密等。其灵活的配置选项可以根据不同的需求进行定制,为开发者提供了强大的保护机制。

官网:https://mkaring.github.io/ConfuserEx/

文档:git clone https://github.com/mkaring/ConfuserEx.wiki.git

2.2 功能特点

  • 代码混淆:通过重命名、控制流混淆等技术,使反编译后的代码难以理解。
  • 字符串加密:对字符串进行加密,防止攻击者轻易获取敏感信息。
  • 完整性校验:确保应用程序在运行过程中没有被篡改。
  • 反反编译:防止反编译工具对应用程序进行反编译。
  • 插件系统:允许开发者根据自己的需求编写自定义混淆规则,增强工具的灵活性和扩展性。

2.3 基本使用方法

  1. 下载安装 ConfuserExGUI

    https://github.com/mkaring/ConfuserEx/releases

  2. ConfuserExGUI界面
    在这里插入图片描述

  3. 将待混淆的 .dll 或 .exe 文件拖拽进中间方框区域。

    他会自动带出基本路径和输出路径
    在这里插入图片描述
    4. 设置 .NET 运行时

    .NET Core, .NET Standard, .NET 5 Support · Issue #302 · mkaring/ConfuserEx

    ConfuserExGUI默认支支持.NET FrameWork,如果需要使用.NET Core版本,需要手动设置运行时。

    1. 点击【⚙️】选择对应版本的运行时。
      在这里插入图片描述

    2. 点击【+】选择运行时文件夹
      在这里插入图片描述
      在这里插入图片描述

  4. 选择 Settings 项,添加混淆规则。

在这里插入图片描述

  1. 点击【Protect!】按钮开始混淆。

    在这里插入图片描述

  2. 点击【Save Project】保存混淆项目

    这将保存一个crproj文件。内容示例,可以看到其包含输出路径,基本路径,模块以及模块对应的规则。

    <project outputDir="E:\File\WorkFile\ConfuserExTest\ConfuserDemo\ConfuserDemo\bin\Debug\net5.0-windows\Confused" baseDir="E:\File\WorkFile\ConfuserExTest\ConfuserDemo\ConfuserDemo\bin\Debug\net5.0-windows" xmlns="http://confuser.codeplex.com">
      <module path="ConfuserDllDemo.dll">
        inherit="false">
          <protection id="rename">
            <argument name="mode" value="reversible" />
            <argument name="generatePassword" value="true" />
          protection>
        </rule>
      </module>
      <module path="ConfuserDemo.dll" />
      <module path="ConfuserDllDemo2.dll">
        inherit="false">
          <protection id="constants" />
          <protection id="ctrl flow" />
        <protection id="rename">
          <argument name="mode" value="reversible" />
          <argument name="generatePassword" value="true" />
          protection>
        </rule>
      </module>
      <probePath>C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\5.0.17</probePath>
      <probePath>C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.17</probePath>
      <probePath>C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\5.0.17</probePath>
    </project>
    

2.4 集成到MSBuild

ConfuserEx提供了ConfuserEx.CIL.exe工具,可以运行ConfuserEx.CIL.exe执行代码混淆。所以可以通过csproj配置MSBuild事件或者通过bat脚本执行ConfuserEx.CIL.exe工具等方法实现xxxxx执行混淆。

其基本命令为:

Confuser.CLI.exe <path to project file>

以下是两种方式的示例:

  • 方式一:通过bat脚本执行ConfuserEx.CIL.exe工具

    ..\release\tool\ConfuserEx.CIL.exe Your_ConfuderExProjectPath.crproj
    
  • 方式二:通过csproj配置MSBuild事件

    • csproj配置如下:

      <Project Sdk="Microsoft.NET.Sdk">
      
          <PropertyGroup>
              <OutputType>WinExe</OutputType>
              <TargetFramework>net5.0-windows</TargetFramework>
              <UseWPF>true</UseWPF>
              <ConfuserExPath>$(SolutionDir)tools\ConfuserEx\Confuser.CLI.exe</ConfuserExPath>
              <ConfuserConfig>$(SolutionDir)tools\ConfuserEx\ConfuserDemoConfuder.crproj</ConfuserConfig>
          </PropertyGroup>
      
          <ItemGroup>
            <ProjectReference Include="..\ConfuserDllDemo2\ConfuserDllDemo2.csproj" />
            <ProjectReference Include="..\ConfuserDllDemo\ConfuserDllDemo.csproj" />
          </ItemGroup>
      
          <Target Name="Obfuscate" AfterTargets="Build">
              <!-- 执行混淆命令 -->
              <Exec Command="&quot;$(ConfuserExPath)&quot; &quot;$(ConfuserConfig)&quot;" />
          </Target>
      
      </Project>
      
      
      
    • 配置解析

      • 定义 ConfuserEx 路径

        <PropertyGroup>
            <ConfuserExPath>$(SolutionDir)tools\ConfuserEx\Confuser.CLI.exe</ConfuserExPath>
            <ConfuserConfig>$(SolutionDir)tools\ConfuserEx\ConfuserDemoConfuder.crproj</ConfuserConfig>
        </PropertyGroup>
        
        • ConfuserExPath:指定 ConfuserEx 的可执行文件路径。
          • $(SolutionDir) 是 MSBuild 的内置变量,表示解决方案的根目录。但是注意只有通过解决f
          • 确保路径中使用的是反斜杠 \,而不是正斜杠 /
        • ConfuserConfig:指定 ConfuserEx 的配置文件路径。
          • 配置文件 .crproj 包含了混淆规则和保护选项。
      • 定义构建后目标

        <Target Name="Obfuscate" AfterTargets="Build">
            <!-- 执行混淆命令 -->
            <Exec Command="&quot;$(ConfuserExPath)&quot; &quot;$(ConfuserConfig)&quot;" />
        </Target>
        
        • Target:定义一个名为 Obfuscate 的目标。
          • AfterTargets="Build":表示该目标会在 Build 目标完成后执行。
        • Exec:执行命令行指令。
          • Command 属性中使用了 &quot; 来转义双引号,确保路径中包含空格时命令能正确执行。

2.5 深入设置

2.5.1 保护机制

ConfuserEx 提供了四种混淆预设:Minimum,Normal,Aggressive,Maximum,每种预设,设定了不同的混淆模式,也可以选择不设置预设,自行选择混淆模式。其对应关系如下:

**Protection保护项** / **preset**预设 Minimum Normal Aggressive Maximum
Name
Hardening
Anti Debug
Anti IL Dasm
Watermark
Constants
Reference Proxy
Resources
Anti Dump
Anti Tamper
Invalid Metadata
Type Scramble
2.5.1.1 ConfuserEx Protection
标题 简要说明 缺点 备注
Hardening 代码硬化保护 合并调用指令,隐藏敏感方法,对性能影响小 适用范围小,只针对全局静态构造函数 可能对方法有要求。实践没起效
Reference Proxy 中间代理保护 添加中间方法作为代理,隐藏对类型、方法和字段的引用 可能对方法有要求。实践没起效
Anti Debug 反调试保护 保护代码会维护一个专用线程来监控调试器。 只适用于应用程序的主程序集,对性能有影响,能够被dnspy移除
Watermark 增加一个被ConfuserEx 保护的特性,也没有实质性的保护,默认启用
Anti IL Dasm 给代码添加一个SuppressIldasmAttribute自定义属性 没有任何实质性的混淆保护,只是增加礼貌的提示。
Invalid Metadata 向模块中添加无效的元数据,阻止反汇编器或反编译器正常打开目标程序。 实践没起效,不明原因
Anti Dump防转储保护 不推荐,我们需要能够捕捉Dump以进行分析
Rename 重命名保护 高效,推荐,支持多种重命名方式 可能会影响反射 推荐
Anti Tamper反篡改保护 确保应用程序的完整性。
Type Scramble 类型混淆保护 不明副作用,不推荐使用。使用最好对特定类型启用
Constants 使用算法对程序中的常量进行压缩,推荐使用 推荐
Resources 资源保护 通过算法对资源进行编码和压缩

2.5.2 精细的代码保护

声明式混淆和表达式函数是ConfuserEx中非常重要的功能,它们共同为开发者提供了灵活、精确的代码保护机制。声明式混淆通过ObfuscationAttribute特性直接在代码中指定混淆规则,而表达式函数通过规则模式筛选代码元素,实现更精细的代码保护。

  • 声明式混淆

    使用System.Reflection.ObfuscationAttribute 特性指导ConcuserEx混淆。

    声明式混淆是通过.NET框架提供的System.Reflection.ObfuscationAttribute特性来指导混淆工具(如ConfuserEx)对代码进行混淆的一种方式。

主要特性
  1. Exclude:布尔值,表示是否将当前代码元素排除在混淆之外。
    • Exclude = true:当前代码元素不会被混淆。
    • Exclude = false:当前代码元素会被混淆。
  2. Feature:字符串值,用于指定混淆工具的特定功能。
    • 例如:Feature = "generate debug symbol: true"表示生成调试符号。
    • 也可以组合多个功能,如Feature = "preset(minimum);+ctrl flow;-anti debug;+rename(mode=letters,flatten=false)"
  3. ApplyToMembers:布尔值,表示是否将当前类型的混淆规则应用到其成员。
    • 默认值为true,表示混淆规则会应用到类型的所有成员。
[assembly: Obfuscation(Exclude = false, Feature = "generate debug symbol: true")]
[assembly: Obfuscation(Exclude = false, Feature = "random seed: Hello!")]
[assembly: Obfuscation(Exclude = false, Feature = "strong name key:C:\\key.pfx")]
[assembly: Obfuscation(Exclude = false, Feature = "strong name key password:hunter2")]

[assembly: Obfuscation(Exclude = false, Feature = "packer:compressor(key=dynamic)")]
[assembly: Obfuscation(Exclude = false, Feature = "preset(minimum);+ctrl flow;-anti debug;+rename(mode=letters,flatten=false);")]

[assembly: Obfuscation(Exclude = false, Feature = "namespace('Test'):-rename")]
[assembly: Obfuscation(Exclude = false, Feature = "namespace('LibraryA.Test'):+rename")]
[assembly: Obfuscation(Exclude = false, Feature = "external module:LibraryB.dll")]
namespace Test {

    [Obfuscation(Exclude = false, Feature = "constants")]
    class Program {
    
        public static void Main() {
            Console.WriteLine("Hi");
        }
    }
}
  • 表达式函数

    在设置规则时,可以看到一个Pattern,其默认值为true。这里支持设置表达式函数筛选模块中哪些成员进行混淆。通过组合这些函数和运算符,可以灵活地指定规则的适用范围,从而实现更精细的代码保护。
    在这里插入图片描述

    • 规则模式的构成

      规则模式由以下部分组成:

      1. 文字表达(Literal Expressions):
        • 布尔文字truefalse,用于表示逻辑值。
        • 字符串文字:用单引号(')或双引号(")括起来的字符串,支持用反斜杠(\)转义特殊字符。例如:'NS1.MyClass'
      2. 运算符:
        • and:逻辑与。
        • or:逻辑或。
        • not:逻辑非。
      3. 表达函数(Expression Functions):
        • 这些函数用于检查代码元素的属性,返回布尔值(truefalse)。
        • 如果返回 true,则表示该规则适用于当前评估的代码元素。
    • 支持的函数

      1. decl-type(string)
      • 功能:检查当前评估的类型(或类型成员的声明类型)是否具有指定的签名。
      • 示例decl-type("System.Object") 返回 true,如果当前类型是 System.Object
      2.full-name(string)
      • 功能:检查当前评估的项目是否具有指定的签名(全名)。
      • 示例full-name("MyNamespace.MyClass") 返回 true,如果当前项目的全名是 MyNamespace.MyClass
      3. is-public()
      • 功能:检查当前评估的项目是否在程序集外部可见(即是否为公共成员)。
      • 示例is-public() 返回 true,如果当前项目是公共的。
      4. match(string)
      • 功能:检查当前评估的项目的签名是否与指定的正则表达式匹配。
      • 示例match(".*MyClass.*") 返回 true,如果当前项目的签名包含 MyClass
      5. match-name(string)
      • 功能:检查当前评估的项目的名称是否与指定的正则表达式匹配。
      • 示例match-name("MyClass") 返回 true,如果当前项目的名称是 MyClass
      6.match-type-name(string)
      • 功能:检查当前评估的类型的名称(或类型成员的声明类型的名称)是否与指定的正则表达式匹配。
      • 示例match-type-name("MyClass") 返回 true,如果当前类型的名称是 MyClass
      7. member-type(string)
      • 功能:检查当前评估的项目是否具有指定的类型。
      • 支持的类型typemethodfieldpropertyeventmodule
      • 示例member-type("method") 返回 true,如果当前项目是一个方法。
      8. module(string)
      • 功能:检查当前评估的项目的模块是否具有指定的名称。
      • 示例module("MyModule.dll") 返回 true,如果当前项目的模块名称是 MyModule.dll
      9. name(string)
      • 功能:检查当前评估的项目的名称是否与指定的名称匹配。
      • 示例name("MyMethod") 返回 true,如果当前项目的名称是 MyMethod
      10. namespace(string)
      • 功能:检查当前评估的类型(或类型成员的声明类型)是否具有指定的命名空间。
      • 示例namespace("MyNamespace") 返回 true,如果当前类型的命名空间是 MyNamespace
      11. inherits(string)
      • 功能:检查当前评估的类型是否继承自指定的类型。
      • 示例inherits("System.Exception") 返回 true,如果当前类型继承自 System.Exception
      12. is-type(string)
      • 功能:检查当前评估的类型是否属于指定的特殊类型。
      • 示例is-type("delegate") 返回 true,如果当前类型是一个委托。
    • 实践

      例如:要匹配程序集ConfuserDllDemo2CalculateExpressionFunctions类的Calculate方法,可以使用 ConfuserEx 的规则模式。

      member-type('method') and name('Calculate') and decl-type('ConfuserDllDemo2.CalculateExpressionFunctions')
      

在这里插入图片描述

  • 配置示例
    <project outputDir="E:\File\WorkFile\ConfuserExTest\ConfuserDemo\ConfuserDemo\bin\Debug\net5.0-windows\Confused" baseDir="E:\File\WorkFile\ConfuserExTest\ConfuserDemo\ConfuserDemo\bin\Debug\net5.0-windows" xmlns="http://confuser.codeplex.com">
      <module path="ConfuserDemo.dll">
        inherit="false">
          <protection id="constants" />
        </rule>
      </module>
      <module path="ConfuserDllDemo.dll">
        inherit="false">
          <protection id="rename">
            <argument name="mode" value="reversible" />
            <argument name="generatePassword" value="true" />
          protection>
          <protection id="harden" />
          <protection id="constants" />
          <protection id="ref proxy" />
          <protection id="invalid metadata" />
        </rule>
      </module>
      <module path="ConfuserDllDemo2.dll">
        inherit="false">
          <protection id="ctrl flow" />
          <protection id="constants" />
          <protection id="rename">
            <argument name="mode" value="reversible" />
            <argument name="generatePassword" value="true" />
          protection>
        </rule>
      </module>
      <probePath>C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\5.0.17</probePath>
      <probePath>C:\Program Files\dotnet\shared\Microsoft.NETCore.App\5.0.17</probePath>
      <probePath>C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\5.0.17</probePath>
    </project>
    

2.6 使用建议

  1. 建议启用重命名保护、常量保护

    高效,对性能影响小

    <protection id="constants" />
    <protection id="rename">
      <argument name="mode" value="reversible" />
      <argument name="generatePassword" value="true" />
    protection>
    
  2. 结合使用声明式混淆和表达式函数和对核心或敏感代码进行混淆

  3. 注意避免重命名可能会进行反射的方法


网站公告

今日签到

点亮在社区的每一天
去签到