Ejemplo n.º 1
0
        private int?CalculateSwitchCaseIndex(Block block, SwitchData switchData, int key)
        {
            if (switchData is NativeSwitchData)
            {
                _instructionEmulator.Push(new Int32Value(key));
                _instructionEmulator.Emulate(block.Instructions, block.SwitchData.IsKeyHardCoded ? 2 : 1, block.Instructions.Count - 1);

                var popValue = _instructionEmulator.Peek();
                _instructionEmulator.Pop();
                return(((Int32Value)popValue).Value);
            }
            if (switchData is NormalSwitchData)
            {
                var normalSwitchData = (NormalSwitchData)switchData;
                return(key % normalSwitchData.DivisionKey);
            }
            return(null);
        }
Ejemplo n.º 2
0
        public int emulate(int val, out int locValue)
        {
            locValue = 0;
            //we take the value of the arg as a parameter to pass along to the switch block
            var ins = new InstructionEmulator(blocks.Method);

            ins.Initialize(blocks.Method);
            if (native)
            {
                var test = x86emulate(switchBlock.FirstInstr.Operand as MethodDef, new[] { val });
                ins.Push(new Int32Value(test));
                //emulates the block however we dont emulate all the block
                ins.Emulate(switchBlock.Instructions, 1, switchBlock.Instructions.Count - 1);
                //we now get the local value this will contain the num value used to work out the next arg in the next case
                if (!isolder)
                {
                    locValue = (ins.GetLocal(localSwitch) as Int32Value).Value;
                }
            }
            else
            {
                ins.Push(new Int32Value(val));
                //emulates the block however we dont emulate all the block
                ins.Emulate(switchBlock.Instructions, 0, switchBlock.Instructions.Count - 1);
                //we now get the local value this will contain the num value used to work out the next arg in the next case
                if (!isolder)
                {
                    locValue = (ins.GetLocal(localSwitch) as Int32Value).Value;
                }
            }
            //we use de4dots instructionEmulator to emulate the block
            //we push the arg value to the stack

            //we peek at the stack value and this is the next case so we return this to continue

            var caseValue = ins.Peek() as Int32Value;

            return(caseValue.Value);
        }
Ejemplo n.º 3
0
        private int EmulateManagedMethod(MethodDef method, int startIndex, int endIndex,
                                         params Tuple <Parameter, int>[] parameters)
        {
            _instructionEmulator.Initialize(method, false);
            foreach (var parameter in parameters)
            {
                _instructionEmulator.SetArg(parameter.Item1, new Int32Value(parameter.Item2));
            }

            for (var i = startIndex; i < endIndex; i++)
            {
                _instructionEmulator.Emulate(method.Body.Instructions[i]);
            }

            return(((Int32Value)_instructionEmulator.Pop()).Value);
        }
