字符串混淆技术应用 设计一个字符串混淆程序 可混淆.NET程序集中的字符串
關于字符串的研究,目前已經有兩篇。
原理篇:字符串混淆技術在.NET程序保護中的應用及如何解密被混淆的字符串?
實踐篇:字符串反混淆實戰 Dotfuscator 4.9 字符串加密技術應對策略
今天來講第三篇,如何應用上面所學內容,設計一個字符串混淆程序。
先設計一個控制臺程序,它是將要被我混淆的程序集文件:
public static void Main() {try{RunSnippet();}catch (Exception e){string error = string.Format("---\nThe following error occurred while executing the snippet:\n{0}\n---", e.ToString());Console.WriteLine(error);}finally{Console.Write("Press any key to continue...");Console.ReadKey();} } ?代碼是Snippet Compiler 的標準模板,在控制臺上打印一段字符串。這里,有二個字符串常量,是我需要對它進行加密的地方。
不能直接改源代碼,而且要以程序的方式來操作程序集。要能修改.net程序集,現在能找到的方法是Mono.Cecil,最新的版本是0.9.5.0。
先設計混淆算法,是個很簡單的Base64代碼轉換,這一步可以深入挖掘,做更復雜的混淆算法。
public static string StringDecode(string text1) {return Encoding.UTF8.GetString(Convert.FromBase64String(text1)); }要把這段代碼轉化為IL代碼,用Mono.Cecil來注入到制定的程序集中,先來看看翻譯成IL之后的代碼
.method public hidebysig static string StringDecode(string) cil managed {.maxstack 8L_0000: call class [mscorlib]System.Text.Encoding [mscorlib]System.Text.Encoding::get_UTF8()L_0005: ldarg.0 L_0006: call uint8[] [mscorlib]System.Convert::FromBase64String(string)L_000b: callvirt instance string [mscorlib]System.Text.Encoding::GetString(uint8[])L_0010: ret }再對比Mono.Cecil的語法例子,把上面的IL代碼,翻譯成C#代碼
MethodDefinition new_method = new MethodDefinition("StringDecode", attr, asm.MainModule.Import(typeof(string))); ParameterDefinition para = new ParameterDefinition(asm.MainModule.Import(typeof(string))); new_method.Parameters.Add(para); tp.Methods.Add(new_method);new_method.Body.MaxStackSize = 8; MethodReference mr; ILProcessor worker = new_method.Body.GetILProcessor ();mr = asm.MainModule.Import(typeof(Encoding).GetMethod("get_UTF8")); worker.Append(worker.Create(OpCodes.Call, mr));worker.Append(worker.Create(OpCodes.Ldarg_0));mr = asm.MainModule.Import(typeof(Convert).GetMethod("FromBase64String")); worker.Append(worker.Create(OpCodes.Call, mr));mr = asm.MainModule.Import(typeof(Encoding).GetMethod("GetString", new Type[] { typeof(Byte[]) })); worker.Append(worker.Create(OpCodes.Callvirt, mr)); worker.Append(worker.Create(OpCodes.Ret));?
再次,我樣要搜索目標程序集中的所有字符串,把它轉化成Base64的字符串編碼,于是遍歷IL指令,進行轉化
List<Instruction> actionInsert=new List<Instruction> (); foreach (Instruction ins in entry_point.Body.Instructions) {if (ins.OpCode.Name == "ldstr"){Console.WriteLine("Find target instruction, start modify..");byte[] bytes = System.Text.Encoding.UTF8.GetBytes (Convert.ToString (ins.Operand));ins.Operand = Convert.ToBase64String (bytes);actionInsert.Add(ins);} } ? ?最后,我們把原來的指令替換成字符串混淆算法調用
for (int i = 0; i < actionInsert.Count; i++) {mr = asm.MainModule.Import(new_method);worker = entry_point.Body.GetILProcessor();worker.InsertAfter(actionInsert[i], worker.Create(OpCodes.Call, mr)); } ? ?最后保存程序集,用.net Reflector 載入程序集,如下圖所示,字符串常量已經變成了方法調用:
這樣,增加了代碼反編譯的難度,字符串的含義完全被替換成一堆無意義的字符串。
Mono.Cecil最新的版本中,API有變化,本篇程序代碼中應用到的讀取程序集和寫入程序集
string path = @"C:\Users\Administrator\Desktop\CPP\Default.exe"; AssemblyDefinition asm = AssemblyDefinition.ReadAssembly(path); MethodDefinition entry_point = asm.EntryPoint;path = @"C:\Users\Administrator\Desktop\CPP\DefaultSecury.exe"; asm.MainModule.Write(path);關于字符串混淆算法,下面列舉幾個我找到的混淆算法,加密強度會高一些:
static string stringEncrypt(string string_0) {char[] chArray;char[] chArray1 = chArray = string_0.ToCharArray();while (true){int num;int length = chArray1.Length;if (length <= 0){break;}chArray1[num = length + -1] = (char) (chArray[num] - '?');}return string.Intern(new string(chArray)); } ?下面是Dotfuscator的混淆算法,還加了鹽,強度提升不少。
static string GetString(string source, int salt){int index = 0;char[] data = source.ToCharArray();salt += 0xe74d6d7; // This const data generated by dotfuscatorwhile (index < data.Length){char key = data[index];byte low = (byte)((key & '\x00ff') ^ salt++);byte high = (byte)((key >> 8) ^ salt++);data[index] = (char)((low << 8 | high));index++;}return string.Intern(new string(data));} ?經過混淆后的字符串,完全看不出原文的含義。比如下面的代碼片段,都有些懷疑它使用的字符集,有點像中東國家的語言
再來看一個代碼中有中文的例子,這是一段用戶登陸代碼,它加密后的字符看起來更不可理解。
如果要給字符串混淆加鹽,只需要簡單的修改上面的代碼,添加一個臨時變量,再增加到調用的混淆算法中。
全文代碼以NUnit測試方法寫成,單元測試配合Resharper真是好用,可以節省大量的代碼,一個方法即可作為入口程序啟動運行。
給開發和測試帶多很多方便。
轉載于:https://www.cnblogs.com/JamesLi2015/p/3168786.html
總結
以上是生活随笔為你收集整理的字符串混淆技术应用 设计一个字符串混淆程序 可混淆.NET程序集中的字符串的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: keil uVision 注册过期导致编
- 下一篇: asp.net ajax控件工具集 Au