예제 #1
0
        public override void deobfuscateBegin()
        {
            base.deobfuscateBegin();

            if (options.RestoreFields)
            {
                fieldsRestorer = new FieldsRestorer(module);
                fieldsRestorer.initialize();
            }

            foreach (var method in stringDecrypter.DecrypterMethods)
            {
                staticStringInliner.add(method, (method2, args) => {
                    return(stringDecrypter.decrypt(method2, args));
                });
            }
            DeobfuscatedFile.stringDecryptersAdded();

            resourceResolver.initialize();
            decryptResources();

            dumpEmbeddedAssemblies();

            startedDeobfuscating = true;
        }
예제 #2
0
        public override void deobfuscateBegin()
        {
            base.deobfuscateBegin();

            stringDecrypter.initialize(DeobfuscatedFile);
            staticStringInliner.add(stringDecrypter.Method, (method2, args) => {
                return(stringDecrypter.decrypt((int)args[0]));
            });
            DeobfuscatedFile.stringDecryptersAdded();

            assemblyResolver.initialize(DeobfuscatedFile, this);
            assemblyResolver.initializeEmbeddedFiles();
            addModuleCctorInitCallToBeRemoved(assemblyResolver.InitMethod);

            resourceResolver.initialize(DeobfuscatedFile, this);
            foreach (var info in resourceResolver.mergeResources())
            {
                addResourceToBeRemoved(info.Resource, "Encrypted resources");
            }
            addModuleCctorInitCallToBeRemoved(resourceResolver.InitMethod);

            getManifestResourceRestorer = new GetManifestResourceRestorer(module);
            getManifestResourceRestorer.find(DeobfuscatedFile, this);

            dumpEmbeddedAssemblies();
        }
예제 #3
0
        public override void deobfuscateBegin()
        {
            base.deobfuscateBegin();

            stringDecrypter = new StringDecrypter(decrypterInfo);
            stringDecrypter.find();
            if (stringDecrypter.Detected)
            {
                stringDecrypter.initialize(getEncoding(options.StringCodePage));
                staticStringInliner.add(stringDecrypter.Method, (method, gim, args) => stringDecrypter.decrypt((uint)args[0]));
                DeobfuscatedFile.stringDecryptersAdded();
            }
            else
            {
                freePEImage();
            }

            foreach (var method in mainType.InitMethods)
            {
                addCctorInitCallToBeRemoved(method);
            }
            addTypeToBeRemoved(mainType.Type, "Obfuscator type");
            removeDuplicateEmbeddedResources();
            removeInvalidResources();
        }
예제 #4
0
        public override void deobfuscateBegin()
        {
            base.deobfuscateBegin();

            staticStringInliner.add(stringDecrypter.Method, (method, gim, args) => stringDecrypter.decrypt((string)args[0], (int)args[1]));
            DeobfuscatedFile.stringDecryptersAdded();
        }
예제 #5
0
        public override void deobfuscateBegin()
        {
            base.deobfuscateBegin();

            stringDecrypter.initialize(DeobfuscatedFile);
            staticStringInliner.add(stringDecrypter.Method, (method2, gim, args) => {
                return(stringDecrypter.decrypt((int)args[0]));
            });
            DeobfuscatedFile.stringDecryptersAdded();

            assemblyResolver.initialize(DeobfuscatedFile, this);
            assemblyResolver.initializeEmbeddedFiles();
            addModuleCctorInitCallToBeRemoved(assemblyResolver.InitMethod);

            resourceResolver.initialize(DeobfuscatedFile, this);
            foreach (var info in resourceResolver.mergeResources())
            {
                addResourceToBeRemoved(info.Resource, "Encrypted resources");
            }
            addModuleCctorInitCallToBeRemoved(resourceResolver.InitMethod);

            resourceMethodsRestorer = new ResourceMethodsRestorer(module);
            if ((Operations.RenamerFlags & (RenamerFlags.RenameTypes | RenamerFlags.RenameNamespaces)) != 0)
            {
                resourceMethodsRestorer.find(DeobfuscatedFile, this);
            }

            dumpEmbeddedAssemblies();
        }
