字符串混淆技術在.NET程序保護中的應用及如何解密被混淆的字符串


Visual Studio提供的Dotfuscator保護程序,可以對用戶代碼中包含的字符串進行加密。比如下面的例子,為了找到這個程序的注冊算法,用.NET Reflector加載程序集后,發現代碼中的字符串,都變成這種形式的:

Assembly executingAssembly = Assembly.GetExecutingAssembly();
ArrayList list = new ArrayList();
string str = Class64.smethod_0("ᓊᓜᓙᒷᓎᓝᒶᒱᒽ");
string fullName = executingAssembly.FullName;
Version version = new Version();
bool flag = false;
int index = fullName.ToLower().IndexOf(Class64.smethod_0("ᓟᓎᓛᓜᓒᓘᓗᒦ"));

注意到這幾行代碼中的方法調用的參數,已經完全不是我們熟悉的English,我把它放到Google翻譯中去尋找它的語言,結果是一種東歐的國家的語言,為了得到它對應的英語,我得找這方面的翻譯資料。如何將這種語言,翻譯成英語,結果只有專門做翻譯的公司才可以做,而且報價不便宜,按字數來收費。這一條路似乎走不通……

意識到自己走錯方向之后,馬上把自己的想法,翻譯成英語,用Google來搜索。Google翻譯的質量,確實不錯。

很快,我就得到這篇文章Decrypting strings in obfuscated assemblies,它告訴我,這個程序集應用了字符串混淆算法,同樣的例子是這樣的

int num = 19;
if (args.Length < 1)
{
        Console.WriteLine(a("昞傳圢䐤弦न個弬崮帰䄲༴᜶稸吺似䴾⑀⁂ㅄ桿㩈㉊⍌㭎ぐ⭒畔㹖⩘篳♜潞ᱠ䍢奤ቦ᭨ݪ卬佮⩰ᱲtͶॸ๺ॼ᥾uda86", num), a("東瘞䰠匢䤤䈦洨䐪娬䄮崰尲吳匶屍䤺", num));
        Console.ReadKey();
}

老外一看到這些方塊的文字,第一想到的就是Chinese,呵呵,中文語言在世界上還真有點名氣。難怪Windows的安裝程序中,專門有一項是Aisan Language是專門用來安裝東方語言文字字符集的。

解決方案也比較簡單,調用加密的辦法,獲取它的運行時的值:

string encryptedString = "東瘞䰠匢䤤䈦洨䐪娬䄮崰尲吳匶屍䤺";
int key = 19;

Assembly assembly = Assembly.LoadFile(assemblyPath);

// Okay, It’s sample code.. what do you expect! :)
MethodInfo secretMethod = assembly.GetModules()[0]
                  .GetMethods(BindingFlags.NonPublic| BindingFlags.Public| BindingFlags.Static)[0];
string decryptedString = secretMethod.Invoke(null, new object[] {encryptedString, key}) as string;
 
        

這樣就解決了字符串的反混淆。如果需要對程序中的每個字符串進行調用,需要寫一個GUI,用來批量的解決反混淆。

做到這里,基本上可以理解被混淆的程序集中的字符串的含義,然而,網上的一篇文章介紹的工具DotNetStringSearch,引起了我的注意,我確實是在找這樣的工具,也一直想做一個一勞永逸的工作,就是我需要一個工具程序,打開一個應用過字符串混淆的程序,點一個按鈕,它馬上可以為我顯示原文字符串和混淆后的字符串。

可細DotNetStringSearch的作者並沒有公布這個軟件的細節,源代碼也沒有開放,唯一提到的Rainst.net這個網站中的一篇文章,現在已經打不開,無從得知它應用的技術。這一條路似乎也走不下去……

 

一個偶然的原因,看到CodeProject上面的一篇文章,講解如何應用Mono.Cecil實現.NET代碼注入,這一下子引起了我的注意。與我們通常用的反射不同,它實現的是直接修改程序集的代碼,比起16進制工具修改EXE/DLL的二進制文件要高級得多,畢竟是原來的.NET代碼,可以直接調試,觀察實現過程。一下小心,找到SystemInternal上面的一個實用工具,Strings,這個程序可以提取PE文件中的字符串內容。

image 

思路一下就打開了,原來不是反射,是直接對PE文件格式進行讀取,運行Strings程序,果然它順利的讀取了PE格式中的字符串資源,而且源代碼是開放的,里面的例子程序是這樣的

static void Main(string[] args)
{
            try
            {
                string exePath = args[0];

                List<string> allUserStrings = ReadAllUserStrings(exePath);

                File.WriteAllLines(exePath + ".txt", allUserStrings.Select(str => CSStringConverter.Convert(str)));

                Console.WriteLine("hotovo... ");
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception: " + ex.ToString());
                Console.WriteLine("press a key...");
                Console.ReadKey();
            }
 }
 

通過上面的一段代碼,你可以很容易的找到它的源代碼文件,於是可以解決我說的目標:做一個通用的字符串反混淆程序,可以對當前流行的加密工具加密后的字符串進行反混淆。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM