public IEnumerable<FieldDef> cleanUp()
        {
            var removedFields = new List<FieldDef>();
            var moduleCctor = DotNetUtils.getModuleTypeCctor(module);
            if (moduleCctor == null)
                return removedFields;
            var moduleCctorBlocks = new Blocks(moduleCctor);

            var keep = findFieldsToKeep();
            foreach (var fieldInfo in fieldToInfo.getValues()) {
                if (keep.ContainsKey(fieldInfo))
                    continue;
                if (removeInitCode(moduleCctorBlocks, fieldInfo)) {
                    removedFields.Add(fieldInfo.field);
                    removedFields.Add(fieldInfo.arrayInitField);
                }
                fieldInfo.arrayInitField.InitialValue = new byte[1];
                fieldInfo.arrayInitField.FieldSig.Type = module.CorLibTypes.Byte;
                fieldInfo.arrayInitField.RVA = 0;
            }

            IList<Instruction> allInstructions;
            IList<ExceptionHandler> allExceptionHandlers;
            moduleCctorBlocks.getCode(out allInstructions, out allExceptionHandlers);
            DotNetUtils.restoreBody(moduleCctorBlocks.Method, allInstructions, allExceptionHandlers);
            return removedFields;
        }
Ejemplo n.º 2
0
        void deobfuscate(MethodDefinition method, string msg, Action<Blocks> handler)
        {
            if (savedMethodBodies != null)
                savedMethodBodies.save(method);

            Log.v("{0}: {1} ({2:X8})", msg, Utils.removeNewlines(method), method.MetadataToken.ToUInt32());
            Log.indent();

            if (hasNonEmptyBody(method)) {
                var blocks = new Blocks(method);

                handler(blocks);

                IList<Instruction> allInstructions;
                IList<ExceptionHandler> allExceptionHandlers;
                blocks.getCode(out allInstructions, out allExceptionHandlers);
                DotNetUtils.restoreBody(method, allInstructions, allExceptionHandlers);
            }

            Log.deIndent();
        }
Ejemplo n.º 3
0
        void deobfuscate(MethodDefinition method, BlocksCflowDeobfuscator cflowDeobfuscator, MethodPrinter methodPrinter)
        {
            if (!hasNonEmptyBody(method))
                return;

            var blocks = new Blocks(method);
            int numRemovedLocals = 0;
            int oldNumInstructions = method.Body.Instructions.Count;

            deob.deobfuscateMethodBegin(blocks);
            if (options.ControlFlowDeobfuscation) {
                cflowDeobfuscator.init(blocks);
                cflowDeobfuscator.deobfuscate();
            }

            if (deob.deobfuscateOther(blocks) && options.ControlFlowDeobfuscation)
                cflowDeobfuscator.deobfuscate();

            if (options.ControlFlowDeobfuscation) {
                numRemovedLocals = blocks.optimizeLocals();
                blocks.repartitionBlocks();
            }

            deobfuscateStrings(blocks);
            deob.deobfuscateMethodEnd(blocks);

            IList<Instruction> allInstructions;
            IList<ExceptionHandler> allExceptionHandlers;
            blocks.getCode(out allInstructions, out allExceptionHandlers);
            DotNetUtils.restoreBody(method, allInstructions, allExceptionHandlers);

            if (numRemovedLocals > 0)
                Log.v("Removed {0} unused local(s)", numRemovedLocals);
            int numRemovedInstructions = oldNumInstructions - method.Body.Instructions.Count;
            if (numRemovedInstructions > 0)
                Log.v("Removed {0} dead instruction(s)", numRemovedInstructions);

            const Log.LogLevel dumpLogLevel = Log.LogLevel.veryverbose;
            if (Log.isAtLeast(dumpLogLevel)) {
                Log.log(dumpLogLevel, "Deobfuscated code:");
                Log.indent();
                methodPrinter.print(dumpLogLevel, allInstructions, allExceptionHandlers);
                Log.deIndent();
            }
        }
Ejemplo n.º 4
0
        public void createMethod(MethodBase realMethod)
        {
            if (realMethodToNewMethod.ContainsKey(realMethod))
                return;
            var newMethodInfo = new NewMethodInfo(realMethod, newMethodInfos.Count, getDelegateMethodName(realMethod), getDelegateMethodName(realMethod));
            newMethodInfos.Add(newMethodInfo);
            delegateNameToNewMethodInfo[newMethodInfo.delegateMethodName] = newMethodInfo;
            delegateNameToNewMethodInfo[newMethodInfo.rewrittenMethodName] = newMethodInfo;
            realMethodToNewMethod[realMethod] = newMethodInfo;

            var moduleInfo = Resolver.loadAssembly(realMethod.Module);
            var methodInfo = moduleInfo.getMethod(realMethod);
            if (!methodInfo.hasInstructions())
                throw new ApplicationException(string.Format("Method {0} ({1:X8}) has no body", methodInfo.methodDef, methodInfo.methodDef.MDToken.Raw));

            var codeGenerator = new CodeGenerator(this, newMethodInfo.delegateMethodName);
            codeGenerator.setMethodInfo(methodInfo);
            newMethodInfo.delegateType = codeGenerator.DelegateType;

            var blocks = new Blocks(methodInfo.methodDef);
            foreach (var block in blocks.MethodBlocks.getAllBlocks())
                update(block, newMethodInfo);

            IList<Instruction> allInstructions;
            IList<ExceptionHandler> allExceptionHandlers;
            blocks.getCode(out allInstructions, out allExceptionHandlers);
            newMethodInfo.delegateInstance = codeGenerator.generate(allInstructions, allExceptionHandlers);
        }
