public MethodDefinition deobfuscate(MethodDefinition method)
        {
            MethodDefinition deobfuscatedMethod;

            if (deobfuscated.TryGetValue(method, out deobfuscatedMethod))
            {
                return(deobfuscatedMethod);
            }

            if (method.Body == null || method.Body.Instructions.Count == 0)
            {
                deobfuscated[method] = method;
                return(method);
            }

            deobfuscatedMethod   = DotNetUtils.clone(method);
            deobfuscated[method] = deobfuscatedMethod;

            var blocks = new Blocks(deobfuscatedMethod);

            deobfuscate(blocks);
            IList <Instruction>      allInstructions;
            IList <ExceptionHandler> allExceptionHandlers;

            blocks.getCode(out allInstructions, out allExceptionHandlers);
            DotNetUtils.restoreBody(deobfuscatedMethod, allInstructions, allExceptionHandlers);

            return(deobfuscatedMethod);
        }
Esempio n. 2
0
 public InstructionPatcher(int patchIndex, int afterIndex, Instruction lastInstr)
 {
     this.patchIndex  = patchIndex;
     this.afterIndex  = afterIndex;
     this.lastInstr   = lastInstr;
     this.clonedInstr = new Instr(DotNetUtils.clone(lastInstr));
 }
Esempio n. 3
0
        protected bool inlineLoadMethod(int patchIndex, MethodDefinition methodToInline, Instruction loadInstr, int instrIndex)
        {
            if (!isReturn(methodToInline, instrIndex))
            {
                return(false);
            }

            int methodArgsCount = DotNetUtils.getArgsCount(methodToInline);

            for (int i = 0; i < methodArgsCount; i++)
            {
                block.insert(patchIndex++, Instruction.Create(OpCodes.Pop));
            }

            block.Instructions[patchIndex] = new Instr(DotNetUtils.clone(loadInstr));
            return(true);
        }
Esempio n. 4
0
        protected bool inlineLoadMethod(int patchIndex, MethodDefinition methodToInline, Instruction loadInstr, int instrIndex)
        {
            var instr = DotNetUtils.getInstruction(methodToInline.Body.Instructions, ref instrIndex);

            if (instr == null || instr.OpCode.Code != Code.Ret)
            {
                return(false);
            }

            int methodArgsCount = DotNetUtils.getArgsCount(methodToInline);

            for (int i = 0; i < methodArgsCount; i++)
            {
                block.insert(patchIndex++, Instruction.Create(OpCodes.Pop));
            }

            block.Instructions[patchIndex] = new Instr(DotNetUtils.clone(loadInstr));
            return(true);
        }
Esempio n. 5
0
        protected bool inlineOtherMethod(int patchIndex, MethodDefinition methodToInline, Instruction instr, int instrIndex, int popLastArgs = 0)
        {
            int  loadIndex       = 0;
            int  methodArgsCount = DotNetUtils.getArgsCount(methodToInline);
            bool foundLdarga     = false;

            while (instr != null && loadIndex < methodArgsCount)
            {
                bool isLdarg = true;
                switch (instr.OpCode.Code)
                {
                case Code.Ldarg:
                case Code.Ldarg_S:
                case Code.Ldarg_0:
                case Code.Ldarg_1:
                case Code.Ldarg_2:
                case Code.Ldarg_3:
                    break;

                case Code.Ldarga:
                case Code.Ldarga_S:
                    foundLdarga = true;
                    break;

                default:
                    isLdarg = false;
                    break;
                }
                if (!isLdarg)
                {
                    break;
                }

                if (DotNetUtils.getArgIndex(instr) != loadIndex)
                {
                    return(false);
                }
                loadIndex++;
                instr = DotNetUtils.getInstruction(methodToInline.Body.Instructions, ref instrIndex);
            }
            if (instr == null || loadIndex != methodArgsCount - popLastArgs)
            {
                return(false);
            }

            if (instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt)
            {
                if (foundLdarga)
                {
                    return(false);
                }
                var callInstr    = instr;
                var calledMethod = callInstr.Operand as MethodReference;
                if (calledMethod == null)
                {
                    return(false);
                }

                if (!isCompatibleType(-1, calledMethod.MethodReturnType.ReturnType, methodToInline.MethodReturnType.ReturnType))
                {
                    return(false);
                }

                if (!checkSameMethods(calledMethod, methodToInline, popLastArgs))
                {
                    return(false);
                }

                instr = DotNetUtils.getInstruction(methodToInline.Body.Instructions, ref instrIndex);
                if (instr == null || instr.OpCode.Code != Code.Ret)
                {
                    return(false);
                }

                block.Instructions[patchIndex] = new Instr(DotNetUtils.clone(callInstr));
                return(true);
            }
            else if (instr.OpCode.Code == Code.Newobj)
            {
                if (foundLdarga)
                {
                    return(false);
                }
                var newobjInstr = instr;
                var ctor        = newobjInstr.Operand as MethodReference;
                if (ctor == null)
                {
                    return(false);
                }

                if (!isCompatibleType(-1, ctor.DeclaringType, methodToInline.MethodReturnType.ReturnType))
                {
                    return(false);
                }

                var methodArgs       = DotNetUtils.getArgs(methodToInline);
                var calledMethodArgs = DotNetUtils.getArgs(ctor);
                if (methodArgs.Count + 1 - popLastArgs != calledMethodArgs.Count)
                {
                    return(false);
                }
                for (int i = 1; i < calledMethodArgs.Count; i++)
                {
                    if (!isCompatibleType(i, calledMethodArgs[i], methodArgs[i - 1]))
                    {
                        return(false);
                    }
                }

                instr = DotNetUtils.getInstruction(methodToInline.Body.Instructions, ref instrIndex);
                if (instr == null || instr.OpCode.Code != Code.Ret)
                {
                    return(false);
                }

                block.Instructions[patchIndex] = new Instr(DotNetUtils.clone(newobjInstr));
                return(true);
            }
            else if (instr.OpCode.Code == Code.Ldfld || instr.OpCode.Code == Code.Ldflda ||
                     instr.OpCode.Code == Code.Ldftn || instr.OpCode.Code == Code.Ldvirtftn)
            {
                var ldInstr = instr;
                instr = DotNetUtils.getInstruction(methodToInline.Body.Instructions, ref instrIndex);
                if (instr == null || instr.OpCode.Code != Code.Ret)
                {
                    return(false);
                }

                if (methodArgsCount != 1)
                {
                    return(false);
                }
                block.Instructions[patchIndex] = new Instr(DotNetUtils.clone(ldInstr));
                return(true);
            }

            return(false);
        }