Ejemplo n.º 4
0
            uint CalculateMagic(uint input)
            {
                instrEmulator.Initialize(method, method.Parameters, locals, method.Body.InitLocals, false);
                instrEmulator.SetLocal(emuLocal, new Int32Value((int)input));

                foreach (var instr in instructions)
                {
                    instrEmulator.Emulate(instr);
                }

                var tos = instrEmulator.Pop() as Int32Value;

                if (tos == null || !tos.AllBitsValid())
                {
                    throw new ApplicationException("Couldn't calculate magic value");
                }
                return((uint)tos.Value);
            }
 int GetOffset(int offset)
 {
     if (OffsetCalcInstructions == null || OffsetCalcInstructions.Count == 0)
     {
         return(offset);
     }
     if (dummyMethod == null)
     {
         dummyMethod      = new MethodDefUser();
         dummyMethod.Body = new CilBody();
     }
     emulator.Initialize(dummyMethod);
     emulator.Push(new Int32Value(offset));
     foreach (var instr in OffsetCalcInstructions)
     {
         emulator.Emulate(instr);
     }
     return(((Int32Value)emulator.Pop()).Value);
 }
        public static int GetResult(int num, MethodDef targetMd)
        {
            InstructionEmulator em = new InstructionEmulator();

            MethodDefUser dummy_method = new MethodDefUser();

            dummy_method.Body = new dnlib.DotNet.Emit.CilBody();
            em.Initialize(dummy_method);

            List <Instruction> emuTargets = new List <Instruction>();

            foreach (Instruction inst in targetMd.Body.Instructions)
            {
                if (inst.OpCode == OpCodes.Stfld || inst.OpCode == OpCodes.Ldarg_0 || inst.OpCode == OpCodes.Call || inst.OpCode == OpCodes.Ret)
                {
                    continue;
                }

                if (inst.OpCode == OpCodes.Ldarg_1)
                {
                    emuTargets.Add(Instruction.Create(OpCodes.Ldc_I4, num));
                }
                else if (inst.OpCode == OpCodes.Ldarg)
                {
                    if (((Parameter)inst.Operand).Type.FullName == typeof(System.Int32).FullName && ((Parameter)inst.Operand).Index == 0x1)
                    {
                        emuTargets.Add(Instruction.Create(OpCodes.Ldc_I4, num));
                    }
                }
                else
                {
                    emuTargets.Add(inst);
                }
            }

            foreach (Instruction inst in emuTargets)
            {
                em.Emulate(inst);
            }
            var x = (Int32Value)em.Pop();

            return(x.Value.GetHashCode());
        }
            public bool Create()
            {
                int    arrayIndex;
                Value  array;
                object value;

                while (true)
                {
                    var instr = method.Body.Instructions[index];
                    switch (instr.OpCode.Code)
                    {
                    case Code.Ret:
                        return(true);

                    case Code.Newarr:
                        var arrayType  = (ITypeDefOrRef)instr.Operand;
                        int arrayCount = ((Int32Value)emulator.Pop()).Value;
                        if (arrayType.FullName == "System.Char")
                        {
                            emulator.Push(new UserValue(new char[arrayCount]));
                        }
                        else
                        {
                            emulator.Push(new UnknownValue());
                        }
                        break;

                    case Code.Call:
                    case Code.Callvirt:
                        if (!DoCall(instr))
                        {
                            return(false);
                        }
                        break;

                    case Code.Ldelem_U1:
                        arrayIndex = ((Int32Value)emulator.Pop()).Value;
                        array      = (Value)emulator.Pop();
                        if (array is UserValue)
                        {
                            emulator.Push(new Int32Value(((byte[])((UserValue)array).obj)[arrayIndex]));
                        }
                        else
                        {
                            emulator.Push(Int32Value.CreateUnknownUInt8());
                        }
                        break;

                    case Code.Stelem_I1:
                        value      = emulator.Pop();
                        arrayIndex = ((Int32Value)emulator.Pop()).Value;
                        array      = (Value)emulator.Pop();
                        if (array is UserValue)
                        {
                            ((byte[])((UserValue)array).obj)[arrayIndex] = (byte)((Int32Value)value).Value;
                        }
                        break;

                    case Code.Stelem_I2:
                        value      = emulator.Pop();
                        arrayIndex = ((Int32Value)emulator.Pop()).Value;
                        array      = (Value)emulator.Pop();
                        if (array is UserValue)
                        {
                            ((char[])((UserValue)array).obj)[arrayIndex] = (char)((Int32Value)value).Value;
                        }
                        break;

                    case Code.Ldelem_Ref:
                        arrayIndex = ((Int32Value)emulator.Pop()).Value;
                        array      = (Value)emulator.Pop();
                        var userValue = array as UserValue;
                        if (userValue != null && userValue.obj is string[])
                        {
                            emulator.Push(new StringValue(((string[])userValue.obj)[arrayIndex]));
                        }
                        else
                        {
                            emulator.Push(new UnknownValue());
                        }
                        break;

                    case Code.Ldsfld:
                        emulator.Push(new UserValue((IField)instr.Operand));
                        break;

                    default:
                        emulator.Emulate(instr);
                        break;
                    }

                    index++;
                }
            }
