Beispiel #1
0
        public void SimpleMethodBody(string methodName)
        {
            // Look up method.
            var module           = ModuleDefinition.FromFile(typeof(CilVirtualMachineTest).Assembly.Location);
            var reflectionMethod = typeof(CilVirtualMachineTest).GetMethod(methodName);
            var asmResMethod     = (MethodDefinition)module.LookupMember(reflectionMethod.MetadataToken);

            // Create new virtual machine.
            var vm = new CilVirtualMachine(asmResMethod.CilMethodBody, true);

            // Execute.
            var result = vm.Execute(CancellationToken.None);

            // Inspect return value.
            int expectedResult = (int)reflectionMethod.Invoke(null, null);

            Assert.Equal(new Integer32Value(expectedResult), result.ReturnValue);
        }
Beispiel #2
0
        public void Arguments(int x, int y)
        {
            // Look up method.
            var module           = ModuleDefinition.FromFile(typeof(CilVirtualMachineTest).Assembly.Location);
            var reflectionMethod = typeof(CilVirtualMachineTest).GetMethod(nameof(TestArguments));
            var asmResMethod     = (MethodDefinition)module.LookupMember(reflectionMethod.MetadataToken);

            // Set up VM.
            var vm        = new CilVirtualMachine(asmResMethod.CilMethodBody, true);
            var variables = vm.CurrentState.Variables;

            variables[vm.Architecture.GetParameter(asmResMethod.Parameters[0])] = new Integer32Value(x);
            variables[vm.Architecture.GetParameter(asmResMethod.Parameters[1])] = new Integer32Value(y);

            // Execute.
            var result = vm.Execute(CancellationToken.None);

            // Inspect return value.
            int expectedResult = (int)reflectionMethod.Invoke(null, new object[] { x, y });

            Assert.Equal(new Integer32Value(expectedResult), result.ReturnValue);
        }
        public override void Execute(Context context, IEnumerable <MetadataMember> targets)
        {
            if (!context.IsReflectionSafe)
            {
                return;                            // Sadly Only Reflection To Get Value.
            }
            foreach (var Method in targets.OfType <MethodDefinition>().Where(x => x.CilMethodBody is not null))
            {
                var IL = Method.CilMethodBody.Instructions;
                IL.CalculateOffsets();                                        /* DataFlowGraphs React nani... */
                Method.CilMethodBody.ConstructSymbolicFlowGraph(out var dfg); /* Constructing DataFlowGraph. */
                for (int x = 0; x < IL.Count; x++)
                {
                    var Instr = IL[x];
                    if (Instr.IsCode(CilCode.Call) &&
                        Instr.Operand is MethodSpecification GenericMethod &&                                /* <Module>.Decode<T> */
                        GenericMethod.Signature.TypeArguments.Count == 1 &&
                        GenericMethod.Signature.TypeArguments[0] == context.Module.CorLibTypeFactory.String) /* T is string. (i.e. <Module>.Decode<string>(params)) */
                    {
                        var vm = new CilVirtualMachine(Method.CilMethodBody, context.Module.Is32Module());   /* Define CilEmulator. */
                        var ex = new CilExecutionContext(vm, vm.CurrentState, default);
                        if (!dfg.Nodes.Contains(Instr.Offset))
                        {
                            continue;                                    /* Maybe Some Time it fails to Make DFG for that Instruction Who Knows Hidden Features ?!  */
                        }
                        var StackDeps = dfg.Nodes[Instr.Offset]
                                        .GetOrderedDependencies(DependencyCollectionFlags.IncludeStackDependencies)
                                        .ToList();          /* Get Stack Dependencies For Constants Call.*/
                        StackDeps.Remove(StackDeps.Last()); /* Remove Call Instruction (Decoder Call). */
                        var BackUp = new List <CilInstruction>();
                        foreach (var Dep in StackDeps)
                        {
                            var EmuInstr = Dep.Contents; /* Store Instruction Into Variable To Eumlate it.. */
                            BackUp.Add(new(EmuInstr.OpCode, EmuInstr.Operand ?? null));
                            vm.Dispatcher.Execute(ex, EmuInstr);
                            EmuInstr.Nop(); /* Nop That Instr. */
                        }
                        var ReflectionMethod = context.ReflectionModule.ResolveMethod(GenericMethod.MetadataToken.ToInt32());
                        var RefParams        = ReflectionMethod.GetParameters();
                        var Count            = RefParams.Length;
                        var IOSlot           = new object[Count];
                        for (int i = 0; i < RefParams.Length; i++)
                        {
                            object S     = default;
                            var    Value = vm.CurrentState.Stack.Pop();
                            var    PType = RefParams[--Count].ParameterType;
                            #region Yandere Code (Close Eyes Please 🙃)
                            // Since I never saw anything using any value else so that is good (for now).
                            #region Ldstr-Handling
                            if (PType == typeof(string) && Value is StringValue @string)
                            {
                                S = @string.ToString();
                            }
                            else if (Value is not StringValue && PType == typeof(string))
                            {
                                S = string.Empty; // Hey Skids :DD
                            }
                            #endregion
                            #region I32-Handling
                            if (PType == typeof(int) && Value is I4Value @i32)
                            {
                                S = @i32.I32;
                            }
                            else if (Value is not I4Value && PType == typeof(int))
                            {
                                S = 0;
                            }
                            #endregion
                            #region U32-Handling
                            if (PType == typeof(uint) && Value is I4Value @u32)
                            {
                                S = @u32.U32;
                            }
                            else if (Value is not I4Value && PType == typeof(uint))
                            {
                                S = 0U;
                            }
                            #endregion
                            #endregion
                            /* Assume Fake Parameter. */
                            if (S == default)
                            {
                                S = Convert.ChangeType(new object(), PType);
                            }
                            IOSlot[Count] = S;
                        }
                        try {
                            object Result = default;
                            if (GenericMethod.Method.Resolve().CilMethodBody.Instructions.Any(q => q.ToString().Contains(nameof(Assembly)) || q.ToString().Contains(nameof(StackTrace))))
                            {
                                Result = DynamicInvocation((MethodInfo)ReflectionMethod, Method.Name, context.ReflectionModule, IOSlot);
                            }
                            else
                            {
                                Result = ReflectionMethod.Invoke(null, IOSlot);
                            }

                            Instr.OpCode  = CilOpCodes.Ldstr; /* Changing Call To Ldstr. */
                            Instr.Operand = Result as string  /* Cast Value As String. */
                                            ?? string.Empty;  /* if its null i dont want AsmResolver Throw Errors.... */
                        }
                        catch {
                            // Restore instructions if their an problem (i.e. TargetInvocationException).
                            for (int i = 0; i < BackUp.Count; i++)
                            {
                                CilInstruction Back = BackUp[i];
                                CilInstruction Org  = StackDeps[i].Contents;
                                Org.OpCode  = Back.OpCode;
                                Org.Operand = Back.Operand;
                            }
                        }
                    }
                }
            }
            object DynamicInvocation(MethodInfo method, string invokename, Module module, object[] mparams)
            {
                var pT = new List <Type>();

                foreach (ParameterInfo x in method.GetParameters())
                {
                    pT.Add(x.ParameterType);
                }

                var dMethod = new DynamicMethod(invokename, typeof(string),
                                                pT.ToArray(), module,
                                                true);

                var ILGen = dMethod.GetILGenerator();

                for (int i = 0; i < mparams.Length; i++)
                {
                    ILGen.Emit(OpCodes.Ldarg, i);
                }

                ILGen.Emit(OpCodes.Call, method);

                ILGen.Emit(OpCodes.Ret);

                return(dMethod.Invoke(null, mparams));
            }
        }