Ejemplo n.º 5
0
        void deobfuscate(MethodDef method, string msg, Action<Blocks> handler)
        {
            if (savedMethodBodies != null)
                savedMethodBodies.save(method);

            Logger.v("{0}: {1} ({2:X8})", msg, Utils.removeNewlines(method), method.MDToken.ToUInt32());
            Logger.Instance.indent();

            if (hasNonEmptyBody(method)) {
                try {
                    var blocks = new Blocks(method);

                    handler(blocks);

                    IList<Instruction> allInstructions;
                    IList<ExceptionHandler> allExceptionHandlers;
                    blocks.getCode(out allInstructions, out allExceptionHandlers);
                    DotNetUtils.restoreBody(method, allInstructions, allExceptionHandlers);
                }
                catch {
                    Logger.v("Could not deobfuscate {0:X8}", method.MDToken.ToInt32());
                }
            }

            Logger.Instance.deIndent();
        }
Ejemplo n.º 6
0
        void deobfuscate(MethodDef method, BlocksCflowDeobfuscator cflowDeobfuscator, MethodPrinter methodPrinter, bool isVerbose, bool isVV)
        {
            if (!hasNonEmptyBody(method))
                return;

            var blocks = new Blocks(method);
            int numRemovedLocals = 0;
            int oldNumInstructions = method.Body.Instructions.Count;

            deob.deobfuscateMethodBegin(blocks);
            if (options.ControlFlowDeobfuscation) {
                cflowDeobfuscator.init(blocks);
                cflowDeobfuscator.deobfuscate();
            }

            if (deob.deobfuscateOther(blocks) && options.ControlFlowDeobfuscation)
                cflowDeobfuscator.deobfuscate();

            if (options.ControlFlowDeobfuscation) {
                if (CanOptimizeLocals())
                    numRemovedLocals = blocks.optimizeLocals();
                blocks.repartitionBlocks();
            }

            deobfuscateStrings(blocks);
            deob.deobfuscateMethodEnd(blocks);

            IList<Instruction> allInstructions;
            IList<ExceptionHandler> allExceptionHandlers;
            blocks.getCode(out allInstructions, out allExceptionHandlers);
            DotNetUtils.restoreBody(method, allInstructions, allExceptionHandlers);

            if (isVerbose && numRemovedLocals > 0)
                Logger.v("Removed {0} unused local(s)", numRemovedLocals);
            int numRemovedInstructions = oldNumInstructions - method.Body.Instructions.Count;
            if (isVerbose && numRemovedInstructions > 0)
                Logger.v("Removed {0} dead instruction(s)", numRemovedInstructions);

            if (isVV) {
                Logger.log(LoggerEvent.VeryVerbose, "Deobfuscated code:");
                Logger.Instance.indent();
                methodPrinter.print(LoggerEvent.VeryVerbose, allInstructions, allExceptionHandlers);
                Logger.Instance.deIndent();
            }
        }
Ejemplo n.º 7
0
        void deobfuscateMethods()
        {
            if (savedMethodBodies != null) {
                savedMethodBodies.restoreAll();
                savedMethodBodies = null;
            }
            deob.DeobfuscatedFile = null;

            Log.v("Deobfuscating methods");
            foreach (var method in allMethods) {
                Log.v("Deobfuscating {0} ({1:X8})", method, method.MetadataToken.ToUInt32());
                Log.indent();

                if (hasNonEmptyBody(method)) {
                    var blocks = new Blocks(method);

                    deob.deobfuscateMethodBegin(blocks);
                    if (options.ControlFlowDeobfuscation) {
                        int numDeadBlocks = blocks.deobfuscate();
                        if (numDeadBlocks > 0)
                            Log.v("Removed {0} dead block(s)", numDeadBlocks);
                    }
                    deobfuscateStrings(blocks);
                    deob.deobfuscateMethodEnd(blocks);
                    if (options.ControlFlowDeobfuscation)
                        blocks.deobfuscateLeaveObfuscation();

                    IList<Instruction> allInstructions;
                    IList<ExceptionHandler> allExceptionHandlers;
                    blocks.getCode(out allInstructions, out allExceptionHandlers);
                    DotNetUtils.restoreBody(method, allInstructions, allExceptionHandlers);
                }

                removeNoInliningAttribute(method);

                Log.deIndent();
            }
        }