Ejemplo n.º 8
0
        bool Cleaner()
        {
            bool         modified  = false;
            List <Block> allblocks = new List <Block>();

            foreach (var block in allBlocks)
            {
                if (block.FallThrough == switchBlock)
                {
                    allblocks.Add(block);
                }
            }
            List <Block> targetBlocks = new List <Block>();

            targetBlocks = switchBlock.Targets;
            foreach (Block block in allblocks)
            {
                if (block.LastInstr.IsLdcI4())
                {
                    int val1 = block.LastInstr.GetLdcI4Value();
                    ins.Push(new Int32Value(val1));
                    int nextCase = emulateCase(out int localValue);
                    if (Program.veryVerbose)
                    {
                        Console.ForegroundColor = ConsoleColor.Cyan;
                        Console.Write(nextCase + ",");
                        Console.ForegroundColor = ConsoleColor.Green;
                    }

                    block.ReplaceLastNonBranchWithBranch(0, targetBlocks[nextCase]);
                    replace(targetBlocks[nextCase], localValue);

                    block.Instructions.Add(new Instr(new Instruction(OpCodes.Pop)));
                    modified = true;
                }
                else if (isXor(block))
                {
                    ins.Emulate(block.Instructions, block.Instructions.Count - 5, block.Instructions.Count);
                    Int32Value val1 = (Int32Value)ins.Pop();
                    ins.Push(val1);
                    int nextCase = emulateCase(out int localValue);
                    if (Program.veryVerbose)
                    {
                        Console.ForegroundColor = ConsoleColor.Cyan;
                        Console.Write(nextCase + ",");
                        Console.ForegroundColor = ConsoleColor.Green;
                    }
                    block.ReplaceLastNonBranchWithBranch(0, targetBlocks[nextCase]);
                    replace(targetBlocks[nextCase], localValue);

                    block.Instructions.Add(new Instr(new Instruction(OpCodes.Pop)));
                    modified = true;
                }
                else if (block.Sources.Count == 2 && block.Instructions.Count == 1)
                {
                    var sources = new List <Block>(block.Sources);
                    foreach (Block source in sources)
                    {
                        if (source.FirstInstr.IsLdcI4())
                        {
                            int val1 = source.FirstInstr.GetLdcI4Value();
                            ins.Push(new Int32Value(val1));
                            int nextCase = emulateCase(out int localValue);
                            if (Program.veryVerbose)
                            {
                                Console.ForegroundColor = ConsoleColor.Cyan;
                                if (source == sources[0])
                                {
                                    Console.Write("True: " + nextCase + ",");
                                }
                                else
                                {
                                    Console.Write("False: " + nextCase + ",");
                                }
                                Console.ForegroundColor = ConsoleColor.Green;
                            }
                            source.ReplaceLastNonBranchWithBranch(0, targetBlocks[nextCase]);
                            replace(targetBlocks[nextCase], localValue);

                            source.Instructions[1] = (new Instr(new Instruction(OpCodes.Pop)));
                            modified = true;
                        }
                    }
                }
                else if (block.LastInstr.OpCode == OpCodes.Xor)
                {
                    if (block.Instructions[block.Instructions.Count - 2].OpCode == OpCodes.Mul)
                    {
                        var instr = block.Instructions;

                        int l = instr.Count;
                        if (!(instr[l - 4].IsLdcI4()))
                        {
                            continue;
                        }
                        var sources = new List <Block>(block.Sources);
                        foreach (Block source in sources)
                        {
                            if (source.FirstInstr.IsLdcI4())
                            {
                                int val1 = source.FirstInstr.GetLdcI4Value();
                                try
                                {
                                    instr[l - 5] = new Instr(new Instruction(OpCodes.Ldc_I4, val1));
                                }
                                catch
                                {
                                    instr.Insert(l - 4, new Instr(new Instruction(OpCodes.Ldc_I4, val1)));
                                    l++;
                                }

                                ins.Emulate(instr, l - 5, l);

                                int nextCase = emulateCase(out int localValue);
                                if (Program.veryVerbose)
                                {
                                    Console.ForegroundColor = ConsoleColor.Cyan;
                                    if (source == sources[0])
                                    {
                                        Console.Write("True: " + nextCase + ",");
                                    }
                                    else
                                    {
                                        Console.Write("False: " + nextCase + ",");
                                    }
                                    Console.ForegroundColor = ConsoleColor.Green;
                                }
                                source.ReplaceLastNonBranchWithBranch(0, targetBlocks[nextCase]);
                                replace(targetBlocks[nextCase], localValue);
                                try
                                {
                                    source.Instructions[1] = (new Instr(new Instruction(OpCodes.Pop)));
                                }
                                catch
                                {
                                    source.Instructions.Add((new Instr(new Instruction(OpCodes.Pop))));
                                }

                                modified = true;
                            }
                        }
                    }
                }
            }

            return(modified);
        }
