Пример #1
0
        static int findLdStFieldIndex(IList <Instr> instrs, int index)
        {
            int stack = 0;

            for (int i = index; i < instrs.Count; i++)
            {
                var instr = instrs[i];

                if (stack == 0 && (instr.OpCode.Code == Code.Ldfld || instr.OpCode.Code == Code.Ldflda))
                {
                    return(i);
                }
                if (stack == 1 && instr.OpCode.Code == Code.Stfld)
                {
                    return(i);
                }

                int pushes, pops;
                DotNetUtils.calculateStackUsage(instr.Instruction, false, out pushes, out pops);
                stack -= pops;
                if (stack < 0)
                {
                    break;
                }
                stack += pushes;
            }
            throw new ApplicationException("Could not find ldfld/stfld");
        }
Пример #2
0
        void updateStack(Instruction instr)
        {
            int pushes, pops;

            DotNetUtils.calculateStackUsage(instr, false, out pushes, out pops);
            if (pops == -1)
            {
                valueStack.clear();
            }
            else
            {
                valueStack.pop(pops);
                valueStack.push(pushes);
            }
        }
Пример #3
0
        void emulate_Call(Instruction instr, MethodReference method)
        {
            int pushes, pops;

            DotNetUtils.calculateStackUsage(instr, false, out pushes, out pops);
            valueStack.pop(pops);
            if (pushes == 1)
            {
                valueStack.push(getUnknownValue(method.MethodReturnType.ReturnType));
            }
            else
            {
                valueStack.push(pushes);
            }
        }
Пример #4
0
 // May not return all args. The args are returned in reverse order.
 public static PushedArgs getPushedArgInstructions(IList <Instruction> instructions, int index)
 {
     try {
         int pushes, pops;
         DotNetUtils.calculateStackUsage(instructions[index], false, out pushes, out pops);
         if (pops != -1)
         {
             return(getPushedArgInstructions(instructions, index, pops));
         }
     }
     catch (System.NullReferenceException) {
         // Here if eg. invalid metadata token in a call instruction (operand is null)
     }
     return(new PushedArgs(0));
 }
Пример #5
0
        bool emulateToReturn(int index, Instruction lastInstr)
        {
            int pushes, pops;

            DotNetUtils.calculateStackUsage(lastInstr, false, out pushes, out pops);
            for (int i = 0; i < pops; i++)
            {
                instructionEmulator.pop();
            }

            returnValue = null;
            if (pushes != 0)
            {
                returnValue = new UnknownValue();
                instructionEmulator.setProtected(returnValue);
                instructionEmulator.push(returnValue);
            }

            if (!emulateInstructions(ref index, true))
            {
                return(false);
            }
            if (index >= methodToInline.Body.Instructions.Count)
            {
                return(false);
            }
            if (methodToInline.Body.Instructions[index].OpCode.Code != Code.Ret)
            {
                return(false);
            }

            if (returnValue != null)
            {
                if (instructionEmulator.pop() != returnValue)
                {
                    return(false);
                }
            }
            return(instructionEmulator.stackSize() == 0);
        }
