Beispiel #1
0
        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);
        }
Beispiel #2
0
        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();
        }