예제 #6
0
        public override void deobfuscateBegin()
        {
            base.deobfuscateBegin();

            if (options.DecryptResources)
            {
                addCctorInitCallToBeRemoved(resourceResolver.InitMethod);
                addTypeToBeRemoved(resourceResolver.Type, "Resource resolver type");
            }

            decryptResources();
            stringDecrypter.initialize();

            if (Operations.DecryptStrings != OpDecryptString.None)
            {
                if (stringDecrypter.Resource != null)
                {
                    Log.v("Adding string decrypter. Resource: {0}", Utils.toCsharpString(stringDecrypter.Resource.Name));
                }
                staticStringInliner.add(stringDecrypter.DecryptMethod, (method, gim, args) => {
                    return(stringDecrypter.decrypt(args));
                });
                DeobfuscatedFile.stringDecryptersAdded();
            }

            if (options.DumpEmbeddedAssemblies)
            {
                assemblyResolver.initialize(DeobfuscatedFile, this);

                // Need to dump the assemblies before decrypting methods in case there's a reference
                // in the encrypted code to one of these assemblies.
                dumpEmbeddedAssemblies();
            }

            if (options.DecryptMethods)
            {
                methodsDecrypter.initialize(DeobfuscatedFile, this);
                methodsDecrypter.decrypt();
            }

            if (options.DecryptConstants)
            {
                constantsDecrypter.initialize(DeobfuscatedFile, this);

                addTypeToBeRemoved(constantsDecrypter.Type, "Constants decrypter type");
                addResourceToBeRemoved(constantsDecrypter.Resource, "Encrypted constants");
                int32ValueInliner = new Int32ValueInliner();
                int32ValueInliner.add(constantsDecrypter.Int32Decrypter, (method, gim, args) => constantsDecrypter.decryptInt32((int)args[0]));
                int64ValueInliner = new Int64ValueInliner();
                int64ValueInliner.add(constantsDecrypter.Int64Decrypter, (method, gim, args) => constantsDecrypter.decryptInt64((int)args[0]));
                singleValueInliner = new SingleValueInliner();
                singleValueInliner.add(constantsDecrypter.SingleDecrypter, (method, gim, args) => constantsDecrypter.decryptSingle((int)args[0]));
                doubleValueInliner = new DoubleValueInliner();
                doubleValueInliner.add(constantsDecrypter.DoubleDecrypter, (method, gim, args) => constantsDecrypter.decryptDouble((int)args[0]));
            }

            proxyCallFixer.find();
            startedDeobfuscating = true;
        }
예제 #7
0
 public override void deobfuscateBegin()
 {
     base.deobfuscateBegin();
     foreach (var info in stringDecrypter.StringDecrypterInfos)
     {
         staticStringInliner.add(info.method, (method, gim, args) => stringDecrypter.decrypt(method, (string)args[0], (int)args[1]));
     }
     DeobfuscatedFile.stringDecryptersAdded();
 }
예제 #8
0
        public override void deobfuscateBegin()
        {
            base.deobfuscateBegin();

            proxyDelegateFinder = new ProxyDelegateFinder(module);
            proxyDelegateFinder.find();
            localsRestorer = new LocalsRestorer(module);
            if (options.RestoreLocals)
            {
                localsRestorer.find();
            }

            logicalExpressionFixer = new LogicalExpressionFixer();
            stringDecrypter.initialize();
            integerDecrypter.initialize();
            arrayDecrypter.initialize();

            if (options.DecryptIntegers)
            {
                int32ValueInliner = new Int32ValueInliner();
                foreach (var method in integerDecrypter.getMethods())
                {
                    int32ValueInliner.add(method, (method2, args) => {
                        return(integerDecrypter.decrypt(method2));
                    });
                }
            }

            if (options.DecryptArrays)
            {
                arrayValueInliner = new ArrayValueInliner(module, initializedDataCreator);
                foreach (var method in arrayDecrypter.getMethods())
                {
                    arrayValueInliner.add(method, (method2, args) => {
                        return(arrayDecrypter.decrypt(method2));
                    });
                }
            }

            foreach (var method in stringDecrypter.getMethods())
            {
                staticStringInliner.add(method, (method2, args) => {
                    return(stringDecrypter.decrypt(method2));
                });
                DeobfuscatedFile.stringDecryptersAdded();
            }

            if (options.RemoveAntiStrongName)
            {
                addTypeToBeRemoved(strongNameChecker.Type, "Strong name checker type");
            }

            startedDeobfuscating = true;
        }