Пример #6
0
        // May not return all args. The args are returned in reverse order.
        static PushedArgs getPushedArgInstructions(IList <Instruction> instructions, int index, int numArgs)
        {
            var pushedArgs = new PushedArgs(numArgs);

            Instruction instr;
            int         skipPushes = 0;

            while (index >= 0 && pushedArgs.CanAddMore)
            {
                instr = getPreviousInstruction(instructions, ref index);
                if (instr == null)
                {
                    break;
                }

                int pushes, pops;
                DotNetUtils.calculateStackUsage(instr, false, out pushes, out pops);
                if (pops == -1)
                {
                    break;
                }
                if (instr.OpCode.Code == Code.Dup)
                {
                    pushes = 1;
                    pops   = 0;
                }
                if (pushes > 1)
                {
                    break;
                }

                if (skipPushes > 0)
                {
                    skipPushes -= pushes;
                    if (skipPushes < 0)
                    {
                        break;
                    }
                    skipPushes += pops;
                }
                else
                {
                    if (pushes == 1)
                    {
                        pushedArgs.add(instr);
                    }
                    skipPushes += pops;
                }
            }
            instr = pushedArgs.get(0);
            if (instr != null && instr.OpCode.Code == Code.Dup)
            {
                instr = getPreviousInstruction(instructions, ref index);
                if (instr != null)
                {
                    int pushes, pops;
                    DotNetUtils.calculateStackUsage(instr, false, out pushes, out pops);
                    if (pushes == 1 && pops == 0)
                    {
                        pushedArgs.set(0, instr);
                    }
                }
            }
            pushedArgs.fixDups();

            return(pushedArgs);
        }
Пример #7
0
 static void calculateStackUsage(Instruction instr, bool methodHasReturnValue, out int pushes, out int pops)
 {
     DotNetUtils.calculateStackUsage(instr, false, out pushes, out pops);
 }
Пример #8
0
        bool getArg(MethodReference method, Block block, ref object arg, ref int instrIndex)
        {
            while (true)
            {
                if (instrIndex < 0)
                {
                    // We're here if there were no cflow deobfuscation, or if there are two or
                    // more blocks branching to the decrypter method, or the two blocks can't be
                    // merged because one is outside the exception handler (eg. buggy obfuscator).
                    Log.w("Could not find all arguments to method {0} ({1:X8})",
                          Utils.removeNewlines(method),
                          method.MetadataToken.ToInt32());
                    errors++;
                    return(false);
                }

                var instr = block.Instructions[instrIndex--];
                switch (instr.OpCode.Code)
                {
                case Code.Ldc_I4:
                case Code.Ldc_I8:
                case Code.Ldc_R4:
                case Code.Ldc_R8:
                case Code.Ldstr:
                    arg = instr.Operand;
                    break;

                case Code.Ldc_I4_S:
                    arg = (int)(sbyte)instr.Operand;
                    break;

                case Code.Ldc_I4_0: arg = 0; break;

                case Code.Ldc_I4_1: arg = 1; break;

                case Code.Ldc_I4_2: arg = 2; break;

                case Code.Ldc_I4_3: arg = 3; break;

                case Code.Ldc_I4_4: arg = 4; break;

                case Code.Ldc_I4_5: arg = 5; break;

                case Code.Ldc_I4_6: arg = 6; break;

                case Code.Ldc_I4_7: arg = 7; break;

                case Code.Ldc_I4_8: arg = 8; break;

                case Code.Ldc_I4_M1: arg = -1; break;

                case Code.Ldnull:       arg = null; break;

                case Code.Nop:
                    continue;

                case Code.Ldloc:
                case Code.Ldloc_S:
                case Code.Ldloc_0:
                case Code.Ldloc_1:
                case Code.Ldloc_2:
                case Code.Ldloc_3:
                    getLocalVariableValue(Instr.getLocalVar(theMethod.Body.Variables, instr), out arg);
                    break;

                case Code.Ldfld:
                case Code.Ldsfld:
                    arg = instr.Operand;
                    break;

                default:
                    int pushes, pops;
                    DotNetUtils.calculateStackUsage(instr.Instruction, false, out pushes, out pops);
                    if (!useUnknownArgs || pushes != 1)
                    {
                        Log.w("Could not find all arguments to method {0} ({1:X8}), instr: {2}",
                              Utils.removeNewlines(method),
                              method.MetadataToken.ToInt32(),
                              instr);
                        errors++;
                        return(false);
                    }

                    for (int i = 0; i < pops; i++)
                    {
                        if (!getArg(method, block, ref arg, ref instrIndex))
                        {
                            return(false);
                        }
                    }
                    arg = null;
                    break;
                }
                break;
            }

            return(true);
        }