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); }
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)); } }
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; } } } } }