Ejemplo n.º 9
0
        bool EmulateDynocode(InstructionEmulator emu, ref int index)
        {
            var instrs = stringMethod.Body.Instructions;
            var instr  = instrs[index];

            var ctor = instr.Operand as MethodDef;

            if (ctor == null || ctor.MethodSig.GetParamCount() != 1 || ctor.MethodSig.Params[0].ElementType != ElementType.I4)
            {
                return(false);
            }

            if (index + 4 >= instrs.Count)
            {
                return(false);
            }
            var ldloc = instrs[index + 3];
            var stfld = instrs[index + 4];

            if (!ldloc.IsLdloc() || stfld.OpCode.Code != Code.Stfld)
            {
                return(false);
            }
            var enumerableField = stfld.Operand as FieldDef;

            if (enumerableField == null)
            {
                return(false);
            }

            var initValue = emu.GetLocal(ldloc.GetLocal(stringMethod.Body.Variables)) as Int32Value;

            if (initValue == null || !initValue.AllBitsValid())
            {
                return(false);
            }

            int leaveIndex = FindLeave(instrs, index);

            if (leaveIndex < 0)
            {
                return(false);
            }
            var afterLoop = instrs[leaveIndex].Operand as Instruction;

            if (afterLoop == null)
            {
                return(false);
            }
            int newIndex  = instrs.IndexOf(afterLoop);
            var loopLocal = GetDCLoopLocal(index, newIndex);

            if (loopLocal == null)
            {
                return(false);
            }
            var initValue2 = emu.GetLocal(loopLocal) as Int32Value;

            if (initValue2 == null || !initValue2.AllBitsValid())
            {
                return(false);
            }

            int loopStart = GetIndexOfCall(instrs, index, leaveIndex, "System.Int32", "()");
            int loopEnd   = GetIndexOfCall(instrs, loopStart, leaveIndex, "System.Boolean", "()");

            if (loopStart < 0 || loopEnd < 0)
            {
                return(false);
            }
            loopStart++;
            loopEnd--;

            dynocode.Initialize(module);
            var ctorArg = emu.Pop() as Int32Value;

            if (ctorArg == null || !ctorArg.AllBitsValid())
            {
                return(false);
            }
            dynocode.CreateEnumerable(ctor, new object[] { ctorArg.Value });
            dynocode.WriteEnumerableField(enumerableField.MDToken.ToUInt32(), initValue.Value);
            dynocode.CreateEnumerator();
            foreach (var val in dynocode)
            {
                emu.Push(new Int32Value(val));
                for (int i = loopStart; i < loopEnd; i++)
                {
                    emu.Emulate(instrs[i]);
                }
            }

            index = newIndex - 1;
            return(true);
        }
Ejemplo n.º 10
0
        bool FindInts(int index)
        {
            if (index < 0)
            {
                return(false);
            }

            i2 = 0;
            var instrs = stringMethod.Body.Instructions;

            var emu = new InstructionEmulator(stringMethod);

            foreach (var kv in stringMethodConsts.Locals32)
            {
                emu.SetLocal(kv.Key, new Int32Value(kv.Value));
            }

            var fields = new Dictionary <FieldDef, int?>();

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

                FieldDef field;
                switch (instr.OpCode.Code)
                {
                case Code.Ldsfld:
                    field = instr.Operand as FieldDef;
                    if (field == null || field.DeclaringType != stringMethod.DeclaringType || field.FieldType.GetElementType() != ElementType.I4)
                    {
                        goto default;
                    }
                    fields[field] = null;
                    emu.Push(new Int32Value(i1));
                    break;

                case Code.Stsfld:
                    field = instr.Operand as FieldDef;
                    if (field == null || field.DeclaringType != stringMethod.DeclaringType || field.FieldType.GetElementType() != ElementType.I4)
                    {
                        goto default;
                    }
                    if (fields.ContainsKey(field) && fields[field] == null)
                    {
                        goto default;
                    }
                    var val = emu.Pop() as Int32Value;
                    if (val == null || !val.AllBitsValid())
                    {
                        fields[field] = null;
                    }
                    else
                    {
                        fields[field] = val.Value;
                    }
                    break;

                case Code.Call:
                    var method = instr.Operand as MethodDef;
                    if (!decrypterType.Detected || method != decrypterType.Int64Method)
                    {
                        goto done;
                    }
                    emu.Push(new Int64Value((long)decrypterType.GetMagic()));
                    break;

                case Code.Newobj:
                    if (!EmulateDynocode(emu, ref i))
                    {
                        goto default;
                    }
                    break;

                default:
                    if (instr.OpCode.FlowControl != FlowControl.Next)
                    {
                        goto done;
                    }
                    emu.Emulate(instr);
                    break;
                }
            }
            done :;

            foreach (var val in fields.Values)
            {
                if (val == null)
                {
                    continue;
                }
                magic1 = i2 = val.Value;
                return(true);
            }

            return(false);
        }