Ejemplo n.º 8
0
        void stringDecrypterBugWorkaround()
        {
            // There's a bug in Eazfuscator.NET when the VM and string encryption features are
            // enabled. The string decrypter's initialization code checks to make sure it's not
            // called by eg. a dynamic method. When it's called from the VM code, it is
            // called by MethodBase.Invoke() and the string decrypter antis set in causing it
            // to fail.
            // One way to work around this is to make sure the string decrypter has been called
            // once. That way, any VM code calling it won't trigger a failure.
            // We can put this code in <Module>::.cctor() since it gets executed before any
            // other code.
            // Note that we can't call the string decrypter from <Module>::.cctor() since
            // its DeclaringType property will return null (since it's the global type). We
            // must call another created class which calls the string decrypter.

            // You must use --dont-rename --keep-types --preserve-tokens and decrypt strings
            if (!Operations.KeepObfuscatorTypes || Operations.DecryptStrings == OpDecryptString.None ||
                (Operations.RenamerFlags & (RenamerFlags.RenameNamespaces | RenamerFlags.RenameTypes)) != 0)
                return;

            if (stringDecrypter.ValidStringDecrypterValue == null)
                return;

            var newType = module.UpdateRowId(new TypeDefUser(Guid.NewGuid().ToString("B"), module.CorLibTypes.Object.TypeDefOrRef));
            module.Types.Add(newType);
            var newMethod = module.UpdateRowId(new MethodDefUser("x", MethodSig.CreateStatic(module.CorLibTypes.Void), 0, MethodAttributes.Static | MethodAttributes.HideBySig));
            newType.Methods.Add(newMethod);
            newMethod.Body = new CilBody();
            newMethod.Body.MaxStack = 1;
            newMethod.Body.Instructions.Add(Instruction.CreateLdcI4(stringDecrypter.ValidStringDecrypterValue.Value));
            newMethod.Body.Instructions.Add(OpCodes.Call.ToInstruction(stringDecrypter.Method));
            newMethod.Body.Instructions.Add(OpCodes.Pop.ToInstruction());
            newMethod.Body.Instructions.Add(OpCodes.Ret.ToInstruction());

            var cctor = module.GlobalType.FindOrCreateStaticConstructor();
            var blocks = new Blocks(cctor);
            var block = blocks.MethodBlocks.getAllBlocks()[0];
            block.insert(0, OpCodes.Call.ToInstruction(newMethod));

            IList<Instruction> allInstructions;
            IList<ExceptionHandler> allExceptionHandlers;
            blocks.getCode(out allInstructions, out allExceptionHandlers);
            DotNetUtils.restoreBody(cctor, allInstructions, allExceptionHandlers);
        }
Ejemplo n.º 9
0
        void deobfuscateMethods()
        {
            if (savedMethodBodies != null) {
                savedMethodBodies.restoreAll();
                savedMethodBodies = null;
            }
            deob.DeobfuscatedFile = null;

            Log.v("Deobfuscating methods");
            var methodPrinter = new MethodPrinter();
            var cflowDeobfuscator = new BlocksCflowDeobfuscator { InlineMethods = deob.CanInlineMethods };
            foreach (var method in allMethods) {
                Log.v("Deobfuscating {0} ({1:X8})", method, method.MetadataToken.ToUInt32());
                Log.indent();

                if (hasNonEmptyBody(method)) {
                    var blocks = new Blocks(method);
                    int numRemovedLocals = 0;
                    int oldNumInstructions = method.Body.Instructions.Count;

                    deob.deobfuscateMethodBegin(blocks);
                    if (options.ControlFlowDeobfuscation) {
                        cflowDeobfuscator.init(blocks);
                        cflowDeobfuscator.deobfuscate();
                    }

                    if (deob.deobfuscateOther(blocks) && options.ControlFlowDeobfuscation)
                        cflowDeobfuscator.deobfuscate();

                    if (options.ControlFlowDeobfuscation) {
                        numRemovedLocals = blocks.optimizeLocals();
                        blocks.repartitionBlocks();
                    }

                    deobfuscateStrings(blocks);
                    deob.deobfuscateMethodEnd(blocks);

                    IList<Instruction> allInstructions;
                    IList<ExceptionHandler> allExceptionHandlers;
                    blocks.getCode(out allInstructions, out allExceptionHandlers);
                    DotNetUtils.restoreBody(method, allInstructions, allExceptionHandlers);

                    if (numRemovedLocals > 0)
                        Log.v("Removed {0} unused local(s)", numRemovedLocals);
                    int numRemovedInstructions = oldNumInstructions - method.Body.Instructions.Count;
                    if (numRemovedInstructions > 0)
                        Log.v("Removed {0} dead instruction(s)", numRemovedInstructions);

                    const Log.LogLevel dumpLogLevel = Log.LogLevel.veryverbose;
                    if (Log.isAtLeast(dumpLogLevel)) {
                        Log.log(dumpLogLevel, "Deobfuscated code:");
                        Log.indent();
                        methodPrinter.print(dumpLogLevel, method, allInstructions, allExceptionHandlers);
                        Log.deIndent();
                    }
                }

                removeNoInliningAttribute(method);

                Log.deIndent();
            }
        }