﻿# 介紹好用工具：使用 Obfuscar 混淆你的 .NET 組件

大家都知道，要反組譯一個 .NET 開發的 `*.dll` 檔案是非常容易的一件事，只要安裝 [ILSpy](https://github.com/icsharpcode/ILSpy) 工具，就可以很輕易的把當初撰寫的原始碼全部還原。話說回來，我們公司承接的專案，一向都提供完整的原始碼給客戶，所以我自己不太有「混淆器」的需求。但我記得多年前我們有個用 .NET 開發的產品，當時就有用到 .NET 混淆器，避免組件被客戶反組譯。今天這篇文章，我打算介紹一個名為 [Obfuscar](https://github.com/obfuscar/obfuscar) 的好用工具，教你怎樣把手邊編譯過的 .NET 組件混淆成誰也無法理解的版本。

### 準備一個要被混淆的 .NET 專案

1.  建立一個 `c1` 專案
    
    ```bash
    dotnet new console -n c1
    cd c1
    ```
    
2.  查看 `Program.cs` 原始碼
    
    ```bash
    type Program.cs
    ```
    
    我們的原始碼非常簡單，就一行 `Console.WriteLine` 而已，待會可以看看到底混淆的夠不夠徹底！
    
    ```csharp
    // See https://aka.ms/new-console-template for more information
    Console.WriteLine("Hello, World!");
    ```
    
3.  執行 dotnet publish 發行作業
    
    ```bash
    dotnet publish -c Release
    ```
    
    執行輸出如下：
    
    ```
    MSBuild version 17.7.1+971bf70db for .NET
      Determining projects to restore...
      All projects are up-to-date for restore.
      c1 -> G:\Projects\c1\bin\Release\net7.0\c1.dll
      c1 -> G:\Projects\c1\bin\Release\net7.0\publish\
    ```
    
    我們輸出的 `c1.dll` 組件就位於 `bin\Release\net7.0\publish\` 目錄下！
    

### 初次使用 Obfuscar 工具

1.  安裝 [Obfuscar.GlobalTool](https://www.nuget.org/packages/Obfuscar.GlobalTool/) 全域工具
    
    ```bash
    dotnet tool install --global Obfuscar.GlobalTool --version 2.2.*
    ```
    
    > 安裝好之後，其執行檔為 `obfuscar.console`。
    
2.  準備一個 Obfuscar 專用的 XML 設定檔，我將其命名為 `Obfuscar.xml`
    
    這裡我設定了兩個變數，一個 `InPath` 用來指定要混淆的檔案路徑，而 `OutPath` 則是用來指定要輸出混淆過的檔案的儲存路徑。最後的 `Module` 元素則是用來指定要混淆哪幾個檔案，這裡的 `Module` 可以設定多筆資料，一次混淆多個 DLL 或 EXE 檔案。
    
    ```xml
    <?xml version='1.0'?>
    <Obfuscator>
      <Var name="InPath" value=".\bin\Debug\net7.0\publish" />
      <Var name="OutPath" value=".\bin\Debug\net7.0\obfuscated" />
    
      <Module file="$(InPath)\c1.dll" />
    </Obfuscator>
    ```
    
    由於 Obfuscar 可以設定的地方還不少，詳細設定可參見 [Configuration](https://docs.obfuscar.com/getting-started/configuration) 說明。
    
3.  執行混淆工作
    
    ```bash
    obfuscar.console .\Obfuscar.xml
    ```
    
    輸出內容如下：
    
    ```
    Note that Rollbar API is enabled by default to collect crashes. If you want to opt out, please run with -s switch
    Loading project .\Obfuscar.xml...Processing assembly: c1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
    Loading assemblies...Extra framework folders: Done.
    Hiding strings...
    Renaming:  fields...Parameters...Properties...Events...Methods...Types...Done.
    Saving assemblies...Done.
    Writing log file...Done.
    Completed, 0.27 secs.
    ```
    

### 使用 [ILSpy](https://github.com/icsharpcode/ILSpy) 驗證效果

我用最新版 [ILSpy](https://github.com/icsharpcode/ILSpy) 開啟這個 `.\bin\Debug\net7.0\obfuscated\c1.dll` 檔案，發現所有**類別名稱**、**屬性名稱**與**方法名稱**都被混淆過，而且所有的「字串」都看不見了，即便你點進去看混淆過的方法內容，也看不出原始的字串為何，因此要理解原始碼的難度確實有大大的增加！👍

![image](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/421716e2cdaddbc9e216-6c21181e-bb75-41a7-89a5-2f651035f943.webp)

### 相關連結

-   [obfuscar/obfuscar: Open source obfuscation tool for .NET assemblies](https://github.com/obfuscar/obfuscar)
-   [Obfuscar Documentation — obfuscar 2.2 documentation](https://docs.obfuscar.com/)
-   [NuGet Gallery | Obfuscar.GlobalTool 2.2.38](https://www.nuget.org/packages/Obfuscar.GlobalTool/)
-   [ILSpy](https://github.com/icsharpcode/ILSpy)
