{
  "schemaVersion": "0.11.0",
  "canonical": "https://www.pystone.net/notes/dotnet-obfuscation-smartassembly/",
  "atlas": "https://www.pystone.net/?node=dotnet-obfuscation-smartassembly#knowledge-atlas",
  "markdown": "https://www.pystone.net/notes/dotnet-obfuscation-smartassembly.md",
  "context": "https://www.pystone.net/notes/dotnet-obfuscation-smartassembly.context.json",
  "knowledgeVersion": "224c990773de.5fa8af6e39fa",
  "build": {
    "siteCommit": "224c990773de166d23a886306577dd90379529ce",
    "notesCommit": "5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a",
    "builtAt": "1970-01-01T00:00:00.000Z",
    "version": "224c990773de.5fa8af6e39fa"
  },
  "id": "note:dotnet-obfuscation-smartassembly",
  "slug": "dotnet-obfuscation-smartassembly",
  "title": "混淆与加密——SmartAssembly的使用",
  "type": "note",
  "visibility": "public",
  "idStability": "rename-stable",
  "author": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "publisher": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "aliases": [],
  "summary": "混淆与加密——SmartAssembly的使用",
  "contentRole": "unspecified",
  "isMoc": false,
  "mocRecognition": "none",
  "generated": false,
  "attribution": "unspecified",
  "domain": "10-计算机、信息技术与工程",
  "tags": [],
  "mocs": [],
  "contentHash": "e502f81cb77d78a27b2f435838ec9d698318258f6666f67c9026800f8003d75c",
  "assets": [],
  "headings": [
    {
      "depth": 1,
      "text": "混淆与加密——SmartAssembly的使用",
      "anchor": "混淆与加密smartassembly的使用",
      "citation": "https://www.pystone.net/notes/dotnet-obfuscation-smartassembly/#%E6%B7%B7%E6%B7%86%E4%B8%8E%E5%8A%A0%E5%AF%86smartassembly%E7%9A%84%E4%BD%BF%E7%94%A8"
    },
    {
      "depth": 2,
      "text": "概念与功能",
      "anchor": "概念与功能",
      "citation": "https://www.pystone.net/notes/dotnet-obfuscation-smartassembly/#%E6%A6%82%E5%BF%B5%E4%B8%8E%E5%8A%9F%E8%83%BD"
    },
    {
      "depth": 3,
      "text": "混淆功能",
      "anchor": "混淆功能",
      "citation": "https://www.pystone.net/notes/dotnet-obfuscation-smartassembly/#%E6%B7%B7%E6%B7%86%E5%8A%9F%E8%83%BD"
    },
    {
      "depth": 3,
      "text": "辅助功能",
      "anchor": "辅助功能",
      "citation": "https://www.pystone.net/notes/dotnet-obfuscation-smartassembly/#%E8%BE%85%E5%8A%A9%E5%8A%9F%E8%83%BD"
    },
    {
      "depth": 2,
      "text": "操作流程",
      "anchor": "操作流程",
      "citation": "https://www.pystone.net/notes/dotnet-obfuscation-smartassembly/#%E6%93%8D%E4%BD%9C%E6%B5%81%E7%A8%8B"
    },
    {
      "depth": 2,
      "text": "1\\. 名称混淆 Obfuscation",
      "anchor": "1-名称混淆-obfuscation",
      "citation": "https://www.pystone.net/notes/dotnet-obfuscation-smartassembly/#1-%E5%90%8D%E7%A7%B0%E6%B7%B7%E6%B7%86-obfuscation"
    },
    {
      "depth": 3,
      "text": "类/方法名与字段名的混淆",
      "anchor": "类方法名与字段名的混淆",
      "citation": "https://www.pystone.net/notes/dotnet-obfuscation-smartassembly/#%E7%B1%BB%E6%96%B9%E6%B3%95%E5%90%8D%E4%B8%8E%E5%AD%97%E6%AE%B5%E5%90%8D%E7%9A%84%E6%B7%B7%E6%B7%86"
    },
    {
      "depth": 4,
      "text": "转移方法 ChangeMethodParent",
      "anchor": "转移方法-changemethodparent",
      "citation": "https://www.pystone.net/notes/dotnet-obfuscation-smartassembly/#%E8%BD%AC%E7%A7%BB%E6%96%B9%E6%B3%95-changemethodparent"
    },
    {
      "depth": 4,
      "text": "排除特定的命名空间",
      "anchor": "排除特定的命名空间",
      "citation": "https://www.pystone.net/notes/dotnet-obfuscation-smartassembly/#%E6%8E%92%E9%99%A4%E7%89%B9%E5%AE%9A%E7%9A%84%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4"
    },
    {
      "depth": 2,
      "text": "2\\. 流程混淆 Control Flow Obfuscation",
      "anchor": "2-流程混淆-control-flow-obfuscation",
      "citation": "https://www.pystone.net/notes/dotnet-obfuscation-smartassembly/#2-%E6%B5%81%E7%A8%8B%E6%B7%B7%E6%B7%86-control-flow-obfuscation"
    },
    {
      "depth": 2,
      "text": "3\\. 动态代理 References Dynamic Proxy",
      "anchor": "3-动态代理-references-dynamic-proxy",
      "citation": "https://www.pystone.net/notes/dotnet-obfuscation-smartassembly/#3-%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86-references-dynamic-proxy"
    },
    {
      "depth": 2,
      "text": "4\\. 字符串编码与加密 Strings Encoding",
      "anchor": "4-字符串编码与加密-strings-encoding",
      "citation": "https://www.pystone.net/notes/dotnet-obfuscation-smartassembly/#4-%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%BC%96%E7%A0%81%E4%B8%8E%E5%8A%A0%E5%AF%86-strings-encoding"
    },
    {
      "depth": 3,
      "text": "字符串统一收集编码 Encode",
      "anchor": "字符串统一收集编码-encode",
      "citation": "https://www.pystone.net/notes/dotnet-obfuscation-smartassembly/#%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%BB%9F%E4%B8%80%E6%94%B6%E9%9B%86%E7%BC%96%E7%A0%81-encode"
    },
    {
      "depth": 3,
      "text": "字符串压缩加密 Compress",
      "anchor": "字符串压缩加密-compress",
      "citation": "https://www.pystone.net/notes/dotnet-obfuscation-smartassembly/#%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%8E%8B%E7%BC%A9%E5%8A%A0%E5%AF%86-compress"
    },
    {
      "depth": 3,
      "text": "字符串缓存 UseCache",
      "anchor": "字符串缓存-usecache",
      "citation": "https://www.pystone.net/notes/dotnet-obfuscation-smartassembly/#%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%BC%93%E5%AD%98-usecache"
    },
    {
      "depth": 3,
      "text": "使用类的内部委托获取字符串 UseImprovedEncoding",
      "anchor": "使用类的内部委托获取字符串-useimprovedencoding",
      "citation": "https://www.pystone.net/notes/dotnet-obfuscation-smartassembly/#%E4%BD%BF%E7%94%A8%E7%B1%BB%E7%9A%84%E5%86%85%E9%83%A8%E5%A7%94%E6%89%98%E8%8E%B7%E5%8F%96%E5%AD%97%E7%AC%A6%E4%B8%B2-useimprovedencoding"
    },
    {
      "depth": 2,
      "text": "5\\. MSIL Disassembler Protection",
      "anchor": "5-msil-disassembler-protection",
      "citation": "https://www.pystone.net/notes/dotnet-obfuscation-smartassembly/#5-msil-disassembler-protection"
    },
    {
      "depth": 2,
      "text": "密封",
      "anchor": "密封",
      "citation": "https://www.pystone.net/notes/dotnet-obfuscation-smartassembly/#%E5%AF%86%E5%B0%81"
    },
    {
      "depth": 2,
      "text": "6\\. 实际应用建议",
      "anchor": "6-实际应用建议",
      "citation": "https://www.pystone.net/notes/dotnet-obfuscation-smartassembly/#6-%E5%AE%9E%E9%99%85%E5%BA%94%E7%94%A8%E5%BB%BA%E8%AE%AE"
    },
    {
      "depth": 2,
      "text": "Ref",
      "anchor": "ref",
      "citation": "https://www.pystone.net/notes/dotnet-obfuscation-smartassembly/#ref"
    }
  ],
  "claims": [],
  "outgoing": [],
  "incoming": [
    {
      "id": "note:programming-languages-and-runtimes",
      "title": "编程语言与运行时",
      "url": "https://www.pystone.net/notes/programming-languages-and-runtimes/",
      "atlas": "https://www.pystone.net/?node=programming-languages-and-runtimes#knowledge-atlas",
      "label": "编程语言与运行时",
      "origin": "explicit",
      "humanReviewed": true,
      "context": ".NET与CSharp中的“混淆与加密——SmartAssembly的使用”导航项",
      "citation": "https://www.pystone.net/notes/programming-languages-and-runtimes/#net%E4%B8%8Ecsharp"
    }
  ],
  "contentMarkdown": "# 混淆与加密——SmartAssembly的使用\n\n> 创建时间：2020/9/1 16:52\n\n  * 混淆与加密——SmartAssembly的使用\n    * 概念与功能\n      * 混淆功能\n      * 辅助功能\n    * 操作流程\n    * 1\\. 名称混淆 Obfuscation\n      * 类/方法名与字段名的混淆\n        * 转移方法 ChangeMethodParent\n        * 排除特定的命名空间\n    * 2\\. 流程混淆 Control Flow Obfuscation\n    * 3\\. 动态代理 References Dynamic Proxy\n    * 4\\. 字符串编码与加密 Strings Encoding\n      * 字符串统一收集编码 Encode\n      * 字符串压缩加密 Compress\n      * 字符串缓存 UseCache\n      * 使用类的内部委托获取字符串 UseImprovedEncoding\n    * 5\\. MSIL Disassembler Protection\n    * 密封\n    * 6\\. 实际应用建议\n    * Ref\n\n## 概念与功能\n\n### 混淆功能\n\n名称混淆 Obfuscation\n修改类型、字段、属性、方法等的名称。\n\n流程混淆 Control Flow Obfuscation\n修改方法内的执行逻辑，使其执行错综复杂。\n\n动态代理 References Dynamic Proxy\nSmartAssembly 会将方法的调用转到动态代理上。\n\n资源压缩加密 Resources Compression and Encryption\nSmartAssembly 会将资源以加密并压缩的方式嵌入到程序集中，运行时进行解压缩与解密。\n\n字符串压缩加密 Strings Encoding\nSmartAssembly 会将字符串都进行加密，运行时自动对其进行解密。\n\n防止 MSIL Disassembler 对其进行反编译 MSIL Disassembler Protection\n在程序集中加一个 Attribute，这样 MSIL Disassembler 就不会反编译这个程序集。\n\n### 辅助功能\n\n强签名 Strong Name Signing\n强签名可以确保程序之间的依赖关系是严格确定的，如果对其中的一个依赖进行篡改，将导致无法加载正确的程序集。\n微软提供了强签名工具Sn.exe ，所以可以无需使用 SmartAssembly 的。\n\n自动错误上报 Automated Error Reporting\nSmartAssembly 会自动向 exe 程序注入异常捕获与上报的逻辑。\n\n功能使用率上报 Feature Usage Reporting\nSmartAssembly 会修改每个方法，记录这些方法的调用次数并上报。\n\n依赖合并 Dependencies Merging\nSmartAssembly 会将程序集中你勾选的的依赖与此程序集合并成一个整的程序集。\n\n依赖嵌入 Dependencies Embedding\nSmartAssembly 会将依赖以加密并压缩的方式嵌入到程序集中，运行时进行解压缩与解密。\n\n裁剪 Pruning\nSmartAssembly 会将没有用到的字段、属性、方法、事件等删除。它声称删除了这些就能让程序逆向后代码更难读懂。\n\n密封类\n如果 SmartAssembly 发现一个类可以被密封，就会把它密封，这样能获得一点点性能提升。\n\n生成调试信息 Generate Debugging Information\n可以生成混淆后的 pdb 文件\n\n## 操作流程\n\n依赖SQL Server\n\n  1. new project\n\n  2. 选择需要改进和保护的主程序集，可以为windows forms 应用程序、wpf应用程序、console 控制台程序、dll程序集、asp.net web 应用程序等等。\n\n  3. set destination。置经过smartassembly处理之后的程序集存放的位置。\n\n  4. 设置smartassembly的程序参数。\n\n  5. dependencies merging，设置主程序集依靠的其他相关程序集。这些依靠的程序集会合并到主程序集中。建议不要选择第三方的程序集。\n\n  6. pruning 精简代码，这一步将从程序集中删除一些没有用的代码和元数据。smartassembly将检查程序集中的代码，自动判定哪些代码是有用的，哪些代码是从不会执行到的。同时，也将移除没有用的元数据。并可以分别选择对主程序集和依靠的程序集进行精简代码操作。\n\n  7. obfuscation 混淆代码。它将类和方法的名称更改为不可读的字符，但不会改变代码的功能，达到保护代码的目的。同时，也可以减少元数据，减小程序集的大小。\n\n  8. 点击build 按钮，就输出混淆后的程序集了，并且所有依靠的程序集都合并在一起了，这样在发布的时候，只需要发布合并后的一个程序集和第三方的程序集了。\n\n  9. 在smartassembly设置中，有个other protections 的选项，你可以选择在添加一些错误的metadata stream，如下图所示，这样在使用reflector 反编译工具根本就无法打开该程序集。\n\n## 1\\. 名称混淆 Obfuscation\n\n### 类/方法名与字段名的混淆\n\n类名和方法名的混淆有三个不同级别：\n\n  * 等级 1 是使用 ASCII 字符集\n\n  * 等级 2 是使用不可见的 Unicode 字符集\n\n  * 等级 3 是使用高级重命名算法的不可见的 Unicode 字符集\n\n需要注意：对于部分程序集，类与方法名（NameMangling）的等级只能选为 3，否则混淆程序会无法完成编译。\n\n字段名的混淆有三个不同级别：\n\n  * 等级 1 是源码中字段名称和混淆后字段名称一一对应\n\n  * 等级 2 是在一个类中的不同字段使用不同名称即可（这不废话吗，不过 SmartAssembly 应该是为了强调与等级 1 和等级 3 的不同，必须写一个描述）\n\n  * 等级 3 是允许不同类中的字段使用相同的名字（这样能够更加让人难以理解）\n\n需要注意：对于部分程序集，字段名（FieldsNameMangling）的等级只能选为 2 或 3，否则混淆程序会无法完成编译。\n（实际试验中，以上各种组合经常会出现无法编译的情况。1~3 的差异对逆向来说难度差异非常小的）\n该功能的源码：<https://walterlv.gitee.io/post/algorithm-of-generating-random-identifiers>\n\n> **特别小心如果有 InternalsVisibleTo 或者依据名称的反射调用，这种混淆下极有可能挂掉！！！请充分测试你的软件，切记！！！**\n\n#### 转移方法 ChangeMethodParent\n\n如果开启，可能会将一个类中的方法转移到另一个类中，这使得逆向时对类型含义的解读更加匪夷所思。\n\n#### 排除特定的命名空间\n\n如果你的程序集中确实存在需要被按照名称反射调用的类型，或者有 internal 的类/方法需要被友元程序集调用，请排除这些命名空间。\n\n## 2\\. 流程混淆 Control Flow Obfuscation\n\n0，1级差异不大\n2，3级可读性降低，差异不大\n4 级已经开始使用没有含义的指针来转换我们的内部实现了。这时除了外部调用以外，代码基本已无法解读其含义了。\n\n## 3\\. 动态代理 References Dynamic Proxy\n\n一些常规方法的调用被替换成了一个代理类的调用。生成的代理类都在根命名空间下。\n\n## 4\\. 字符串编码与加密 Strings Encoding\n\n### 字符串统一收集编码 Encode\n\n将程序集中的 **字符串** 都统一收集起来，存为一个 **资源** ；然后提供一个 **解密辅助类** 统一获取这些字符串。\n生成字符串获取辅助类后，原本写着字符串的地方就会被替换为 Strings.Get(int) 方法的调用。\n\n### 字符串压缩加密 Compress\n\n压缩加密后，Resources 中的那份字符串资源成为二进制文件。这份压缩的字符串在程序启动的时候会进行一次解压，随后就直接读取解压后的字符串了。会占用启动时间（虽然不长），但不会占用太多运行时时间。\n\n### 字符串缓存 UseCache\n\n无论是否开启了字符串缓存，实际 Strings.Get 方法都会缓存字符串。\n\n### 使用类的内部委托获取字符串 UseImprovedEncoding\n\n之前的混淆都会在原来有字符串地方使用 Strings.Get 来获取字符串。而如果开启了这一选项，那么 Strings.Get 就不是全局调用的了，而是在类的内部调用一个委托字段。\n\n## 5\\. MSIL Disassembler Protection\n\n防止 MSIL Disassembler 对其进行反编译\n这其实是个没啥用的选项，因为我们程序集只会多出一个全局的特性：[assembly: SuppressIldasm]\n只有 MSIL Disassembler 和基于 MSIL Disassembler 的工具认这个特性。真正想逆向程序集的，根本不会在乎 MSIL Disassembler 被禁掉。\ndnSpy 和 dotPeek 实际上都忽略了这个特性，依然能毫无障碍地反编译。\n\n## 密封\n\n在 OtherOptimizations 选项中，有一项 SealClasses 可以将所有可以密封的类进行密封（当然，此操作不会修改 API）。\n公有类，可能被继承，不会被密封\n\n## 6\\. 实际应用建议\n\n原则: 在保证你没有额外产生 Bug，性能没有明显损失的情况下，进行最大程度的保护，能混淆得多厉害就混淆得多厉害。\n\n  1. 流程混淆——建议必选\n直接选用 4 级流程（不安全代码）混淆，如果出问题才换为 3 级（goto）混淆，理论上不需要使用更低级别\n流程混淆对性能的影响是非常小的，因为多执行的代码都是有编译期级别优化的，没有太多性能开销的代码\n流程混淆仅影响实现，不修改 API，所以基本不会影响其他程序各种对此程序集的调用\n\n  2. 名称混淆——尽量选择\n任意选择类/方法名和字段名的级别，只要能编译通过就行（因为无论选哪个，对程序的影响都一样，逆向的难度差异也较小）\n名称混淆不影响程序执行性能，所以只要能打开，就尽量打开\n\n> 如果有 InternalsVisibleTo 或者可能被其他程序集按名称反射调用，请：\n>\n>     * 关闭此混淆\n>\n>     * 使用 Exclude 排除特定命名空间，使此命名空间下的类/方法名不进行名称混淆\n>\n>     * 如果你能接受用 Attribute 标记某些类不应该混淆类名，也可以使用这些标记（只是我不推荐这么做，这让混淆污染了自己的代码）\n\n  3. 动态代理——推荐选择\n动态代理仅影响实现，不修改 API，所以基本不会影响其他程序各种对此程序集的调用\n动态代理会生成新的类/委托来替换之前的方法调用，所以可能造成非常轻微的性能损失（一般可以忽略）\n\n  4. 字符串压缩加密——可以选择\n由于所有的字符串都被统一成一个资源，如果额外进行压缩加密，那么逆向时理解程序的含义将变得非常困难（没有可以参考的锚点）\n会对启动时间有轻微的性能影响，如果额外压缩加密，那么会有更多性能影响；如果你对启动性能要求较高，还是不要选了\n会轻微增加内存占用和读取字符串时的 CPU 占用，如果你对程序性能要求非常高，还是不要选了\n\n> 其他功能意义不大：\n>  裁剪 —— 一般也不会有多少开发者会故意往程序集中写一些不会用到的类吧！\n>  依赖合并/依赖嵌入 —— 并不会对逆向造成障碍，开不开启差别不大，反而降低了性能\n>  防止 MSIL Disassembler 反编译 —— 并不会对逆向造成障碍，防君子不防小人\n>  密封类 —— 声称可以提升性能，但这点性能提升微乎其微\n\n## Ref\n\n<https://walterlv.gitee.io/post/obfuscation-configurations-of-smart-assembly.html>\n<https://www.cnblogs.com/yt9999/articles/2145989.html>\n"
}