Ejemplo n.º 11
0
        public static Value[] GetInitializedArray(int arraySize, MethodDef method, ref int newarrIndex, Code stelemOpCode)
        {
            var resultValueArray = new Value[arraySize];

            var emulator = new InstructionEmulator(method);
            var theArray = new UnknownValue();

            emulator.Push(theArray);

            var instructions = method.Body.Instructions;
            int i;

            for (i = newarrIndex + 1; i < instructions.Count; i++)
            {
                var instr = instructions[i];
                if (instr.OpCode.FlowControl != FlowControl.Next)
                {
                    break;
                }
                if (instr.OpCode.Code == Code.Newarr)
                {
                    break;
                }
                switch (instr.OpCode.Code)
                {
                case Code.Newarr:
                case Code.Newobj:
                    goto done;

                case Code.Stloc:
                case Code.Stloc_S:
                case Code.Stloc_0:
                case Code.Stloc_1:
                case Code.Stloc_2:
                case Code.Stloc_3:
                case Code.Starg:
                case Code.Starg_S:
                case Code.Stsfld:
                case Code.Stfld:
                    if (emulator.Peek() == theArray && i != newarrIndex + 1 && i != newarrIndex + 2)
                    {
                        goto done;
                    }
                    break;
                }

                if (instr.OpCode.Code == stelemOpCode)
                {
                    var value = emulator.Pop();
                    var index = emulator.Pop() as Int32Value;
                    var array = emulator.Pop();
                    if (ReferenceEquals(array, theArray) && index != null && index.AllBitsValid())
                    {
                        if (0 <= index.Value && index.Value < resultValueArray.Length)
                        {
                            resultValueArray[index.Value] = value;
                        }
                    }
                }
                else
                {
                    emulator.Emulate(instr);
                }
            }
done:
            if (i != newarrIndex + 1)
            {
                i--;
            }
            newarrIndex = i;

            return(resultValueArray);
        }