예제 #9
0
        public override void deobfuscateBegin()
        {
            base.deobfuscateBegin();

            staticStringInliner.add(stringDecrypter.Method, (method, gim, args) => stringDecrypter.decrypt((string)args[0]));
            DeobfuscatedFile.stringDecryptersAdded();

            proxyCallFixer.find();
            cfMethodCallInliner = new CfMethodCallInliner(proxyCallFixer);

            dumpEmbeddedAssemblies();
        }
예제 #10
0
        public override void deobfuscateBegin()
        {
            base.deobfuscateBegin();

            cliSecureRtType.findStringDecrypterMethod();
            stringDecrypter.Method = cliSecureRtType.StringDecrypterMethod;

            addAttributesToBeRemoved(cliSecureAttributes, "Obfuscator attribute");

            if (options.DecryptResources)
            {
                decryptResources(resourceDecrypter);
                addCctorInitCallToBeRemoved(resourceDecrypter.RsrcRrrMethod);
            }

            stackFrameHelper = new StackFrameHelper(module);
            stackFrameHelper.find();

            foreach (var type in module.Types)
            {
                if (type.FullName == "InitializeDelegate" && DotNetUtils.derivesFromDelegate(type))
                {
                    this.addTypeToBeRemoved(type, "Obfuscator type");
                }
            }

            proxyCallFixer.find();

            staticStringInliner.add(stringDecrypter.Method, (method, gim, args) => stringDecrypter.decrypt((string)args[0]));
            DeobfuscatedFile.stringDecryptersAdded();

            if (options.DecryptMethods)
            {
                addCctorInitCallToBeRemoved(cliSecureRtType.InitializeMethod);
                addCctorInitCallToBeRemoved(cliSecureRtType.PostInitializeMethod);
                findPossibleNamesToRemove(cliSecureRtType.LoadMethod);
            }

            if (options.RestoreVmCode)
            {
                if (csvm.restore())
                {
                    addResourceToBeRemoved(csvm.Resource, "CSVM data resource");
                }
                else
                {
                    Logger.e("Couldn't restore VM methods. Use --dont-rename or it will not run");
                    preserveTokensAndTypes();
                }
            }
        }
예제 #11
0
 void initializeStringDecrypter()
 {
     if (hasInitializedStringDecrypter)
     {
         return;
     }
     stringDecrypter.initialize(DeobfuscatedFile);
     foreach (var info in stringDecrypter.Infos)
     {
         staticStringInliner.add(info.Method, (method, gim, args) => stringDecrypter.decrypt(method, (int)args[0], (int)args[1], (int)args[2]));
     }
     DeobfuscatedFile.stringDecryptersAdded();
     hasInitializedStringDecrypter = true;
 }
