Visual Studio提供的Dotfuscator保護程序,能夠對用戶代碼中包含的字符串進行加密。好比下面的例子,爲了找到這個程序的註冊算法,用.NET Reflector加載程序集後,發現代碼中的字符串,都變成這種形式的:css
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翻譯中去尋找它的語言,結果是一種東歐的國家的語言,爲了獲得它對應的英語,我得找這方面的翻譯資料。如何將這種語言,翻譯成英語,結果只有專門作翻譯的公司才能夠作,並且報價不便宜,按字數來收費。這一條路彷佛走不通……html
意識到本身走錯方向以後,立刻把本身的想法,翻譯成英語,用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,用來批量的解決反混淆。spa
作到這裏,基本上能夠理解被混淆的程序集中的字符串的含義,然而,網上的一篇文章介紹的工具DotNetStringSearch,引發了個人注意,我確實是在找這樣的工具,也一直想作一個一勞永逸的工做,就是我須要一個工具程序,打開一個應用過字符串混淆的程序,點一個按鈕,它立刻能夠爲我顯示原文字符串和混淆後的字符串。.net
可細DotNetStringSearch的做者並無公佈這個軟件的細節,源代碼也沒有開放,惟一提到的Rainst.net這個網站中的一篇文章,如今已經打不開,無從得知它應用的技術。這一條路彷佛也走不下去……翻譯
一個偶然的緣由,看到CodeProject上面的一篇文章,講解如何應用Mono.Cecil實現.NET代碼注入,這一會兒引發了個人注意。與咱們一般用的反射不一樣,它實現的是直接修改程序集的代碼,比起16進制工具修改EXE/DLL的二進制文件要高級得多,畢竟是原來的.NET代碼,能夠直接調試,觀察實現過程。一下當心,找到SystemInternal上面的一個實用工具,Strings,這個程序能夠提取PE文件中的字符串內容。調試
思路一下就打開了,原來不是反射,是直接對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(); } }
經過上面的一段代碼,你能夠很容易的找到它的源代碼文件,因而能夠解決我說的目標:作一個通用的字符串反混淆程序,能夠對當前流行的加密工具加密後的字符串進行反混淆。