Ejemplo n.º 12
0
        bool GetNewValue(MethodDef method, int arg, out int newValue)
        {
            newValue = 0;
            emulator.Initialize(method);
            emulator.SetArg(method.Parameters[0], new Int32Value(arg));

            Instruction instr;

            emulateIndex = 0;
            instructions = method.Body.Instructions;
            int counter = 0;

            while (true)
            {
                if (counter++ >= 50)
                {
                    return(false);
                }
                if (emulateIndex < 0 || emulateIndex >= instructions.Count)
                {
                    return(false);
                }
                instr = instructions[emulateIndex];
                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:
                case Code.Stloc:
                case Code.Stloc_S:
                case Code.Stloc_0:
                case Code.Stloc_1:
                case Code.Stloc_2:
                case Code.Stloc_3:
                case Code.Ldloc:
                case Code.Ldloc_S:
                case Code.Ldloc_0:
                case Code.Ldloc_1:
                case Code.Ldloc_2:
                case Code.Ldloc_3:
                case Code.Ldc_I4:
                case Code.Ldc_I4_0:
                case Code.Ldc_I4_1:
                case Code.Ldc_I4_2:
                case Code.Ldc_I4_3:
                case Code.Ldc_I4_4:
                case Code.Ldc_I4_5:
                case Code.Ldc_I4_6:
                case Code.Ldc_I4_7:
                case Code.Ldc_I4_8:
                case Code.Ldc_I4_M1:
                case Code.Ldc_I4_S:
                case Code.Add:
                case Code.Sub:
                case Code.Xor:
                case Code.Or:
                case Code.Nop:
                case Code.Dup:
                case Code.Mul:
                case Code.Rem:
                case Code.Div:
                    emulator.Emulate(instr);
                    emulateIndex++;
                    break;

                case Code.Br:
                case Code.Br_S:
                case Code.Beq:
                case Code.Beq_S:
                case Code.Bge:
                case Code.Bge_S:
                case Code.Bge_Un:
                case Code.Bge_Un_S:
                case Code.Bgt:
                case Code.Bgt_S:
                case Code.Bgt_Un:
                case Code.Bgt_Un_S:
                case Code.Ble:
                case Code.Ble_S:
                case Code.Ble_Un:
                case Code.Ble_Un_S:
                case Code.Blt:
                case Code.Blt_S:
                case Code.Blt_Un:
                case Code.Blt_Un_S:
                case Code.Bne_Un:
                case Code.Bne_Un_S:
                case Code.Brfalse:
                case Code.Brfalse_S:
                case Code.Brtrue:
                case Code.Brtrue_S:
                case Code.Switch:
                    if (!branchEmulator.Emulate(instr))
                    {
                        return(false);
                    }
                    break;

                case Code.Ret:
                    var retValue = emulator.Pop();
                    if (!retValue.IsInt32())
                    {
                        return(false);
                    }
                    var retValue2 = (Int32Value)retValue;
                    if (!retValue2.AllBitsValid())
                    {
                        return(false);
                    }
                    newValue = retValue2.Value;
                    return(true);

                default:
                    if (instr.OpCode.OpCodeType != OpCodeType.Prefix)
                    {
                        return(false);
                    }
                    emulateIndex++;
                    break;
                }
            }
        }
        bool EmulateInstructions(ref int index, bool allowUnknownArgs)
        {
            Instruction instr;
            var         instrs       = methodToInline.Body.Instructions;
            int         counter      = 0;
            var         foundOpCodes = new Dictionary <Code, bool>();
            bool        checkInstrs  = false;

            while (true)
            {
                if (counter++ >= 50)
                {
                    return(false);
                }
                if (index < 0 || index >= instrs.Count)
                {
                    return(false);
                }
                instr = instrs[index];
                foundOpCodes[instr.OpCode.Code] = true;
                switch (instr.OpCode.Code)
                {
                case Code.Stloc:
                case Code.Stloc_S:
                case Code.Stloc_0:
                case Code.Stloc_1:
                case Code.Stloc_2:
                case Code.Stloc_3:
                case Code.Ldloc:
                case Code.Ldloc_S:
                case Code.Ldloc_0:
                case Code.Ldloc_1:
                case Code.Ldloc_2:
                case Code.Ldloc_3:
                case Code.Ldc_I4:
                case Code.Ldc_I4_0:
                case Code.Ldc_I4_1:
                case Code.Ldc_I4_2:
                case Code.Ldc_I4_3:
                case Code.Ldc_I4_4:
                case Code.Ldc_I4_5:
                case Code.Ldc_I4_6:
                case Code.Ldc_I4_7:
                case Code.Ldc_I4_8:
                case Code.Ldc_I4_M1:
                case Code.Ldc_I4_S:
                case Code.Add:
                case Code.Sub:
                case Code.Xor:
                case Code.Or:
                case Code.Nop:
                case Code.Dup:
                case Code.Mul:
                case Code.Rem:
                case Code.Div:
                    instructionEmulator.Emulate(instr);
                    index++;
                    break;

                case Code.Ldarg:
                case Code.Ldarg_S:
                case Code.Ldarg_0:
                case Code.Ldarg_1:
                case Code.Ldarg_2:
                case Code.Ldarg_3:
                    var arg = instr.GetParameter(parameters);
                    if (arg != arg1 && arg != arg2)
                    {
                        if (!allowUnknownArgs)
                        {
                            goto done;
                        }
                        checkInstrs = true;
                    }
                    instructionEmulator.Emulate(instr);
                    index++;
                    break;

                case Code.Call:
                case Code.Callvirt:
                case Code.Newobj:
                    goto done;

                case Code.Switch:
                    var value = instructionEmulator.Pop() as Int32Value;
                    if (value == null || !value.AllBitsValid())
                    {
                        return(false);
                    }
                    var targets = (Instruction[])instr.Operand;
                    if (value.Value >= 0 && value.Value < targets.Length)
                    {
                        index = instrs.IndexOf(targets[value.Value]);
                    }
                    else
                    {
                        index++;
                    }
                    break;

                case Code.Br:
                case Code.Br_S:
                    index = instrs.IndexOf((Instruction)instr.Operand);
                    break;

                case Code.Brtrue:
                case Code.Brtrue_S:
                    index = EmulateBrtrue(index);
                    break;

                case Code.Brfalse:
                case Code.Brfalse_S:
                    index = EmulateBrfalse(index);
                    break;

                case Code.Isinst:
                case Code.Castclass:
                    if (returnValue != null && instructionEmulator.Peek() == returnValue)
                    {
                        // Do nothing
                    }
                    else
                    {
                        instructionEmulator.Emulate(instr);
                    }
                    index++;
                    break;

                default:
                    if (instr.OpCode.OpCodeType != OpCodeType.Prefix)
                    {
                        goto done;
                    }
                    index++;
                    break;
                }
            }
done:
            if (checkInstrs)
            {
                if (!foundOpCodes.ContainsKey(Code.Ldc_I4_1))
                {
                    return(false);
                }
                if (!foundOpCodes.ContainsKey(Code.Ldc_I4_2))
                {
                    return(false);
                }
                if (!foundOpCodes.ContainsKey(Code.Add))
                {
                    return(false);
                }
                if (!foundOpCodes.ContainsKey(Code.Dup))
                {
                    return(false);
                }
                if (!foundOpCodes.ContainsKey(Code.Mul))
                {
                    return(false);
                }
                if (!foundOpCodes.ContainsKey(Code.Rem))
                {
                    return(false);
                }
                if (!foundOpCodes.ContainsKey(Code.Brtrue) && !foundOpCodes.ContainsKey(Code.Brtrue_S) &&
                    !foundOpCodes.ContainsKey(Code.Brfalse) && !foundOpCodes.ContainsKey(Code.Brfalse_S))
                {
                    return(false);
                }
            }
            return(true);
        }