예제 #12
0
        public override void deobfuscateBegin()
        {
            base.deobfuscateBegin();

            addTypeToBeRemoved(killType, "KILL type");

            mainType.initialize();
            foreach (var initMethod in mainType.OtherInitMethods)
            {
                addCctorInitCallToBeRemoved(initMethod);
                addCtorInitCallToBeRemoved(initMethod);
            }

            if (Operations.DecryptStrings != OpDecryptString.None)
            {
                stringDecrypter.initialize();
                staticStringInliner.add(stringDecrypter.DecryptMethod, (method, gim, args) => {
                    return(stringDecrypter.decrypt((int)args[0]));
                });
                DeobfuscatedFile.stringDecryptersAdded();
                addModuleCctorInitCallToBeRemoved(stringDecrypter.InitMethod);
                addCallToBeRemoved(mainType.getInitStringDecrypterMethod(stringDecrypter.InitMethod), stringDecrypter.InitMethod);
            }

            assemblyResolver = new AssemblyResolver(module);
            assemblyResolver.initialize();
            dumpEmbeddedAssemblies();

            removeTamperDetection();

            proxyCallFixer.initialize();
            proxyCallFixer.find();

            resourceDecrypter = new ResourceDecrypter(module);
            resourceDecrypter.initialize();
            resourceDecrypter.decrypt();
            if (resourceDecrypter.CanRemoveTypes)
            {
                addTypeToBeRemoved(resourceDecrypter.ResourceFlagsType, "Obfuscator ResourceFlags type");
                addTypeToBeRemoved(resourceDecrypter.ResType, "Obfuscator Res type");
                addTypeToBeRemoved(resourceDecrypter.ResourceEnumeratorType, "Obfuscator ResourceEnumerator type");
                addTypeToBeRemoved(resourceDecrypter.EncryptedResourceReaderType, "Obfuscator EncryptedResourceReader type");
                addTypeToBeRemoved(resourceDecrypter.EncryptedResourceSetType, "Obfuscator EncryptedResourceSet type");
                addTypeToBeRemoved(resourceDecrypter.EncryptedResourceStreamType, "Obfuscator EncryptedResourceStream type");
            }
        }
예제 #13
0
        void initStringDecrypter(StringDecrypterInfo info)
        {
            Log.v("Adding string decrypter. Resource: {0}", Utils.toCsharpString(info.StringsResource.Name));
            var decrypter = new StringDecrypter(info);

            if (decrypter.CanDecrypt)
            {
                staticStringInliner.add(DotNetUtils.getMethod(info.GetStringDelegate, "Invoke"), (method, args) => {
                    var fieldDefinition = DotNetUtils.getField(module, (FieldReference)args[0]);
                    return(decrypter.decrypt(fieldDefinition.MetadataToken.ToInt32(), (int)args[1]));
                });
                staticStringInliner.add(info.StringDecrypterMethod, (method, args) => {
                    return(decrypter.decrypt(0, (int)args[0]));
                });
            }
            stringDecrypters.Add(decrypter);
            DeobfuscatedFile.stringDecryptersAdded();
        }
예제 #14
0
        public override void deobfuscateBegin()
        {
            base.deobfuscateBegin();

            addAttributeToBeRemoved(cliSecureAttribute, "Obfuscator attribute");

            if (options.DecryptResources)
            {
                var resourceDecrypter = new ResourceDecrypter(module);
                resourceDecrypter.find();
                decryptResources(resourceDecrypter);
                addCctorInitCallToBeRemoved(resourceDecrypter.RsrcRrrMethod);
            }

            stackFrameHelper = new StackFrameHelper(module);
            stackFrameHelper.find();

            foreach (var type in module.Types)
            {
                if (type.FullName == "InitializeDelegate" && DotNetUtils.derivesFromDelegate(type))
                {
                    this.addTypeToBeRemoved(type, "Obfuscator type");
                }
            }

            proxyDelegateFinder.find();

            staticStringInliner.add(stringDecrypter.Method, (method, args) => stringDecrypter.decrypt((string)args[0]));
            DeobfuscatedFile.stringDecryptersAdded();

            if (options.DecryptMethods)
            {
                addCctorInitCallToBeRemoved(cliSecureRtType.InitializeMethod);
                addCctorInitCallToBeRemoved(cliSecureRtType.PostInitializeMethod);
                findPossibleNamesToRemove(cliSecureRtType.LoadMethod);
            }

            if (options.RestoreVmCode)
            {
                csvm.restore();
                addAssemblyReferenceToBeRemoved(csvm.VmAssemblyReference, "CSVM assembly reference");
                addResourceToBeRemoved(csvm.Resource, "CSVM data resource");
            }
        }
