void FindStringDecrypterMethods(TypeDef type, ISimpleDeobfuscator simpleDeobfuscator) { foreach (var method in DotNetUtils.FindMethods(type.Methods, "System.String", new string[] { "System.String", "System.Int32" })) { if (method.Body.HasExceptionHandlers) { continue; } if (DotNetUtils.GetMethodCalls(method, "System.Char[] System.String::ToCharArray()") != 1) { continue; } if (DotNetUtils.GetMethodCalls(method, "System.String System.String::Intern(System.String)") != 1) { continue; } simpleDeobfuscator.Deobfuscate(method); var instrs = method.Body.Instructions; for (int i = 0; i < instrs.Count - 3; i++) { var ldarg = instrs[i]; if (!ldarg.IsLdarg() || ldarg.GetParameterIndex() != 0) { continue; } var callvirt = instrs[i + 1]; if (callvirt.OpCode.Code != Code.Callvirt) { continue; } var calledMethod = callvirt.Operand as MemberRef; if (calledMethod == null || calledMethod.FullName != "System.Char[] System.String::ToCharArray()") { continue; } var stloc = instrs[i + 2]; if (!stloc.IsStloc()) { continue; } var ldci4 = instrs[i + 3]; if (!ldci4.IsLdcI4()) { continue; } var info = new StringDecrypterInfo(method, ldci4.GetLdcI4Value()); stringDecrypterMethods.Add(info.method, info); Logger.v("Found string decrypter method: {0}, magic: 0x{1:X8}", Utils.RemoveNewlines(info.method), info.magic); break; } } }
void findStringDecrypterMethods(TypeDefinition type, ISimpleDeobfuscator simpleDeobfuscator) { foreach (var method in DotNetUtils.findMethods(type.Methods, "System.String", new string[] { "System.String", "System.Int32" })) { if (method.Body.HasExceptionHandlers) { continue; } var methodCalls = DotNetUtils.getMethodCallCounts(method); if (methodCalls.count("System.Char[] System.String::ToCharArray()") != 1) { continue; } if (methodCalls.count("System.String System.String::Intern(System.String)") != 1) { continue; } simpleDeobfuscator.deobfuscate(method); var instructions = method.Body.Instructions; for (int i = 0; i <= instructions.Count - 3; i++) { var ldci4 = method.Body.Instructions[i]; if (!DotNetUtils.isLdcI4(ldci4)) { continue; } if (instructions[i + 1].OpCode.Code != Code.Ldarg_1) { continue; } if (instructions[i + 2].OpCode.Code != Code.Add) { continue; } var info = new StringDecrypterInfo(method, DotNetUtils.getLdcI4Value(ldci4)); stringDecrypterMethods[info.method] = info; Log.v("Found string decrypter method: {0}, magic: 0x{1:X8}", Utils.removeNewlines(info.method), info.magic); break; } } }
void findStringDecrypterMethods(TypeDef type, ISimpleDeobfuscator simpleDeobfuscator) { foreach (var method in DotNetUtils.findMethods(type.Methods, "System.String", new string[] { "System.String", "System.Int32" })) { if (method.Body.HasExceptionHandlers) continue; if (DotNetUtils.getMethodCalls(method, "System.Char[] System.String::ToCharArray()") != 1) continue; if (DotNetUtils.getMethodCalls(method, "System.String System.String::Intern(System.String)") != 1) continue; simpleDeobfuscator.deobfuscate(method); var instructions = method.Body.Instructions; for (int i = 0; i <= instructions.Count - 3; i++) { var ldci4 = method.Body.Instructions[i]; if (!ldci4.IsLdcI4()) continue; if (instructions[i + 1].OpCode.Code != Code.Ldarg_1) continue; if (instructions[i + 2].OpCode.Code != Code.Add) continue; var info = new StringDecrypterInfo(method, ldci4.GetLdcI4Value()); stringDecrypterMethods.add(info.method, info); Logger.v("Found string decrypter method: {0}, magic: 0x{1:X8}", Utils.removeNewlines(info.method), info.magic); break; } } }
void FindStringDecrypterMethods(TypeDef type, ISimpleDeobfuscator simpleDeobfuscator) { foreach (var method in DotNetUtils.FindMethods(type.Methods, "System.String", new string[] { "System.String", "System.Int32" })) { if (method.Body.HasExceptionHandlers) continue; if (DotNetUtils.GetMethodCalls(method, "System.Char[] System.String::ToCharArray()") != 1) continue; if (DotNetUtils.GetMethodCalls(method, "System.String System.String::Intern(System.String)") != 1) continue; simpleDeobfuscator.Deobfuscate(method); var instrs = method.Body.Instructions; for (int i = 0; i < instrs.Count - 3; i++) { var ldarg = instrs[i]; if (!ldarg.IsLdarg() || ldarg.GetParameterIndex() != 0) continue; var callvirt = instrs[i + 1]; if (callvirt.OpCode.Code != Code.Callvirt) continue; var calledMethod = callvirt.Operand as MemberRef; if (calledMethod == null || calledMethod.FullName != "System.Char[] System.String::ToCharArray()") continue; var stloc = instrs[i + 2]; if (!stloc.IsStloc()) continue; var ldci4 = instrs[i + 3]; if (!ldci4.IsLdcI4()) continue; var info = new StringDecrypterInfo(method, ldci4.GetLdcI4Value()); stringDecrypterMethods.Add(info.method, info); Logger.v("Found string decrypter method: {0}, magic: 0x{1:X8}", Utils.RemoveNewlines(info.method), info.magic); break; } } }
void findStringDecrypterMethods(TypeDefinition type) { foreach (var method in DotNetUtils.findMethods(type.Methods, "System.String", new string[] { "System.String", "System.Int32" })) { if (method.Body.HasExceptionHandlers) continue; var methodCalls = DotNetUtils.getMethodCallCounts(method); if (methodCalls.count("System.Char[] System.String::ToCharArray()") != 1) continue; if (methodCalls.count("System.String System.String::Intern(System.String)") != 1) continue; DeobfuscatedFile.deobfuscate(method); var instructions = method.Body.Instructions; for (int i = 0; i <= instructions.Count - 3; i++) { var ldci4 = method.Body.Instructions[i]; if (!DotNetUtils.isLdcI4(ldci4)) continue; if (instructions[i + 1].OpCode.Code != Code.Ldarg_1) continue; if (instructions[i + 2].OpCode.Code != Code.Add) continue; var info = new StringDecrypterInfo(method, DotNetUtils.getLdcI4Value(ldci4)); Log.v("Found string decrypter method: {0}, magic: 0x{1:X8}", info.method, info.magic); stringDecrypterMethods[info.method] = info; staticStringDecrypter.add(info.method, (method2, args) => decryptString(stringDecrypterMethods[method2], (string)args[0], (int)args[1])); break; } } }
static string decryptString(StringDecrypterInfo info, string encrypted, int value) { char[] chars = encrypted.ToCharArray(); byte key = (byte)(info.magic + value); for (int i = 0; i < chars.Length; i++) { char c = chars[i]; byte b1 = (byte)((byte)c ^ key++); byte b2 = (byte)((byte)(c >> 8) ^ key++); chars[i] = (char)((b1 << 8) | b2); } return new string(chars); }