Ejemplo n.º 14
0
        bool GetNewValue(MethodDef method, int arg, out int newValue)
        {
            newValue = 0;
            emulator.Initialize(method);
            emulator.SetArg(method.Parameters[0], new Int32Value(arg));

            emulateIndex = 0;
            instructions = method.Body.Instructions;
            int counter = 0;

            while (true)
            {
                if (counter++ >= 50)
                {
                    return(false);
                }
                if (emulateIndex < 0 || emulateIndex >= instructions.Count)
                {
                    return(false);
                }
                var instr = instructions[emulateIndex];
                switch (instr.OpCode.Code)
                {
                case Code.Br:
                case Code.Br_S:
                case Code.Beq:
                case Code.Beq_S:
                case Code.Bge:
                case Code.Bge_S:
                case Code.Bge_Un:
                case Code.Bge_Un_S:
                case Code.Bgt:
                case Code.Bgt_S:
                case Code.Bgt_Un:
                case Code.Bgt_Un_S:
                case Code.Ble:
                case Code.Ble_S:
                case Code.Ble_Un:
                case Code.Ble_Un_S:
                case Code.Blt:
                case Code.Blt_S:
                case Code.Blt_Un:
                case Code.Blt_Un_S:
                case Code.Bne_Un:
                case Code.Bne_Un_S:
                case Code.Brfalse:
                case Code.Brfalse_S:
                case Code.Brtrue:
                case Code.Brtrue_S:
                case Code.Switch:
                    if (!branchEmulator.Emulate(instr))
                    {
                        return(false);
                    }
                    break;

                case Code.Ret:
                    var retValue = emulator.Pop();
                    if (!retValue.IsInt32())
                    {
                        return(false);
                    }
                    var retValue2 = (Int32Value)retValue;
                    if (!retValue2.AllBitsValid())
                    {
                        return(false);
                    }
                    newValue = retValue2.Value;
                    return(true);

                default:
                    emulator.Emulate(instr);
                    emulateIndex++;
                    break;
                }
            }
        }
Ejemplo n.º 15
0
        private bool doit(Block swBlock)
        {
            var modified = false;

            if (swBlock.Targets == null)
            {
                return(modified);
            }


            var allSwBlocks = allBlocks.Where(block => block.FallThrough == swBlock).ToList();

            foreach (var block in allSwBlocks)
            {
                var instr = block.Instructions;
                var count = block.Instructions.Count;
                int localVal;
                if (block.LastInstr.IsLdcI4() && count == 3)
                {
                    ins.Emulate(instr, count - 3, count);
                    var nextCase = caseEmulate(out localVal);
                    block.ReplaceLastNonBranchWithBranch(0, swBlock.Targets[nextCase]);
                    block.Instructions.Add(new Instr(new Instruction(OpCodes.Pop)));
                    replace(swBlock.Targets[nextCase], localVal);
                    modified = true;
                }
                else if (use1(block))
                {
                    ins.Emulate(instr, count - 9, count);
                    var nextCase = caseEmulate(out localVal);
                    block.ReplaceLastNonBranchWithBranch(0, swBlock.Targets[nextCase]);
                    block.Instructions.Add(new Instr(new Instruction(OpCodes.Pop)));
                    replace(swBlock.Targets[nextCase], localVal);
                    modified = true;
                }
                else if (use2(block))
                {
                    ins.Emulate(instr, count - 5, count);
                    var nextCase = caseEmulate(out localVal);
                    block.ReplaceLastNonBranchWithBranch(0, swBlock.Targets[nextCase]);
                    block.Instructions.Add(new Instr(new Instruction(OpCodes.Pop)));
                    replace(swBlock.Targets[nextCase], localVal);
                    modified = true;
                }
                else if (iseasyBlock(block))
                {
                    ins.Emulate(instr, count - 3, count);
                    var nextCase = caseEmulate(out localVal);
                    block.ReplaceLastNonBranchWithBranch(0, swBlock.Targets[nextCase]);
                    block.Instructions.Add(new Instr(new Instruction(OpCodes.Pop)));
                    replace(swBlock.Targets[nextCase], localVal);
                    modified = true;
                }
                else if (isMathCase(block) || isMathCase3(block))
                {
                    if (!instr[count - 7].IsLdcI4())
                    {
                        continue;
                    }
                    ins.Emulate(instr, count - 7, count);
                    var nextCase = caseEmulate(out localVal);
                    block.ReplaceLastNonBranchWithBranch(0, swBlock.Targets[nextCase]);
                    block.Instructions.Add(new Instr(new Instruction(OpCodes.Pop)));
                    replace(swBlock.Targets[nextCase], localVal);
                    modified = true;
                }
                else if (isMathCase2(block))
                {
                    if (!instr[count - 9].IsLdcI4())
                    {
                        continue;
                    }
                    ins.Emulate(instr, count - 9, count);
                    var nextCase = caseEmulate(out localVal);
                    block.ReplaceLastNonBranchWithBranch(0, swBlock.Targets[nextCase]);
                    block.Instructions.Add(new Instr(new Instruction(OpCodes.Pop)));
                    replace(swBlock.Targets[nextCase], localVal);
                    modified = true;
                }
                else if (isMathCase4(block))
                {
                    if (!instr[count - 9].IsLdcI4())
                    {
                        continue;
                    }
                    ins.Emulate(instr, count - 9, count);
                    var nextCase = caseEmulate(out localVal);
                    block.ReplaceLastNonBranchWithBranch(0, swBlock.Targets[nextCase]);
                    block.Instructions.Add(new Instr(new Instruction(OpCodes.Pop)));

                    replace(swBlock.Targets[nextCase], localVal);
                    modified = true;
                }
                else if (anotherunSure(block))
                {
                    var sources = new List <Block>(block.Sources);
                    foreach (var sour in sources)
                    {
                        if (!sour.FirstInstr.IsLdcI4())
                        {
                            continue;
                        }
                        //  ins.Push(new Int32Value(sour.FirstInstr.GetLdcI4Value()));
                        block.Instructions[count - 3] =
                            new Instr(Instruction.CreateLdcI4(sour.FirstInstr.GetLdcI4Value()));
                        ins.Emulate(instr, count - 3, count);
                        var nextCase = caseEmulate(out localVal);
                        sour.ReplaceLastNonBranchWithBranch(0, swBlock.Targets[nextCase]);
                        sour.Remove(0, sour.Instructions.Count);
                        replace(swBlock.Targets[nextCase], localVal);
                        modified = true;
                    }
                }
                else if (unsureCase(block))
                {
                    var sources = new List <Block>(block.Sources);
                    foreach (var sour in sources)
                    {
                        if (!sour.FirstInstr.IsLdcI4())
                        {
                            continue;
                        }
                        if (sour.Instructions.Count != 2)
                        {
                            continue;
                        }
                        //  ins.Push(new Int32Value(sour.FirstInstr.GetLdcI4Value()));
                        block.Instructions[count - 7] =
                            new Instr(Instruction.CreateLdcI4(sour.FirstInstr.GetLdcI4Value()));
                        ins.Emulate(instr, count - 7, count);
                        var nextCase = caseEmulate(out localVal);
                        sour.ReplaceLastNonBranchWithBranch(0, swBlock.Targets[nextCase]);
                        sour.Remove(0, sour.Instructions.Count);
                        replace(swBlock.Targets[nextCase], localVal);
                        modified = true;
                    }
                }
                else if (count == 1)
                {
                }
            }

            return(modified);
        }