예제 #15
0
        void initStringDecrypter(StringDecrypterInfo info)
        {
            Logger.v("Adding string decrypter. Resource: {0}", Utils.toCsharpString(info.StringsResource.Name));
            var decrypter = new StringDecrypter(info);

            if (decrypter.CanDecrypt)
            {
                var invokeMethod = info.GetStringDelegate == null ? null : info.GetStringDelegate.FindMethod("Invoke");
                staticStringInliner.add(invokeMethod, (method, gim, args) => {
                    var fieldDef = DotNetUtils.getField(module, (IField)args[0]);
                    return(decrypter.decrypt(fieldDef.MDToken.ToInt32(), (int)args[1]));
                });
                staticStringInliner.add(info.StringDecrypterMethod, (method, gim, args) => {
                    return(decrypter.decrypt(0, (int)args[0]));
                });
            }
            stringDecrypters.Add(decrypter);
            DeobfuscatedFile.stringDecryptersAdded();
        }
예제 #16
0
        public override void deobfuscateBegin()
        {
            base.deobfuscateBegin();

            resourceDecrypter = new ResourceDecrypter(module, DeobfuscatedFile);
            resourceResolver  = new ResourceResolver(module, resourceDecrypter);
            assemblyResolver  = new AssemblyResolver(module);
            resourceResolver.find();
            assemblyResolver.find();

            decryptResources();
            stringDecrypter.init(resourceDecrypter);
            if (stringDecrypter.Method != null)
            {
                staticStringInliner.add(stringDecrypter.Method, (method, args) => {
                    return(stringDecrypter.decrypt((int)args[0]));
                });
                DeobfuscatedFile.stringDecryptersAdded();
            }

            antiDebugger = new AntiDebugger(module, DeobfuscatedFile, this);
            antiDebugger.find();

            addModuleCctorInitCallToBeRemoved(resourceResolver.Method);
            addModuleCctorInitCallToBeRemoved(assemblyResolver.Method);
            addCallToBeRemoved(module.EntryPoint, tamperDetection.Method);
            addModuleCctorInitCallToBeRemoved(tamperDetection.Method);
            addCallToBeRemoved(module.EntryPoint, antiDebugger.Method);
            addModuleCctorInitCallToBeRemoved(antiDebugger.Method);
            addTypeToBeRemoved(resourceResolver.Type, "Resource resolver type");
            addTypeToBeRemoved(assemblyResolver.Type, "Assembly resolver type");
            addTypeToBeRemoved(tamperDetection.Type, "Tamper detection type");
            addTypeToBeRemoved(antiDebugger.Type, "Anti-debugger type");

            proxyDelegateFinder.find();

            dumpEmbeddedAssemblies();
        }
예제 #17
0
        public override void deobfuscateBegin()
        {
            base.deobfuscateBegin();

            antiStrongName = new AntiStrongName();

            staticStringInliner.add(decrypterType.StringDecrypter1, (method2, args) => {
                return(decrypterType.decrypt1((string)args[0]));
            });
            staticStringInliner.add(decrypterType.StringDecrypter2, (method2, args) => {
                return(decrypterType.decrypt2((string)args[0]));
            });
            DeobfuscatedFile.stringDecryptersAdded();

            libAssemblyResolver = new LibAssemblyResolver(module);
            libAssemblyResolver.find(DeobfuscatedFile, this);

            if (Operations.DecryptStrings == OpDecryptString.None)
            {
                canRemoveDecrypterType = false;
            }

            removeInitCall(nativeLibSaver.InitMethod);
            addResourceToBeRemoved(nativeLibSaver.Resource, "Native lib resource");
            addTypeToBeRemoved(nativeLibSaver.Type, "Native lib saver type");

            foreach (var initMethod in decrypterType.InitMethods)
            {
                removeInitCall(initMethod);
            }

            dumpUnpackedFiles();
            dumpResourceFiles();

            startedDeobfuscating = true;
        }
