object Run(ulong codeAddr, uint key, VMFuncSig sig, object[] arguments) { if (currentCtx != null) { ctxStack.Push(currentCtx); } currentCtx = new VMContext(this); try { Debug.Assert(sig.ParamTypes.Length == arguments.Length); currentCtx.Stack.SetTopPosition((uint)arguments.Length + 1); for (uint i = 0; i < arguments.Length; i++) { currentCtx.Stack[i + 1] = VMSlot.FromObject(arguments[i], sig.ParamTypes[i]); } currentCtx.Stack[(uint)arguments.Length + 1] = new VMSlot { U8 = 1 }; currentCtx.Registers[Constants.REG_K1] = new VMSlot { U4 = key }; currentCtx.Registers[Constants.REG_BP] = new VMSlot { U4 = 0 }; currentCtx.Registers[Constants.REG_SP] = new VMSlot { U4 = (uint)arguments.Length + 1 }; currentCtx.Registers[Constants.REG_IP] = new VMSlot { U8 = codeAddr }; VMDispatcher.Run(currentCtx); Debug.Assert(currentCtx.EHStack.Count == 0); object retVal = null; if (sig.RetType != typeof(void)) { var retSlot = currentCtx.Registers[Constants.REG_R0]; if (Type.GetTypeCode(sig.RetType) == TypeCode.String && retSlot.O == null) { retVal = Data.LookupString(retSlot.U4); } else { retVal = retSlot.ToObject(sig.RetType); } } return(retVal); } finally { currentCtx.Stack.FreeAllLocalloc(); if (ctxStack.Count > 0) { currentCtx = ctxStack.Pop(); } } }
static bool ShouldBeTyped(VMFuncSig sig) { foreach (var param in sig.ParamTypes) { if (param.IsByRef) { return(true); } } return(sig.RetType.IsByRef); }
private void Run(ulong codeAddr, uint key, VMFuncSig sig, void *[] arguments, void *retTypedRef) { if (currentCtx != null) { ctxStack.Push(currentCtx); } currentCtx = new VMContext(this); try { Debug.Assert(sig.ParamTypes.Length == arguments.Length); currentCtx.Stack.SetTopPosition((uint)arguments.Length + 1); for (uint i = 0; i < arguments.Length; i++) { var paramType = sig.ParamTypes[i]; if (paramType.IsByRef) { currentCtx.Stack[i + 1] = new VMSlot { O = new TypedRef(arguments[i]) }; } else { var typedRef = *(TypedReference *)arguments[i]; currentCtx.Stack[i + 1] = VMSlot.FromObject(TypedReference.ToObject(typedRef), __reftype(typedRef)); } } currentCtx.Stack[(uint)arguments.Length + 1] = new VMSlot { U8 = 1 }; currentCtx.Registers[Constants.REG_K1] = new VMSlot { U4 = key }; currentCtx.Registers[Constants.REG_BP] = new VMSlot { U4 = 0 }; currentCtx.Registers[Constants.REG_SP] = new VMSlot { U4 = (uint)arguments.Length + 1 }; currentCtx.Registers[Constants.REG_IP] = new VMSlot { U8 = codeAddr }; VMDispatcher.Run(currentCtx); Debug.Assert(currentCtx.EHStack.Count == 0); if (sig.RetType != typeof(void)) { if (sig.RetType.IsByRef) { var retRef = currentCtx.Registers[Constants.REG_R0].O; if (!(retRef is IReference)) { throw new ExecutionEngineException(); } ((IReference)retRef).ToTypedReference(currentCtx, retTypedRef, sig.RetType.GetElementType()); } else { var retSlot = currentCtx.Registers[Constants.REG_R0]; object retVal; if (Type.GetTypeCode(sig.RetType) == TypeCode.String && retSlot.O == null) { retVal = Data.LookupString(retSlot.U4); } else { retVal = retSlot.ToObject(sig.RetType); } TypedReferenceHelpers.SetTypedRef(retVal, retTypedRef); } } } finally { currentCtx.Stack.FreeAllLocalloc(); if (ctxStack.Count > 0) { currentCtx = ctxStack.Pop(); } } }
static DynamicMethod CreateTrampolineNormal(int moduleId, ulong codeAdr, uint key, VMFuncSig sig, uint sigId) { var dm = new DynamicMethod("", sig.RetType, sig.ParamTypes, Unverifier.Module, true); var gen = dm.GetILGenerator(); //body.Instructions.Add(Instruction.Create(OpCodes.Ldc_I4, id)); //body.Instructions.Add(Instruction.Create(OpCodes.Ldstr, "cracked.to/AndyLarkin | AndyLarkin#3553")); //body.Instructions.Add(Instruction.Create(OpCodes.Ldtoken, method.DeclaringType)); //body.Instructions.Add(Instruction.Create(OpCodes.Ldstr, gx(id))); gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)moduleId); gen.Emit(System.Reflection.Emit.OpCodes.Ldstr, "cracked.to/AndyLarkin | AndyLarkin#3553"); gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)moduleId); gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I8, (long)codeAdr); gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)key); gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)sigId); gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, sig.ParamTypes.Length); gen.Emit(System.Reflection.Emit.OpCodes.Newarr, typeof(object)); for (int i = 0; i < sig.ParamTypes.Length; i++) { gen.Emit(System.Reflection.Emit.OpCodes.Dup); gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, i); gen.Emit(System.Reflection.Emit.OpCodes.Ldarg, i); if (sig.ParamTypes[i].IsValueType) { gen.Emit(System.Reflection.Emit.OpCodes.Box, sig.ParamTypes[i]); } gen.Emit(System.Reflection.Emit.OpCodes.Stelem_Ref); } gen.Emit(System.Reflection.Emit.OpCodes.Call, entryStubNormal); if (sig.RetType == typeof(void)) { gen.Emit(System.Reflection.Emit.OpCodes.Pop); } else if (sig.RetType.IsValueType) { gen.Emit(System.Reflection.Emit.OpCodes.Unbox_Any, sig.RetType); } else { gen.Emit(System.Reflection.Emit.OpCodes.Castclass, sig.RetType); } gen.Emit(System.Reflection.Emit.OpCodes.Ret); return(dm); }
public static IntPtr CreateTrampoline(Module module, ulong codeAdr, uint key, VMFuncSig sig, uint sigId) { object dm = trampolines[codeAdr]; if (dm != null) { return(getDesc((DynamicMethod)dm).GetFunctionPointer()); } lock (trampolines) { dm = (DynamicMethod)trampolines[codeAdr]; if (dm != null) { return(getDesc((DynamicMethod)dm).GetFunctionPointer()); } if (ShouldBeTyped(sig)) { dm = CreateTrampolineTyped(VMInstance.GetModuleId(module), codeAdr, key, sig, sigId); } else { dm = CreateTrampolineNormal(VMInstance.GetModuleId(module), codeAdr, key, sig, sigId); } trampolines[codeAdr] = dm; return(getDesc((DynamicMethod)dm).GetFunctionPointer()); } }
static DynamicMethod CreateTrampolineTyped(int moduleId, ulong codeAdr, uint key, VMFuncSig sig, uint sigId) { var dm = new DynamicMethod("", sig.RetType, sig.ParamTypes, Unverifier.Module, true); var gen = dm.GetILGenerator(); gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)moduleId); gen.Emit(System.Reflection.Emit.OpCodes.Ldstr, "cracked.to/AndyLarkin | AndyLarkin#3553"); gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)moduleId); gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I8, (long)codeAdr); gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)key); gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)sigId); gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, sig.ParamTypes.Length); gen.Emit(System.Reflection.Emit.OpCodes.Newarr, typeof(void *)); for (int i = 0; i < sig.ParamTypes.Length; i++) { gen.Emit(System.Reflection.Emit.OpCodes.Dup); gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, i); if (sig.ParamTypes[i].IsByRef) { gen.Emit(System.Reflection.Emit.OpCodes.Ldarg, i); gen.Emit(System.Reflection.Emit.OpCodes.Mkrefany, sig.ParamTypes[i].GetElementType()); } else { gen.Emit(System.Reflection.Emit.OpCodes.Ldarga, i); gen.Emit(System.Reflection.Emit.OpCodes.Mkrefany, sig.ParamTypes[i]); } var local = gen.DeclareLocal(typeof(TypedReference)); gen.Emit(System.Reflection.Emit.OpCodes.Stloc, local); gen.Emit(System.Reflection.Emit.OpCodes.Ldloca, local); gen.Emit(System.Reflection.Emit.OpCodes.Conv_I); gen.Emit(System.Reflection.Emit.OpCodes.Stelem_I); } if (sig.RetType != typeof(void)) { var retVar = gen.DeclareLocal(sig.RetType); var retRef = gen.DeclareLocal(typeof(TypedReference)); gen.Emit(System.Reflection.Emit.OpCodes.Ldloca, retVar); gen.Emit(System.Reflection.Emit.OpCodes.Mkrefany, sig.RetType); gen.Emit(System.Reflection.Emit.OpCodes.Stloc, retRef); gen.Emit(System.Reflection.Emit.OpCodes.Ldloca, retRef); gen.Emit(System.Reflection.Emit.OpCodes.Call, entryStubTyped); gen.Emit(System.Reflection.Emit.OpCodes.Ldloc, retVar); } else { gen.Emit(System.Reflection.Emit.OpCodes.Ldnull); gen.Emit(System.Reflection.Emit.OpCodes.Call, entryStubTyped); } gen.Emit(System.Reflection.Emit.OpCodes.Ret); return(dm); }
private static DynamicMethod CreateTrampolineNormal(int moduleId, ulong codeAdr, uint key, VMFuncSig sig, uint sigId) { var dm = new DynamicMethod("", sig.RetType, sig.ParamTypes, Unverifier.Module, true); var gen = dm.GetILGenerator(); gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, moduleId); gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I8, (long)codeAdr); gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)key); gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)sigId); gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, sig.ParamTypes.Length); gen.Emit(System.Reflection.Emit.OpCodes.Newarr, typeof(object)); for (var i = 0; i < sig.ParamTypes.Length; i++) { gen.Emit(System.Reflection.Emit.OpCodes.Dup); gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, i); gen.Emit(System.Reflection.Emit.OpCodes.Ldarg, i); if (sig.ParamTypes[i].IsValueType) { gen.Emit(System.Reflection.Emit.OpCodes.Box, sig.ParamTypes[i]); } gen.Emit(System.Reflection.Emit.OpCodes.Stelem_Ref); } gen.Emit(System.Reflection.Emit.OpCodes.Call, entryStubNormal); if (sig.RetType == typeof(void)) { gen.Emit(System.Reflection.Emit.OpCodes.Pop); } else if (sig.RetType.IsValueType) { gen.Emit(System.Reflection.Emit.OpCodes.Unbox_Any, sig.RetType); } else { gen.Emit(System.Reflection.Emit.OpCodes.Castclass, sig.RetType); } gen.Emit(System.Reflection.Emit.OpCodes.Ret); return(dm); }