Пример #1
0
        public VMSlot InferStackValue()
        {
            var emulator  = new InstructionEmulator();
            var pushValue = DataSources.First(); // TODO: might need to verify multiple data sources.

            emulator.EmulateDependentInstructions(pushValue);
            emulator.EmulateInstruction(pushValue);
            return(emulator.Stack.Pop());
        }
Пример #2
0
        private void EmulateMethod(DelegateInitInfo info, InstructionEmulator emulator)
        {
            var blocks    = new Blocks(info.InitMethod);
            var allBlocks = blocks.MethodBlocks.GetAllBlocks();

            emulator.Initialize(blocks, true);
            emulator.SetArg(0, new ObjectValue(info.Field));
            emulator.SetArg(1, new Int32Value(info.Key));
            EmulatoeBlock(emulator, allBlocks[0]);
        }
Пример #3
0
        private void EmulateBrantchBlock(InstructionEmulator emulator, Block block)
        {
            if (block == null)
            {
                return;
            }
            var instr    = block.Instructions;
            var isSwitch = block.LastInstr.OpCode == OpCodes.Switch;

            for (int i = 0; i < instr.Count - (isSwitch ? 1 : 0); i++)
            {
                if (instr[i].OpCode == OpCodes.Call && instr[i].Operand is MethodDef nativeMethod && IsNativeMethod(nativeMethod))
                {
                    EmulateNativeMethod(emulator, nativeMethod);
                }
        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());
        }
Пример #5
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);
        }
        public static void CleanVarMelt(MethodDef meth)
        {
            var blocks = new Blocks(meth);

            CfDeob.Initialize(blocks);
            Inemu = new InstructionEmulator(meth);

            //			CfDeob.Add(new LocalsSolver());
            CfDeob.Add(new VariableMelting());
            //   CfDeob.Add(new VariableMelting());
            CfDeob.Deobfuscate();
            blocks.RepartitionBlocks();

            //      de4dot.blocks.NetguardCflow tfhdgrs = new de4dot.blocks.NetguardCflow();
            //    de4dot.blocks.NetguardCflow.test2 = blocks;
            //  tfhdgrs.Deobfuscate(test);
            IList <Instruction>      instructions;
            IList <ExceptionHandler> exceptionHandlers;

            blocks.GetCode(out instructions, out exceptionHandlers);
            DotNetUtils.RestoreBody(meth, instructions, exceptionHandlers);
        }
Пример #7
0
        private JumpAnnotation InferJumpTargets(ILInstruction instruction)
        {
            try
            {
                var metadata        = new JumpAnnotation();
                var symbolicAddress = instruction.Dependencies[instruction.Dependencies.Count - 1];

                foreach (var dataSource in symbolicAddress.DataSources)
                {
                    var emulator = new InstructionEmulator();
                    emulator.EmulateDependentInstructions(dataSource);
                    emulator.EmulateInstruction(dataSource);

                    // After partial emulation, IP is on stack.
                    uint nextIp = (uint)emulator.Stack.Pop().U8;

                    Logger.Debug2(Tag, $"Inferred edge IL_{instruction.Offset:X4} -> IL_{nextIp:X4}");

                    if (nextIp > (ulong)KoiStream.Contents.GetPhysicalSize())
                    {
                        Logger.Warning(Tag,
                                       $"Jump instruction at IL_{instruction.Offset:X4} "
                                       + $"transfers control to an instruction outside of the KoiVM stream (IL_{nextIp:X4}.");
                    }

                    metadata.InferredJumpTargets.Add(nextIp);
                }

                instruction.Annotation = metadata;
                return(metadata);
            }
            catch (NotSupportedException e)
            {
                Logger.Warning(Tag, $"Could not infer jump target for {instruction.Offset:X4}. {e.Message}");
            }

            return(null);
        }
Пример #8
0
 public void DecryptMethods()
 {
     for (int i = 0; i < delegateInfos.Count; i++)
     {
         var info    = delegateInfos[i];
         var emuator = new InstructionEmulator();
         EmulateMethod(info, emuator);
         var local = info.InitMethod.Body.Variables.FirstOrDefault(t => t.Type.FullName == "System.Reflection.MethodBase");
         if (local == null)
         {
             continue;
         }
         var value = emuator.GetLocal(local);
         if (!(value is ObjectValue objValue) || !(objValue.obj is IMethod method))
         {
             continue;
         }
         info.Resolved  = true;
         info.Decrypted = method;
         info.OpCode    = ResolveOpCode(info.InitMethod, info.Field, info.Key);
         Decrypted++;
     }
 }
 public ReflectionToDNLibMethodCreator(MethodDef method)
 {
     this.method   = method;
     this.emulator = new InstructionEmulator(method);
 }
Пример #10
0
        public static Value[] getInitializedArray(int arraySize, MethodDefinition 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);
        }
Пример #11
0
 public BabelMethodCallInliner()
 {
     emulator       = new InstructionEmulator();
     branchEmulator = new BranchEmulator(emulator, this);
 }
Пример #12
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);
        }
Пример #13
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);
        }
        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];

            if (!ldloc.IsLdloc() || instrs[index + 4].OpCode.Code != Code.Stfld)
            {
                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);
            }

            var dcGen = dynocode.getDynocodeGenerator(ctor.DeclaringType);

            if (dcGen == null)
            {
                return(false);
            }
            int loopLocalValue = initValue2.value;

            foreach (var val in dcGen.getValues(initValue.value))
            {
                loopLocalValue ^= val;
            }

            emu.setLocal(loopLocal, new Int32Value(loopLocalValue));
            emu.emulate(instr);
            index = newIndex - 1;
            return(true);
        }
Пример #15
0
 public ReflectionToCecilMethodCreator(MethodDefinition method)
 {
     this.method   = method;
     this.emulator = new InstructionEmulator(method);
 }
Пример #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);
        }