public override void Unload() { // Let's just hope that nothing else detoured this, as this is depth-based... RuntimeDetour.Undetour(m_IntroRespawnEnd); RuntimeDetour.Undetour(m_NextLevel); RuntimeDetour.Undetour(m_Begin); RuntimeDetour.Undetour(m_GetDash); RuntimeDetour.Undetour(m_GetJump); RuntimeDetour.Undetour(m_GetGrab); RuntimeDetour.Undetour(m_GetMoveX); RuntimeDetour.Undetour(m_GetMoveY); RuntimeDetour.Undetour(m_GetAim); }
public static void InstallDispatchHandler(MethodBase method) { var method_token = MethodToken(method); if (_DispatchHandlers.Contains(method_token)) { _Logger.Debug($"Not installing dispatch handler for {method.Name} ({method_token}) - it's already installed"); return; } var parms = method.GetParameters(); int ptypes_offs = 1; if (method.IsStatic) { ptypes_offs = 0; } var ptypes = new Type[parms.Length + ptypes_offs]; if (!method.IsStatic) { ptypes[0] = method.DeclaringType; } for (int i = 0; i < parms.Length; i++) { ptypes[i + ptypes_offs] = parms[i].ParameterType; } var method_returns = false; if (method is MethodInfo) { if (((MethodInfo)method).ReturnType != typeof(void)) { method_returns = true; } } var dm = new DynamicMethod( $"DISPATCH HANDLER FOR METHOD TOKEN {method_token}", method is MethodInfo ? ((MethodInfo)method).ReturnType : typeof(void), ptypes, method.Module, skipVisibility: true ); var il = dm.GetILGenerator(); var loc_args = il.DeclareLocal(typeof(object[])); loc_args.SetLocalSymInfo("args"); var loc_target = il.DeclareLocal(typeof(object)); loc_target.SetLocalSymInfo("target"); if (method.IsStatic) { il.Emit(OpCodes.Ldnull); } else { il.Emit(OpCodes.Ldarg_0); } il.Emit(OpCodes.Stloc, loc_target); int ary_size = ptypes.Length - 1; if (method.IsStatic) { ary_size = ptypes.Length; } il.Emit(OpCodes.Ldc_I4, ary_size); il.Emit(OpCodes.Newarr, typeof(object)); il.Emit(OpCodes.Stloc, loc_args); for (int i = 0; i < ary_size; i++) { il.Emit(OpCodes.Ldloc, loc_args); il.Emit(OpCodes.Ldc_I4, i); il.Emit(OpCodes.Ldarg, i + ptypes_offs); if (ptypes[i + ptypes_offs].IsValueType) { il.Emit(OpCodes.Box, ptypes[i + ptypes_offs]); } il.Emit(OpCodes.Stelem, typeof(object)); } il.Emit(OpCodes.Ldc_I8, method_token); il.Emit(OpCodes.Ldloc, loc_target); il.Emit(OpCodes.Ldloc, loc_args); il.Emit(OpCodes.Call, _HandleDispatchMethod); if (!method_returns) { il.Emit(OpCodes.Pop); } if (method_returns && method is MethodInfo && ((MethodInfo)method).ReturnType.IsValueType) { il.Emit(OpCodes.Unbox_Any, ((MethodInfo)method).ReturnType); } il.Emit(OpCodes.Ret); RuntimeDetour.Detour( from: method, to: dm ); _Trampolines[method_token] = RuntimeDetour.CreateOrigTrampoline(method); _DispatchHandlers.Add(method_token); _Logger.Debug($"Installed dispatch handler for {method.Name} (token {method_token})"); }
public override void Unload() { // Let's just hope that nothing else detoured this, as this is depth-based... RuntimeDetour.Undetour(m_Update); }
internal static bool TestRuntimeDetourHelper() { MethodInfo m_PrintA = typeof(ModRuntimePatcher).GetMethod("PrintA", BindingFlags.NonPublic | BindingFlags.Static); MethodInfo m_PrintB = typeof(ModRuntimePatcher).GetMethod("PrintB", BindingFlags.NonPublic | BindingFlags.Static); MethodInfo m_PrintC = typeof(ModRuntimePatcher).GetMethod("PrintC", BindingFlags.NonPublic | BindingFlags.Static); MethodInfo m_PrintATrampoline = typeof(ModRuntimePatcher).GetMethod("PrintATrampoline", BindingFlags.NonPublic | BindingFlags.Static); PrintA(); // A d_PrintA t_FromB = m_PrintA.Detour <d_PrintA>(m_PrintB); PrintA(); // B t_FromB(); // A unsafe { m_PrintATrampoline.Detour( RuntimeDetour.CreateTrampoline(m_PrintA) ); PrintATrampoline(); // A } d_PrintA t_FromC = m_PrintA.Detour <d_PrintA>((Action)PrintC); PrintA(); // C t_FromC(); // B m_PrintA.GetOrigTrampoline <d_PrintA>()(); // A m_PrintB.Detour(m_PrintC); PrintB(); // C m_PrintB.Detour((Action)PrintD); PrintB(); // D m_PrintA.Undetour(); m_PrintA.Undetour(); PrintA(); // A MethodInfo m_PrintQDTO = typeof(QuickDebugTestObject).GetMethod("PrintQDTO", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); MethodInfo m_PrintQDTODetour = typeof(ModRuntimePatcher).GetMethod("PrintQDTODetour", BindingFlags.NonPublic | BindingFlags.Static); MethodInfo m_PrintQDTOTrampoline = typeof(ModRuntimePatcher).GetMethod("PrintQDTOTrampoline", BindingFlags.NonPublic | BindingFlags.Static); QuickDebugTestObject qdto = new QuickDebugTestObject(); qdto.PrintQDTO(); // QDTO d_PrintQDTO t_FromQDTO = m_PrintQDTO.Detour <d_PrintQDTO>(m_PrintQDTODetour); qdto.PrintQDTO(); // QDTO Detour t_FromQDTO(qdto); // QDTO unsafe { m_PrintQDTOTrampoline.Detour( RuntimeDetour.CreateTrampoline(m_PrintQDTO) ); PrintQDTOTrampoline(qdto); // QDTO } return(true); }
public override void Unload() { RuntimeDetour.Undetour(m_RegisterCompletion); }