HOWTO · Csharp

如何在 C# 中混淆程式碼

了解 C# 混淆如何轉換受控組件、常用技術的作用,以及如何評估其局限性。

本頁內容

C# 混淆會轉換 .NET 組件,使其程式碼和中繼資料更難檢查,同時力求保留應用程式的預期行為。它可以提高粗略分析所需的成本,但不能保證軟體能抵禦逆向工程,也不能保護嵌入用戶端應用程式中的秘密。

受控 .NET 組件通常包含中間語言(IL)以及類型、方法和屬性名稱等中繼資料。反編譯器可以利用這些資訊呈現原始碼的可讀近似形式。具體細節因編譯器、建置設定和應用程式而異,因此混淆是防禦的一層,而不是安全邊界。

C# 中程式碼混淆的含義

混淆會套用旨在使程式更難被人或工具理解的轉換。重新命名識別碼、轉換字串和更改程式碼結構都是常見例子。有用的混淆過程力求保留程式的預期行為,但轉換可能引入相容性問題或錯誤。請使用與未混淆應用程式相同的情節和部署條件測試發行組建。

C# 程式碼混淆的工作原理

混淆器會分析組件,並在產生用於散發的組建之前套用所選的轉換。一些轉換會更改名稱或表示形式;另一些則會改變控制流程或加入檢查。其結果仍需在目標 .NET 執行階段上執行,並與反射、序列化、外掛程式以及其他依賴名稱或中繼資料的程式碼協同運作。請保留未修改的組建以及符號或工具產生的對應檔案(如受支援),以便診斷生產問題。

為 C# 選擇混淆工具

.NET Reactor、Eazfuscator.NET、Babel 和 ConfuserEx 等名稱曾與 C# 混淆相關聯。此列表僅為範例,並非排名或推薦;本文不確立它們目前的可用性、維護情況、功能或相容性。請查看每個產品的目前文件,並針對你的目標框架和應用程式進行測試。

比較工具時,應依據它們實際支援的轉換、與你的建置和部署管線的相容性、對偵錯和支援的影響,以及它們處理反射或第三方程式庫的方式。審查產生的成品並測試封裝後的應用程式。不要僅憑某個工具承諾能使逆向工程變得不可能就選擇它。

重新命名混淆

重新命名混淆會將選定的類別、方法、欄位或屬性名稱替換為描述性較弱的識別碼。例如,範例性宣告 class Data { public int age; } 在識別碼重新命名後可能變為 class a { public int b; }。這兩個宣告以描述性較弱的名稱展示了相同的欄位形態;它們是一次轉換的草圖,而不是完整的混淆器工作流程,也不是轉換後的應用程式保留其行為的證據。下面的可執行範例展示了在此類轉換之前的可讀類型和屬性。

名稱也可以是應用程式介面的一部分。反射、序列化器、相依性注入、外掛程式和外部呼叫方可能依賴這些名稱。在需要的地方設定排除項目,並在轉換後測試這些路徑。如果工具提供重新命名對應,請保留符號或該對應,因為它可以幫助將生產堆疊追蹤與原始原始碼聯繫起來。

執行此範例:

using System;

public sealed class CustomerRecord
{
    public int Age { get; }

    public CustomerRecord(int age)
    {
        Age = age;
    }
}

public static class Program
{
    public static void Main()
    {
        var record = new CustomerRecord(34);
        Console.WriteLine(record.Age);
    }
}

該範例展示了一個可讀的類型和屬性;混淆器可能會根據其設定和應用程式的相依關係重新命名符合條件的識別碼。執行時,程式會寫出記錄的 Age 值。執行未在提供的資料包中得到驗證,這是在混淆之前對程式的可執行說明,而不是完整的混淆器工作流程。

字串加密

字串保護會轉換選定的字串字面值,使其原始文字不會以相同方式以明文儲存在組件中。一個簡單的範例是將 Console.WriteLine("Encrypt this") 更改為諸如 Console.WriteLine("x%$&#@") 的轉換後表示形式;這只是一個前後草圖,而不是可行的加密實作。真正的工具必須在執行階段復原該值,應用程式才能使用它。

這會使在基本檢查期間搜尋面向使用者的訊息或其他字串變得不那麼有用。它並不會使嵌入的密碼、API 金鑰或其他秘密變得安全:應用程式必須能夠復原該值,而分析人員可以檢查該過程或在執行階段觀察該值。請將秘密保存在受信任的服務上,只向用戶端應用程式提供它們需要的存取權限。

反偵錯

一些產品提供旨在偵測偵錯或分析的檢查,並可能透過記錄記錄檔、限制功能或停止執行來回應。偵測取決於產品和環境,並可能產生誤報。激進的回應還可能干擾合法的偵錯、無障礙工具、支援或安全研究。請將此類檢查視為可選的摩擦,並在啟用之前驗證它們對受支援裝置和診斷的影響。

防竄改保護

防竄改功能可以檢查受保護的檔案或程式碼是否已被更改,並套用已設定的回應。根據產品的不同,該回應可能包括通知、功能受限或關閉。這些機制並不能確立每一次修改都會被偵測到,而過於寬泛的回應可能會中斷合法更新或導致支援事故。請將簽章、修補、升級和復原路徑的測試作為發行驗證的一部分。

插入虛擬程式碼

插入虛擬程式碼會加入旨在使檢查複雜化而不改變應用程式預期邏輯的程式碼。其效果取決於轉換以及用於分析結果的工具。加入的程式碼並不能保證反編譯器會失敗或逆向工程會被阻止;它還可能增加組件大小或使診斷複雜化。請評估增加的複雜性是否為你的應用程式提供了足夠的實際價值。

二進位連結與合併

一些混淆工具可以將組件或程式庫合併為更少的輸出檔案。這可能會簡化封裝,但檔案數量、應用程式大小、啟動行為和部署要求取決於工具和應用程式。合併可能會影響資源查找、反射、原生相依性和授權。請在實際部署環境中測試合併後的組建,並將所公開資訊的任何減少視為可能的副作用,而不是安全保證。