From df96e41ee2cfa7b6fbced3600f6174c319111730 Mon Sep 17 00:00:00 2001 From: UltimateGG Date: Mon, 5 Aug 2024 15:30:45 -0500 Subject: [PATCH] Add uint check for ConfuserEx <= 1.4.0 List # strings decrypted --- ConfuserEx2_String_Decryptor/.gitignore | 5 + .../ConfuserEx2_String_Decryptor/Program.cs | 227 +++++++++--------- 2 files changed, 122 insertions(+), 110 deletions(-) create mode 100644 ConfuserEx2_String_Decryptor/.gitignore diff --git a/ConfuserEx2_String_Decryptor/.gitignore b/ConfuserEx2_String_Decryptor/.gitignore new file mode 100644 index 0000000..8c3c7ad --- /dev/null +++ b/ConfuserEx2_String_Decryptor/.gitignore @@ -0,0 +1,5 @@ +.vs/ +packages/ +bin/ +obj/ +*.user diff --git a/ConfuserEx2_String_Decryptor/ConfuserEx2_String_Decryptor/Program.cs b/ConfuserEx2_String_Decryptor/ConfuserEx2_String_Decryptor/Program.cs index 6e0de57..5baa0df 100644 --- a/ConfuserEx2_String_Decryptor/ConfuserEx2_String_Decryptor/Program.cs +++ b/ConfuserEx2_String_Decryptor/ConfuserEx2_String_Decryptor/Program.cs @@ -10,134 +10,141 @@ namespace ConfuserEx2_String_Decryptor { - internal class Program + internal class Program + { + static Assembly LoadedAssembly; + private static int Decrypted = 0; + + public static void Main(string[] args) { - static Assembly LoadedAssembly; + Console.Title = "Dynamic ConfuserEx2 String Decryptor (ConfuserEx 1.1.0+)"; + if (args.Length == 0) + { + Console.WriteLine(Console.Title); + Console.WriteLine("Use on unpacked samples (Dumped - Passing Module Constructor)"); + Console.WriteLine("Use ConfuserEx2_String_Decryptor.exe (32-bit) on 32-bit samples and ConfuserEx2_String_Decryptor.exe (64-bit) on 64-bit samples\n"); + Console.WriteLine("Usage: Drag&Drop or ConfuserEx2_String_Decryptor.exe "); + Console.ReadKey(); + return; + } - static void Main(string[] args) - { - Console.Title = "Dynamic ConfuserEx2 String Decryptor (ConfuserEx 1.6.0+-)"; - if (args.Length == 0) - { - Console.WriteLine("ConfuserEx2 String Decryptor (ConfuserEx 1.6.0+-)"); - Console.WriteLine("Use on unpacked samples (Dumped - Passing Module Constructor)"); - Console.WriteLine("Use ConfuserEx2_String_Decryptor.exe (32-bit) on 32-bit samples and ConfuserEx2_String_Decryptor.exe (64-bit) on 64-bit samples\n"); - Console.WriteLine("Usage: Drag&Drop or ConfuserEx2_String_Decryptor.exe "); - Console.ReadKey(); - return; - } + if (!File.Exists(args[0])) + { + Console.WriteLine($"File not found: {args[0]}"); + return; + } - if (!File.Exists(args[0])) - { - Console.WriteLine($"File not found: {args[0]}"); - return; - } + string path = Path.GetFullPath(args[0]); + ModuleDefinition moduleDef = ModuleDefinition.FromFile(path); + var strDecMethods = FindStrDecryptMethods(moduleDef); + if (!strDecMethods.Any()) + { + Console.WriteLine("String decryption methods not found!!!\nDid you unpack the sample???"); + Console.ReadKey(); + return; + } - string path = Path.GetFullPath(args[0]); - ModuleDefinition moduleDef = ModuleDefinition.FromFile(path); - var strDecMethods = FindStrDecryptMethods(moduleDef); - if (!strDecMethods.Any()) - { - Console.WriteLine("String decryption methods not found!!!\nDid you unpack the sample???"); - Console.ReadKey(); - return; - } + LoadedAssembly = Assembly.LoadFrom(path); + var module = LoadedAssembly.GetModules().FirstOrDefault(); + InstallHook(); - LoadedAssembly = Assembly.LoadFrom(path); - var module = LoadedAssembly.GetModules().FirstOrDefault(); - InstallHook(); + foreach (var strDecMethod in strDecMethods) + { + var strDecMethodRefl = module.ResolveMethod(strDecMethod.Key.MetadataToken.ToInt32()); - foreach (var strDecMethod in strDecMethods) + foreach (TypeDefinition type in moduleDef.GetAllTypes().Where(t => t.Methods.Count > 0)) + { + foreach (MethodDefinition method in type.Methods.Where(m => m.CilMethodBody != null)) + { + foreach (var inst in method.CilMethodBody.Instructions.Where(i => i.OpCode == CilOpCodes.Call && i.Operand is MethodSpecification)) { - var strDecMethodRefl = module.ResolveMethod(strDecMethod.MetadataToken.ToInt32()); + if (((MethodSpecification)inst.Operand).Method.MetadataToken.ToInt32() != strDecMethod.Key.MetadataToken.ToInt32()) + continue; - foreach (TypeDefinition type in moduleDef.GetAllTypes().Where(t => t.Methods.Count > 0)) + if (inst.Operand.ToString().Contains("")) + { + var index = method.CilMethodBody.Instructions.IndexOf(inst); + for (int i = index - 1; i > index - 4; i--) { - foreach (MethodDefinition method in type.Methods.Where(m => m.CilMethodBody != null)) - { - foreach (var inst in method.CilMethodBody.Instructions.Where(i => i.OpCode == CilOpCodes.Call && i.Operand is MethodSpecification)) - { - if (((MethodSpecification)inst.Operand).Method.MetadataToken.ToInt32() == strDecMethod.MetadataToken.ToInt32()) - { - if (inst.Operand.ToString().Contains("")) - { - var index = method.CilMethodBody.Instructions.IndexOf(inst); - for (int i = index - 1; i > index - 4; i--) - { - if (method.CilMethodBody.Instructions[i].OpCode == CilOpCodes.Ldc_I4) - { - var encValue = (int)method.CilMethodBody.Instructions[i].Operand; - char[] decString = (char[])((MethodInfo)strDecMethodRefl).MakeGenericMethod(typeof(char[])).Invoke(null, new object[] { encValue }); - method.CilMethodBody.Instructions[i].ReplaceWith(CilOpCodes.Ldstr, new string(decString)); - var importer = moduleDef.DefaultImporter; - var factory = moduleDef.CorLibTypeFactory; - var importedMethod = factory.CorLibScope - .CreateTypeReference("System", "String") - .CreateMemberReference("ToCharArray", MethodSignature.CreateInstance(factory.Char.MakeSzArrayType())) - .ImportWith(importer); - inst.ReplaceWith(CilOpCodes.Call, importedMethod); - break; - } - } - } - if (inst.Operand.ToString().Contains("")) - { - var index = method.CilMethodBody.Instructions.IndexOf(inst); - for (int i = index - 1; i > index - 4; i--) - { - if (method.CilMethodBody.Instructions[i].OpCode == CilOpCodes.Ldc_I4) - { - var encValue = (int)method.CilMethodBody.Instructions[i].Operand; - string decString = (string)((MethodInfo)strDecMethodRefl).MakeGenericMethod(typeof(string)).Invoke(null, new object[] { encValue }); - inst.ReplaceWithNop(); - method.CilMethodBody.Instructions[i].ReplaceWith(CilOpCodes.Ldstr, decString); - break; - } - } - } - } - } - } + if (method.CilMethodBody.Instructions[i].OpCode == CilOpCodes.Ldc_I4) + { + int encValue = (int)method.CilMethodBody.Instructions[i].Operand; + object[] parameters = strDecMethod.Value ? new object[] { encValue } : new object[] { (uint)encValue }; + char[] decString = (char[])((MethodInfo)strDecMethodRefl).MakeGenericMethod(typeof(char[])).Invoke(null, parameters); + method.CilMethodBody.Instructions[i].ReplaceWith(CilOpCodes.Ldstr, new string(decString)); + var importer = moduleDef.DefaultImporter; + var factory = moduleDef.CorLibTypeFactory; + var importedMethod = factory.CorLibScope + .CreateTypeReference("System", "String") + .CreateMemberReference("ToCharArray", MethodSignature.CreateInstance(factory.Char.MakeSzArrayType())) + .ImportWith(importer); + inst.ReplaceWith(CilOpCodes.Call, importedMethod); + Decrypted++; + break; + } } - } - if (path.EndsWith(".exe") || path.EndsWith(".dll")) - { - moduleDef.Write(path.Insert(path.Length - 4, "-cleaned")); - } - else { moduleDef.Write(path + "-cleaned"); } - } + } - private static List FindStrDecryptMethods(ModuleDefinition moduleDef) - { - List strDecMethods = new List(); - foreach (TypeDefinition type in moduleDef.GetAllTypes().Where(t => t.Methods.Count > 0)) - { - foreach (MethodDefinition method in type.Methods.Where(m => m.CilMethodBody != null && m.Parameters.Count == 1 && m.Parameters[0].ParameterType.FullName.Equals("System.Int32"))) + if (inst.Operand.ToString().Contains("")) + { + var index = method.CilMethodBody.Instructions.IndexOf(inst); + for (int i = index - 1; i > index - 4; i--) { - if (method.CilMethodBody.Instructions.Any(inst => inst.ToString().Contains("GetExecutingAssembly()")) && method.CilMethodBody.Instructions.Any(inst => inst.ToString().Contains("GetCallingAssembly()"))) - { - strDecMethods.Add(method); - } + if (method.CilMethodBody.Instructions[i].OpCode == CilOpCodes.Ldc_I4) + { + int encValue = (int)method.CilMethodBody.Instructions[i].Operand; + object[] parameters = strDecMethod.Value ? new object[] { encValue } : new object[] { (uint)encValue }; + string decString = (string)((MethodInfo)strDecMethodRefl).MakeGenericMethod(typeof(string)).Invoke(null, parameters); + inst.ReplaceWithNop(); + method.CilMethodBody.Instructions[i].ReplaceWith(CilOpCodes.Ldstr, decString); + Decrypted++; + break; + } } + } } - return strDecMethods; + } } + } - private static void InstallHook() - { - var target = typeof(Assembly).GetMethod("GetCallingAssembly"); - if (target == null) - throw new Exception("Could not resolve Assembly.GetCallingAssembly"); - - var harmony = new Harmony("GetCallingAssembly"); - var stub = typeof(Program).GetMethod("PreFix_GetCallingAssembly"); - harmony.Patch(target, new HarmonyMethod(stub)); - } + Console.WriteLine($"Decrypted {Decrypted} strings"); + path = Path.Combine(Path.GetDirectoryName(path) ?? "./", Path.GetFileNameWithoutExtension(path) + "-cleaned" + Path.GetExtension(path)); + moduleDef.Write(path); + Console.WriteLine("Saved as: " + path); + Console.ReadKey(); + } - public static bool PreFix_GetCallingAssembly(ref Assembly __result) + private static Dictionary FindStrDecryptMethods(ModuleDefinition moduleDef) + { + Dictionary strDecMethods = new Dictionary(); + foreach (TypeDefinition type in moduleDef.GetAllTypes().Where(t => t.Methods.Count > 0)) + { + foreach (MethodDefinition method in type.Methods.Where(m => m.CilMethodBody != null && m.Parameters.Count == 1 && (m.Parameters[0].ParameterType.FullName.Equals("System.Int32") || m.Parameters[0].ParameterType.FullName.Equals("System.UInt32")))) { - __result = LoadedAssembly; // sets the result --> return value of original called method - return false; // skip executing original GetCallingAssembly() method + if (method.CilMethodBody.Instructions.Any(inst => inst.ToString().Contains("GetExecutingAssembly()")) && method.CilMethodBody.Instructions.Any(inst => inst.ToString().Contains("GetCallingAssembly()"))) + { + strDecMethods.Add(method, method.Parameters[0].ParameterType.FullName.Equals("System.Int32")); // True -> ConfuserEx > 1.4.1 | False -> ConfuserEx <= 1.4.1 + } } + } + return strDecMethods; + } + + private static void InstallHook() + { + var target = typeof(Assembly).GetMethod("GetCallingAssembly"); + if (target == null) + throw new Exception("Could not resolve Assembly.GetCallingAssembly"); + + var harmony = new Harmony("GetCallingAssembly"); + var stub = typeof(Program).GetMethod("PreFix_GetCallingAssembly"); + harmony.Patch(target, new HarmonyMethod(stub)); + } + + public static bool PreFix_GetCallingAssembly(ref Assembly __result) + { + __result = LoadedAssembly; // sets the result --> return value of original called method + return false; // skip executing original GetCallingAssembly() method } + } }