Beispiel #4
0
        public override void Execute(Context context, IEnumerable <MetadataMember> targets)
        {
            if (!context.IsReflectionCorlibSafe)
            {
                return;
            }
            foreach (var Method in targets.OfType <MethodDefinition>().Where(m => m.CilMethodBody is not null))
            {
                var Instructions = Method.CilMethodBody.Instructions;
                Method.CilMethodBody.ConstructSymbolicFlowGraph(out var DFG); /* Dfg Constructing. */
                for (int x = 0; x < Instructions.Count; x++)
                {
                    var Instr = Instructions[x];   /* Some People Make It Callvirt To Deafet Public tools :p */
                    if ((Instr.IsCode(CilCode.Call) || Instr.IsCode(CilCode.Callvirt)) &&
                        Instr.IsFromNS("System", "Math") && DFG.Nodes.Contains(Instr.Offset))
                    {
                        var CallNode = DFG.Nodes[Instr.Offset]
                                       .GetOrderedDependencies(DependencyCollectionFlags.IncludeStackDependencies)
                                       .ToList();

                        if (CallNode.Any(x => x.Contents.OpCode.OperandType == CilOperandType.InlineMethod))
                        {
                            continue;
                        }

                        var vm = new CilVirtualMachine(Method.CilMethodBody,
                                                       context.Module.Is32Module());
                        var ex = new CilExecutionContext(vm, vm.CurrentState, default);

                        foreach (var Dep in CallNode)
                        {
                            var CInstr = Dep.Contents;
                            vm.Dispatcher.Execute(ex, CInstr);
                            CInstr.Nop();
                        }
                        var ISlot = new object[((IMethodDescriptor)Instr.Operand)
                                               .Signature.GetTotalParameterCount()];
                        for (int i = 0; i < ISlot.Length; i++)
                        {
                            var Value = vm.CurrentState.Stack.Pop();
                            ISlot[i] = Value switch {
                                I4Value I4 => I4.I32,
                                I8Value I8 => I8.I64,
                                FValue F => F.F64,
                                Float32Value F32 => F32.F32,
                                Float64Value F64 => F64.F64,
                                Integer16Value I6 => I6.I16,
                                Integer32Value I32 => I32.I32,
                                Integer64Value I64 => I64.I64,
                                        _ => throw new NotSupportedException(nameof(Value))
                            };
                        }
                        var InvocationValue = context.ReflectionCorlib.ResolveMethod(((IMethodDescriptor)Instr.Operand).MetadataToken.ToInt32())
                                              .Invoke(null, ISlot);
                        Instr.OpCode = ((IMethodDescriptor)Instr.Operand).Signature.ReturnType.ElementType switch {
                            ElementType.I4 => CilOpCodes.Ldc_I4,
                            ElementType.I8 => CilOpCodes.Ldc_I8,
                            ElementType.R4 => CilOpCodes.Ldc_R4,
                            ElementType.R8 => CilOpCodes.Ldc_R8,
                            _ => CilOpCodes.Ldc_I4,
                        };
                        Instr.Operand = InvocationValue;
                    }
                }
            }
        }
    }