예제 #18
0
        public override void deobfuscateBegin()
        {
            base.deobfuscateBegin();

            methodCallInliner.initialize();

            if (options.RestoreResourceNames)
            {
                resourceNamesRestorer = new ResourceNamesRestorer(module);
                resourceNamesRestorer.find();
                resourceNamesRestorer.renameResources();
            }

            stringDecrypter.initialize();
            foreach (var info in stringDecrypter.DecrypterInfos)
            {
                staticStringInliner.add(info.method, (method2, args) => {
                    return(stringDecrypter.decrypt(method2));
                });
            }
            DeobfuscatedFile.stringDecryptersAdded();

            startedDeobfuscating = true;
        }
예제 #19
0
        public override void deobfuscateBegin()
        {
            base.deobfuscateBegin();

            proxyCallFixer = new ProxyCallFixer(module, DeobfuscatedFile);
            proxyCallFixer.findDelegateCreator();
            proxyCallFixer.find();

            stringDecrypter.init(peImage, fileData, DeobfuscatedFile);
            booleanDecrypter.init(fileData, DeobfuscatedFile);
            booleanValueInliner = new BooleanValueInliner();
            emptyClass          = new EmptyClass(module);

            if (options.DecryptBools)
            {
                booleanValueInliner.add(booleanDecrypter.Method, (method, gim, args) => {
                    return(booleanDecrypter.decrypt((int)args[0]));
                });
            }

            foreach (var info in stringDecrypter.DecrypterInfos)
            {
                staticStringInliner.add(info.method, (method2, gim, args) => {
                    return(stringDecrypter.decrypt(method2, (int)args[0]));
                });
            }
            if (stringDecrypter.OtherStringDecrypter != null)
            {
                staticStringInliner.add(stringDecrypter.OtherStringDecrypter, (method2, gim, args) => {
                    return(stringDecrypter.decrypt((string)args[0]));
                });
            }
            DeobfuscatedFile.stringDecryptersAdded();

            metadataTokenObfuscator = new MetadataTokenObfuscator(module);
            antiStrongname          = new AntiStrongName(getDecrypterType());

            bool removeResourceResolver = false;

            if (options.DecryptResources)
            {
                resourceResolver.init(DeobfuscatedFile, this);
                decryptResources();
                if (options.InlineMethods)
                {
                    addTypeToBeRemoved(resourceResolver.Type, "Resource decrypter type");
                    removeResourceResolver = true;
                }
                addEntryPointCallToBeRemoved(resourceResolver.InitMethod);
                addCctorInitCallToBeRemoved(resourceResolver.InitMethod);
            }
            if (resourceResolver.Detected && !removeResourceResolver && !resourceResolver.FoundResource)
            {
                canRemoveDecrypterType = false;                 // There may be calls to its .ctor
            }
            if (Operations.DecryptStrings != OpDecryptString.None)
            {
                addResourceToBeRemoved(stringDecrypter.Resource, "Encrypted strings");
            }
            else
            {
                canRemoveDecrypterType = false;
            }

            if (options.DecryptMethods && !methodsDecrypter.HasNativeMethods)
            {
                addResourceToBeRemoved(methodsDecrypter.Resource, "Encrypted methods");
                addCctorInitCallToBeRemoved(methodsDecrypter.Method);
            }
            else
            {
                canRemoveDecrypterType = false;
            }

            if (options.DecryptBools)
            {
                addResourceToBeRemoved(booleanDecrypter.Resource, "Encrypted booleans");
            }
            else
            {
                canRemoveDecrypterType = false;
            }

            if (!options.RemoveAntiStrongName)
            {
                canRemoveDecrypterType = false;
            }

            // The inlined methods may contain calls to the decrypter class
            if (!options.InlineMethods)
            {
                canRemoveDecrypterType = false;
            }

            if (options.DumpEmbeddedAssemblies)
            {
                if (options.InlineMethods)
                {
                    addTypeToBeRemoved(assemblyResolver.Type, "Assembly resolver");
                }
                addEntryPointCallToBeRemoved(assemblyResolver.InitMethod);
                addCctorInitCallToBeRemoved(assemblyResolver.InitMethod);
                dumpEmbeddedAssemblies();
            }

            if (options.InlineMethods)
            {
                addTypeToBeRemoved(metadataTokenObfuscator.Type, "Metadata token obfuscator");
            }

            addCctorInitCallToBeRemoved(emptyClass.Method);
            addCtorInitCallToBeRemoved(emptyClass.Method);
            addEntryPointCallToBeRemoved(emptyClass.Method);
            if (options.InlineMethods)
            {
                addTypeToBeRemoved(emptyClass.Type, "Empty class");
            }

            startedDeobfuscating = true;
        }
