public static bool TestNativeWithILMethods(string filenameAsm1, string filenameAsm2) { IntPtr num = X86ILTester.LoadLibrary(filenameAsm1); AssemblyDef assemblyDef = AssemblyDef.Load(filenameAsm1, (ModuleCreationOptions)null); MethodInfo[] methods = Assembly.LoadFile(filenameAsm2).GetModules()[0].GetTypes()[0].GetMethods(BindingFlags.Static | BindingFlags.Public); foreach (MethodDef methodDef in assemblyDef.Modules[0].GlobalType.Methods.Where <MethodDef>((Func <MethodDef, bool>)(m => m.IsNative))) { MethodDef method = methodDef; if ((int)((IEnumerable <MethodInfo>)methods).FirstOrDefault <MethodInfo>((Func <MethodInfo, bool>)(m => m.Name == Convert.ToBase64String(Encoding.UTF8.GetBytes((string)method.Name)))).Invoke((object)null, new object[1] { (object)4919 }) != ((X86ILTester.PredicateCall)Marshal.GetDelegateForFunctionPointer(new IntPtr((long)num + (long)method.NativeBody.RVA), typeof(X86ILTester.PredicateCall)))(4919)) { throw new Exception("WRONG CODE!"); } } return(true); }
private static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine("No input file specified..."); return; } // Store the obfuscated file name for later use (e.g. when resolving the RVAs) Configuration.AssemblyFilename = args[0]; // Load the assembly via dnlib (Only the module, we need this structure to resolve MD Tokens) var assemblyModuleDnlib = ModuleDefMD.Load(Configuration.AssemblyFilename); // Get the <Module>-Type for later use var cctorType = assemblyModuleDnlib.GlobalType; // Store the replaced methods in this list var nativeMethodsReplaced = new List <MethodDef>(); // Find methods with native code var nativeMethods = cctorType.Methods.Where(m => m.IsNative).ToList(); foreach (var nativeMethod in nativeMethods) { // Get the assembly code and the X86 Opcode Structure (Thanks to ubbelol) X86Method x86NativeMethod = new X86Method(nativeMethod); var ILNativeMethod = X86MethodToILConverter.CreateILFromX86Method(x86NativeMethod); nativeMethod.DeclaringType.Methods.Add(ILNativeMethod); nativeMethodsReplaced.Add(nativeMethod); } // Export all the IL Methods to a DLL MethodExporter.ExportMethodsToDll("TestMethodModule.dll", nativeMethodsReplaced, assemblyModuleDnlib); // Call the DLL IL Methods and the native Methods via x86 function ptr to see if the result is the same X86ILTester.TestNativeWithILMethods(Configuration.AssemblyFilename, Path.Combine(Environment.CurrentDirectory, "TestMethodModule.dll")); // Find all the native method calls and replace them with the IL calls foreach (var replacedMethod in nativeMethodsReplaced) { var callsToNativeMethod = replacedMethod.FindAllReferences(assemblyModuleDnlib); var ilMethod = assemblyModuleDnlib.GlobalType.Methods.FirstOrDefault(m => m.Name == replacedMethod.Name + "_IL"); foreach (var call in callsToNativeMethod) { call.Operand = ilMethod; } Console.WriteLine("[+] Removed " + callsToNativeMethod.ToList().Count + " entries."); } // Remove each native method foreach (var replacedMethod in nativeMethodsReplaced) { cctorType.Methods.Remove(replacedMethod); } // Turn off signing assemblyModuleDnlib.IsStrongNameSigned = false; assemblyModuleDnlib.Assembly.PublicKey = null; // Preserve Tokens and fix the flags for ILOnly var moduleWriterOptions = new ModuleWriterOptions(); moduleWriterOptions.MetaDataOptions.Flags |= MetaDataFlags.PreserveAll; moduleWriterOptions.MetaDataOptions.Flags |= MetaDataFlags.KeepOldMaxStack; moduleWriterOptions.Cor20HeaderOptions.Flags = ComImageFlags.ILOnly | ComImageFlags._32BitRequired; assemblyModuleDnlib.Write("out_mod.exe", moduleWriterOptions); }