private static void Main(string[] args) { Console.WriteLine("ILProtectorUnpacker 1.1" + Environment.NewLine); if (args.Length == 0) { Console.WriteLine("Please drag & drop the protected file"); Console.WriteLine("Press any key to exit...."); Console.ReadKey(true); return; } var asmResolver = new AssemblyResolver { EnableFrameworkRedirect = false }; asmResolver.DefaultModuleContext = new ModuleContext(asmResolver); Console.WriteLine("Loading Module..."); var _module = ModuleDefMD.Load(args[0], asmResolver.DefaultModuleContext); var _assembly = Assembly.LoadFrom(args[0]); Console.WriteLine("Running global constructor..."); RuntimeHelpers.RunModuleConstructor(_assembly.ManifestModule.ModuleHandle); Console.WriteLine("Resolving fields..."); var invokeField = _module.GlobalType.FindField("Invoke"); var stringField = _module.GlobalType.FindField("String"); var strInvokeMethodToken = stringField?.FieldType.ToTypeDefOrRefSig().TypeDef?.FindMethod("Invoke")?.MDToken.ToInt32(); var invokeMethodToken = invokeField?.FieldType.ToTypeDefOrRefSig().TypeDef?.FindMethod("Invoke")?.MDToken.ToInt32(); if (invokeMethodToken is null) { throw new Exception("Cannot find Invoke field"); } var invokeInstance = _assembly.ManifestModule.ResolveField(invokeField.MDToken.ToInt32()); var invokeMethod = _assembly.ManifestModule.ResolveMethod(invokeMethodToken.Value); var invokeFieldInst = invokeInstance.GetValue(invokeInstance); MethodBase strInvokeMethod = null; object strFieldInst = null; if (strInvokeMethodToken != null) { var strInstance = _assembly.ManifestModule.ResolveField(stringField.MDToken.ToInt32()); strInvokeMethod = _assembly.ManifestModule.ResolveMethod(strInvokeMethodToken.Value); strFieldInst = strInstance.GetValue(strInstance); ToRemove.Add(stringField); } ToRemove.Add(invokeField); Console.WriteLine("Applying hook..."); Hooks.ApplyHook(); Console.WriteLine("Processing methods..."); foreach (var type in _module.GetTypes()) { foreach (var method in type.Methods) { if (!method.HasBody) { continue; } Hooks.SpoofedMethod = _assembly.ManifestModule.ResolveMethod(method.MDToken.ToInt32()); DecryptMethods(method, invokeMethod, invokeFieldInst); if (strFieldInst != null) { DecryptStrings(method, strInvokeMethod, strFieldInst); } } } Console.WriteLine("Cleaning junk..."); foreach (var obj in ToRemove) { switch (obj) { case FieldDef fieldDefinition: var res = fieldDefinition.FieldType.ToTypeDefOrRefSig().TypeDef; if (res.DeclaringType != null) { res.DeclaringType.NestedTypes.Remove(res); } else { _module.Types.Remove(res); } fieldDefinition.DeclaringType.Fields.Remove(fieldDefinition); break; case TypeDef typeDefinition: typeDefinition.DeclaringType.NestedTypes.Remove(typeDefinition); break; } } foreach (var method in _module.GlobalType.Methods .Where(t => t.HasImplMap && t.ImplMap.Name == "P0").ToList()) { _module.GlobalType.Remove(method); } var constructor = _module.GlobalType.FindStaticConstructor(); if (constructor.Body != null) { var methodBody = constructor.Body; int startIndex = methodBody.Instructions.IndexOf( methodBody.Instructions.FirstOrDefault(t => t.OpCode == OpCodes.Call && ((IMethodDefOrRef)t.Operand).Name == "GetIUnknownForObject")) - 2; int endIndex = methodBody.Instructions.IndexOf(methodBody.Instructions.FirstOrDefault( inst => inst.OpCode == OpCodes.Call && ((IMethodDefOrRef)inst.Operand).Name == "Release")) + 2; methodBody.ExceptionHandlers.Remove(methodBody.ExceptionHandlers.FirstOrDefault( exh => exh.HandlerEnd.Offset == methodBody.Instructions[endIndex + 1].Offset)); for (int i = startIndex; i <= endIndex; i++) { methodBody.Instructions.Remove(methodBody.Instructions[startIndex]); } } Console.WriteLine("Writing module..."); string newFilePath = $"{Path.GetDirectoryName(args[0])}{Path.DirectorySeparatorChar}{Path.GetFileNameWithoutExtension(args[0])}-Unpacked{Path.GetExtension(args[0])}"; ModuleWriterOptionsBase modOpts; if (!_module.IsILOnly || _module.VTableFixups != null) { modOpts = new NativeModuleWriterOptions(_module, true); } else { modOpts = new ModuleWriterOptions(_module); } if (modOpts is NativeModuleWriterOptions nativeOptions) { _module.NativeWrite(newFilePath, nativeOptions); } else { _module.Write(newFilePath, (ModuleWriterOptions)modOpts); } Console.WriteLine("Done!"); Console.ReadKey(true); }
private static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine("Please drag & drop the protected file"); Console.WriteLine("Press any key to exit...."); Console.ReadKey(true); return; } _module = ModuleDefinition.FromFile(args[0]); _assembly = Assembly.LoadFrom(args[0]); RuntimeHelpers.RunModuleConstructor(_assembly.ManifestModule.ModuleHandle); var invokeField = _module.GetModuleType().Fields.FirstOrDefault(t => t.Name == "Invoke"); var stringField = _module.GetModuleType().Fields.FirstOrDefault(t => t.Name == "String"); var strInvokeMethodToken = stringField?.Signature.FieldType.Resolve().Methods .FirstOrDefault(m => m.Name == "Invoke")?.MetadataToken.ToInt32(); var invokeMethodToken = invokeField?.Signature.FieldType.Resolve().Methods .FirstOrDefault(m => m.Name == "Invoke")?.MetadataToken.ToInt32(); if (invokeMethodToken == null) { throw new Exception("Cannot find Invoke field"); } var invokeInstance = _assembly.ManifestModule.ResolveField(invokeField.MetadataToken.ToInt32()); var invokeMethod = _assembly.ManifestModule.ResolveMethod(invokeMethodToken.Value); FieldInfo strInstance = null; MethodBase strInvokeMethod = null; if (strInvokeMethodToken != null) { strInstance = _assembly.ManifestModule.ResolveField(stringField.MetadataToken.ToInt32()); strInvokeMethod = _assembly.ManifestModule.ResolveMethod(strInvokeMethodToken.Value); ToRemove.Add(stringField); } ToRemove.Add(invokeField); Hooks.ApplyHook(); foreach (var type in _module.GetAllTypes()) { foreach (var method in type.Methods) { DecryptMethods(method, invokeMethod, invokeInstance.GetValue(invokeInstance)); if (strInstance != null) { DecryptStrings(method, strInvokeMethod, strInstance.GetValue(strInstance)); } } } foreach (var obj in ToRemove) { switch (obj) { case FieldDefinition fieldDefinition: _module.TopLevelTypes.Remove(fieldDefinition.Signature.FieldType.Resolve()); fieldDefinition.DeclaringType.Fields.Remove(fieldDefinition); break; case SerializedTypeDefinition typeDefinition: typeDefinition.DeclaringType.NestedTypes.Remove(typeDefinition); break; } } foreach (var method in _module.GetModuleType().Methods .Where(t => t.ImplementationMap != null && t.ImplementationMap.Scope.Name.Contains("Protect")).ToList()) { _module.GetModuleType().Methods.Remove(method); } var constructor = _module.GetModuleType().Methods.First(t => t.IsConstructor); if (constructor.CilMethodBody != null) { var methodBody = constructor.CilMethodBody; var startIndex = methodBody.Instructions.IndexOf( methodBody.Instructions.FirstOrDefault(t => t.OpCode == CilOpCodes.Call && ((IMethodDefOrRef)t.Operand).Name == "GetIUnknownForObject")) - 2; var endIndex = methodBody.Instructions.IndexOf(methodBody.Instructions.FirstOrDefault( inst => inst.OpCode == CilOpCodes.Call && ((IMethodDefOrRef)inst.Operand).Name == "Release")) + 2; methodBody.ExceptionHandlers.Remove(methodBody.ExceptionHandlers.FirstOrDefault( exh => exh.HandlerEnd.Offset == methodBody.Instructions[endIndex + 1].Offset)); for (var i = startIndex; i <= endIndex; i++) { methodBody.Instructions.Remove(methodBody.Instructions[startIndex]); } } var extension = Path.GetExtension(args[0]); var path = args[0].Remove(args[0].Length - extension.Length, extension.Length) + "-unpacked" + extension; _module.Write(path); }
public static void Main(string[] args) { if (args.Length < 1) { return; } try { var filePath = Path.GetFullPath(args[0]); if (!File.Exists(filePath)) { return; } filePath = args[0]; AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => Assembly.LoadFile(Path.Combine(Path.GetDirectoryName(filePath), e.Name.Split(',').FirstOrDefault() + ".dll")); Module = ModuleDefMD.Load(filePath); Assembly = Assembly.LoadFrom(filePath); var asmResolver = new AssemblyResolver { EnableTypeDefCache = true }; Module.Context = asmResolver.DefaultModuleContext = new ModuleContext(asmResolver); Module.Location = filePath; var asmRefs = Module.GetAssemblyRefs().ToList(); var notFound = new List <string>(); foreach (var asmRef in asmRefs) { if (asmRef == null) { continue; } var asmDef = asmResolver.Resolve(asmRef.FullName, Module); if (asmDef == null) { notFound.Add(asmRef.FullName); } else { ((AssemblyResolver)Module.Context.AssemblyResolver).AddToCache(asmDef); } } if (notFound.Count > 0) { Console.WriteLine("Could not load file or assembly or one of its dependencies:"); foreach (var item in notFound) { Console.WriteLine(item); } Console.WriteLine(); } RuntimeHelpers.RunModuleConstructor(Assembly.ManifestModule.ModuleHandle); GlobalType = Module.GlobalType; var invokeField = GlobalType.Fields.FirstOrDefault(x => x.Name == "Invoke"); var stringField = GlobalType.Fields.FirstOrDefault(x => x.Name == "String"); var invokeMethodToken = invokeField?.FieldType.TryGetTypeDef().Methods.FirstOrDefault(x => x.Name == "Invoke")?.MDToken.ToInt32(); var strInvokeMethodToken = stringField?.FieldType.TryGetTypeDef().Methods.FirstOrDefault(x => x.Name == "Invoke")?.MDToken.ToInt32(); if (invokeMethodToken == null) { throw new Exception("Cannot find Invoke field!"); } var invokeMethod = Assembly.ManifestModule.ResolveMethod(invokeMethodToken.Value); var invokeInstance = Assembly.ManifestModule.ResolveField(invokeField.MDToken.ToInt32()); FieldInfo strInstance = null; MethodBase strInvokeMethod = null; if (strInvokeMethodToken != null) { strInstance = Assembly.ManifestModule.ResolveField(stringField.MDToken.ToInt32()); strInvokeMethod = Assembly.ManifestModule.ResolveMethod(strInvokeMethodToken.Value); } Hooks.ApplyHook(); foreach (var type in Module.GetTypes()) { foreach (var method in type.Methods) { DecryptMethods(method, invokeMethod, invokeInstance.GetValue(invokeInstance)); if (strInstance != null) { DecryptStrings(method, strInvokeMethod, strInstance.GetValue(strInstance)); } } } JunkTypes.Add(invokeField); JunkTypes.Add(stringField); var methods = GlobalType.Methods.Where(x => x.IsPrivate && x.IsStatic && x.Name.Length == 1).ToList(); JunkTypes.AddRange(methods); CleanCctor(); RemoveJunkTypes(); RemoveEmbeddedAssemblies(); Save(filePath); } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); } Console.WriteLine("Press any key to exit..."); Console.ReadKey(); }