예제 #20
0
        public override void deobfuscateBegin()
        {
            base.deobfuscateBegin();

            resourceDecrypter = new ResourceDecrypter(module, DeobfuscatedFile);
            resourceResolver  = new ResourceResolver(module, resourceDecrypter);
            assemblyResolver  = new AssemblyResolver(module);
            resourceResolver.find();
            assemblyResolver.find();

            decryptResources();
            stringDecrypter.init(resourceDecrypter);
            if (stringDecrypter.Method != null)
            {
                staticStringInliner.add(stringDecrypter.Method, (method, gim, args) => {
                    return(stringDecrypter.decrypt((int)args[0]));
                });
                DeobfuscatedFile.stringDecryptersAdded();
            }

            methodsDecrypter.decrypt(resourceDecrypter);

            if (methodsDecrypter.Detected)
            {
                if (!assemblyResolver.Detected)
                {
                    assemblyResolver.find();
                }
                if (!tamperDetection.Detected)
                {
                    tamperDetection.find();
                }
            }
            antiDebugger = new AntiDebugger(module, DeobfuscatedFile, this);
            antiDebugger.find();

            if (options.DecryptConstants)
            {
                constantsDecrypter.init(resourceDecrypter);
                int32ValueInliner = new Int32ValueInliner();
                int32ValueInliner.add(constantsDecrypter.Int32Decrypter, (method, gim, args) => constantsDecrypter.decryptInt32((int)args[0]));
                int64ValueInliner = new Int64ValueInliner();
                int64ValueInliner.add(constantsDecrypter.Int64Decrypter, (method, gim, args) => constantsDecrypter.decryptInt64((int)args[0]));
                singleValueInliner = new SingleValueInliner();
                singleValueInliner.add(constantsDecrypter.SingleDecrypter, (method, gim, args) => constantsDecrypter.decryptSingle((int)args[0]));
                doubleValueInliner = new DoubleValueInliner();
                doubleValueInliner.add(constantsDecrypter.DoubleDecrypter, (method, gim, args) => constantsDecrypter.decryptDouble((int)args[0]));
                addTypeToBeRemoved(constantsDecrypter.Type, "Constants decrypter type");
                addResourceToBeRemoved(constantsDecrypter.Resource, "Encrypted constants");
            }

            addModuleCctorInitCallToBeRemoved(resourceResolver.Method);
            addModuleCctorInitCallToBeRemoved(assemblyResolver.Method);
            addCallToBeRemoved(module.EntryPoint, tamperDetection.Method);
            addModuleCctorInitCallToBeRemoved(tamperDetection.Method);
            addCallToBeRemoved(module.EntryPoint, antiDebugger.Method);
            addModuleCctorInitCallToBeRemoved(antiDebugger.Method);
            addTypeToBeRemoved(resourceResolver.Type, "Resource resolver type");
            addTypeToBeRemoved(assemblyResolver.Type, "Assembly resolver type");
            addTypeToBeRemoved(tamperDetection.Type, "Tamper detection type");
            addTypeToBeRemoved(antiDebugger.Type, "Anti-debugger type");
            addTypeToBeRemoved(methodsDecrypter.Type, "Methods decrypter type");
            addTypesToBeRemoved(methodsDecrypter.DelegateTypes, "Methods decrypter delegate type");
            addResourceToBeRemoved(methodsDecrypter.Resource, "Encrypted methods");

            proxyCallFixer.find();

            dumpEmbeddedAssemblies();
        }