Пример #1
0
        void deobfuscateMethod(MethodDef method)
        {
            if (!method.IsStatic || method.Body == null)
            {
                return;
            }

            bool fixReturnType = isUnknownType(method.MethodSig.GetRetType());

            argInfos.Clear();
            foreach (var arg in method.Parameters)
            {
                if (arg.IsHiddenThisParameter)
                {
                    continue;
                }
                if (!isUnknownType(arg))
                {
                    continue;
                }
                argInfos[arg] = new TypeInfo <Parameter>(arg);
            }
            if (argInfos.Count == 0 && !fixReturnType)
            {
                return;
            }

            var        methodParams = method.Parameters;
            PushedArgs pushedArgs;
            var        instructions = method.Body.Instructions;

            for (int i = 0; i < instructions.Count; i++)
            {
                var instr = instructions[i];
                switch (instr.OpCode.Code)
                {
                case Code.Ret:
                    if (!fixReturnType)
                    {
                        break;
                    }
                    bool wasNewobj;
                    var  type = getLoadedType(method, method, instructions, i, out wasNewobj);
                    if (type == null)
                    {
                        break;
                    }
                    methodReturnInfo.add(type);
                    break;

                case Code.Call:
                case Code.Calli:
                case Code.Callvirt:
                case Code.Newobj:
                    pushedArgs = MethodStack.getPushedArgInstructions(instructions, i);
                    var calledMethod = instr.Operand as IMethod;
                    if (calledMethod == null)
                    {
                        break;
                    }
                    var calledMethodParams = DotNetUtils.getArgs(calledMethod);
                    for (int j = 0; j < pushedArgs.NumValidArgs; j++)
                    {
                        int calledMethodParamIndex = calledMethodParams.Count - j - 1;
                        var ldInstr = pushedArgs.getEnd(j);
                        switch (ldInstr.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:
                            addMethodArgType(method, getParameter(methodParams, ldInstr), DotNetUtils.getArg(calledMethodParams, calledMethodParamIndex));
                            break;

                        default:
                            break;
                        }
                    }
                    break;

                case Code.Castclass:
                    pushedArgs = MethodStack.getPushedArgInstructions(instructions, i);
                    if (pushedArgs.NumValidArgs < 1)
                    {
                        break;
                    }
                    addMethodArgType(method, getParameter(methodParams, pushedArgs.getEnd(0)), instr.Operand as ITypeDefOrRef);
                    break;

                case Code.Stloc:
                case Code.Stloc_S:
                case Code.Stloc_0:
                case Code.Stloc_1:
                case Code.Stloc_2:
                case Code.Stloc_3:
                    pushedArgs = MethodStack.getPushedArgInstructions(instructions, i);
                    if (pushedArgs.NumValidArgs < 1)
                    {
                        break;
                    }
                    addMethodArgType(method, getParameter(methodParams, pushedArgs.getEnd(0)), instr.GetLocal(method.Body.Variables));
                    break;

                case Code.Stsfld:
                    pushedArgs = MethodStack.getPushedArgInstructions(instructions, i);
                    if (pushedArgs.NumValidArgs < 1)
                    {
                        break;
                    }
                    addMethodArgType(method, getParameter(methodParams, pushedArgs.getEnd(0)), instr.Operand as IField);
                    break;

                case Code.Stfld:
                    pushedArgs = MethodStack.getPushedArgInstructions(instructions, i);
                    if (pushedArgs.NumValidArgs >= 1)
                    {
                        var field = instr.Operand as IField;
                        addMethodArgType(method, getParameter(methodParams, pushedArgs.getEnd(0)), field);
                        if (pushedArgs.NumValidArgs >= 2 && field != null)
                        {
                            addMethodArgType(method, getParameter(methodParams, pushedArgs.getEnd(1)), field.DeclaringType);
                        }
                    }
                    break;

                case Code.Ldfld:
                case Code.Ldflda:
                    pushedArgs = MethodStack.getPushedArgInstructions(instructions, i);
                    if (pushedArgs.NumValidArgs < 1)
                    {
                        break;
                    }
                    addMethodArgType(method, getParameter(methodParams, pushedArgs.getEnd(0)), instr.Operand as IField);
                    break;

                //TODO: For better results, these should be checked:
                case Code.Starg:
                case Code.Starg_S:

                case Code.Ldelema:
                case Code.Ldelem:
                case Code.Ldelem_I:
                case Code.Ldelem_I1:
                case Code.Ldelem_I2:
                case Code.Ldelem_I4:
                case Code.Ldelem_I8:
                case Code.Ldelem_R4:
                case Code.Ldelem_R8:
                case Code.Ldelem_Ref:
                case Code.Ldelem_U1:
                case Code.Ldelem_U2:
                case Code.Ldelem_U4:

                case Code.Ldind_I:
                case Code.Ldind_I1:
                case Code.Ldind_I2:
                case Code.Ldind_I4:
                case Code.Ldind_I8:
                case Code.Ldind_R4:
                case Code.Ldind_R8:
                case Code.Ldind_Ref:
                case Code.Ldind_U1:
                case Code.Ldind_U2:
                case Code.Ldind_U4:

                case Code.Ldobj:

                case Code.Stelem:
                case Code.Stelem_I:
                case Code.Stelem_I1:
                case Code.Stelem_I2:
                case Code.Stelem_I4:
                case Code.Stelem_I8:
                case Code.Stelem_R4:
                case Code.Stelem_R8:
                case Code.Stelem_Ref:

                case Code.Stind_I:
                case Code.Stind_I1:
                case Code.Stind_I2:
                case Code.Stind_I4:
                case Code.Stind_I8:
                case Code.Stind_R4:
                case Code.Stind_R8:
                case Code.Stind_Ref:

                case Code.Stobj:
                default:
                    break;
                }
            }
        }