Ejemplo n.º 16
0
        protected override bool Deobfuscate(Block block)
        {
            ins = ControlFlowRemover.Inemu;
            var modified = false;

            //		var blocks2 = blocks.MethodBlocks.GetAllBlocks();


            if (block.LastInstr.OpCode != OpCodes.Switch)
            {
                return(false);
            }
            if (blocks.Method.MDToken.ToInt32() == 0x060000CC)
            {
            }
            if (block.Instructions.Count <= 4)
            {
                return(false);
            }
            if (block.Instructions[block.Instructions.Count - 4].IsStloc())
            {
                if (blocks.Method.MDToken.ToInt32() == 0x060000CC)
                {
                }
                //		return false;
                var baseBlocksParent = block.Parent;
                var abc = baseBlocksParent.GetAllBlocks()[0].Instructions;

                foreach (var blockInstruction in abc)
                {
                    if (blockInstruction.IsStloc())
                    {
                        if (blockInstruction.Instruction.GetLocal(blocks.Method.Body.Variables).Type ==
                            blocks.Method.Module.CorLibTypes.UInt32)
                        {
                            loc = blockInstruction.Instruction.GetLocal(blocks.Locals);
                            ins.Emulate(abc);
                            break;
                        }
                    }
                }

                //    return false;

                swlocal = Instr.GetLocalVar(blocks.Locals, block.Instructions[block.Instructions.Count - 4]);

                swBlock = block;

                modified = doit(block);
            }
            else if (!block.Instructions[block.Instructions.Count - 4].IsStloc() &&
                     block.Instructions[block.Instructions.Count - 2].OpCode != OpCodes.Nop)
            {
                //		return false;
                if (blocks.Method.MDToken.ToInt32() == 0x060000CC)
                {
                }
                var baseBlocksParent = block.Parent;
                var abc = baseBlocksParent.GetAllBlocks()[0].Instructions;

                foreach (var blockInstruction in abc)
                {
                    if (blockInstruction.IsStloc())
                    {
                        loc = blockInstruction.Instruction.GetLocal(blocks.Locals);
                        ins.Emulate(abc);
                        break;
                    }
                }

                //    return false;

                swlocal = null;

                swBlock = block;

                modified = doit(block);
            }

            return(modified);
        }