/// <summary> /// Primitive patching. Inserts a jump to 'target' at 'site'. Works even if both methods' /// callers have already been compiled. /// </summary> /// <param name="site"></param> /// <param name="target"></param> public static RedirectCallsState PatchJumpTo(IntPtr site, IntPtr target) { RedirectCallsState state = new RedirectCallsState(); // R11 is volatile. unsafe { byte* sitePtr = (byte*)site.ToPointer(); state.a = *sitePtr; state.b = *(sitePtr + 1); state.c = *(sitePtr + 10); state.d = *(sitePtr + 11); state.e = *(sitePtr + 12); state.f = *((ulong*) (sitePtr + 2)); *sitePtr = 0x49; // mov r11, target *(sitePtr + 1) = 0xBB; *((ulong*)(sitePtr + 2)) = (ulong)target.ToInt64(); *(sitePtr + 10) = 0x41; // jmp r11 *(sitePtr + 11) = 0xFF; *(sitePtr + 12) = 0xE3; } return state; }
public static void Deploy() { if (!deployed) { _InitializePrefab_original = typeof(BuildingInfo).GetMethod("InitializePrefab", BindingFlags.Instance | BindingFlags.Public); _InitializePrefab_detour = typeof(BuildingInfoDetour).GetMethod("InitializePrefab", BindingFlags.Instance | BindingFlags.Public); _InitializePrefab_state = RedirectionHelper.RedirectCalls(_InitializePrefab_original, _InitializePrefab_detour); deployed = true; Debugger.Log("Building Themes: BuildingInfo Methods detoured!"); } }
public static void Deploy() { if (!deployed) { _BuildingManager_GetRandomBuildingInfo_original = typeof(BuildingManager).GetMethod("GetRandomBuildingInfo", BindingFlags.Instance | BindingFlags.Public); _BuildingManager_GetRandomBuildingInfo_detour = typeof(BuildingManagerDetour).GetMethod("GetRandomBuildingInfo", BindingFlags.Instance | BindingFlags.Public); _BuildingManager_GetRandomBuildingInfo_state = RedirectionHelper.RedirectCalls(_BuildingManager_GetRandomBuildingInfo_original, _BuildingManager_GetRandomBuildingInfo_detour); deployed = true; Debugger.Log("Building Themes: BuildingManager Methods detoured!"); } }
public static void Deploy() { if (!deployed) { _original = typeof(DistrictWorldInfoPanel).GetMethod("OnPoliciesClick", BindingFlags.Instance | BindingFlags.Public); _detour = typeof(DistrictWorldInfoPanelDetour).GetMethod("OnPoliciesClick", BindingFlags.Instance | BindingFlags.Public); _state = RedirectionHelper.RedirectCalls(_original, _detour); deployed = true; Debugger.Log("Building Themes: DistrictWorldInfoPanel Methods detoured!"); } }
public static void Deploy() { if (!deployed) { _DistrictManager_ReleaseDistrictImplementation_original = typeof(DistrictManager).GetMethod("ReleaseDistrictImplementation", BindingFlags.Instance | BindingFlags.NonPublic); _DistrictManager_ReleaseDistrictImplementation_detour = typeof(DistrictManagerDetour).GetMethod("ReleaseDistrictImplementation", BindingFlags.Instance | BindingFlags.NonPublic); _DistrictManager_ReleaseDistrictImplementation_state = RedirectionHelper.RedirectCalls(_DistrictManager_ReleaseDistrictImplementation_original, _DistrictManager_ReleaseDistrictImplementation_detour); deployed = true; Debugger.Log("Building Themes: DistrictManager Methods detoured!"); } }
public static void Deploy() { if (!deployed) { _ImmaterialResourceManager_AddResource_original = typeof(ImmaterialResourceManager).GetMethod("AddResource", new[] { typeof(ImmaterialResourceManager.Resource), typeof(int), typeof(Vector3), typeof(float) }); _ImmaterialResourceManager_AddResource_detour = typeof(ImmaterialResourceManagerDetour).GetMethod("AddResource", BindingFlags.Instance | BindingFlags.Public); _ImmaterialResourceManager_AddResource_state = RedirectionHelper.RedirectCalls(_ImmaterialResourceManager_AddResource_original, _ImmaterialResourceManager_AddResource_detour); deployed = true; Debugger.Log("Building Themes: ImmaterialResourceManager Methods detoured!"); } }
public static void Deploy() { if (deployed || Util.IsModActive(BuildingThemesMod.EIGHTY_ONE_MOD)) { Debugger.Log("Building Themes: ImmaterialResourceManager Methods won't be detoured: 81 Tiles detected"); return; } _ImmaterialResourceManager_AddResource_original = typeof(ImmaterialResourceManager).GetMethod("AddResource", new[] { typeof(ImmaterialResourceManager.Resource), typeof(int), typeof(Vector3), typeof(float) }); _ImmaterialResourceManager_AddResource_detour = typeof(ImmaterialResourceManagerDetour).GetMethod("AddResource", BindingFlags.Instance | BindingFlags.Public); _ImmaterialResourceManager_AddResource_state = RedirectionHelper.RedirectCalls(_ImmaterialResourceManager_AddResource_original, _ImmaterialResourceManager_AddResource_detour); deployed = true; Debugger.Log("Building Themes: ImmaterialResourceManager Methods detoured!"); }
public static void Deploy() { if (!deployed) { _ZoneBlock_SimulationStep_original = typeof(ZoneBlock).GetMethod("SimulationStep", BindingFlags.Public | BindingFlags.Instance); _ZoneBlock_SimulationStep_detour = typeof(ZoneBlockDetour).GetMethod("SimulationStep", BindingFlags.Instance | BindingFlags.Public); _ZoneBlock_SimulationStep_state = RedirectionHelper.RedirectCalls(_ZoneBlock_SimulationStep_original, _ZoneBlock_SimulationStep_detour); _CheckBlock = typeof(ZoneBlock).GetMethod("CheckBlock", BindingFlags.NonPublic | BindingFlags.Instance); _IsGoodPlace = typeof(ZoneBlock).GetMethod("IsGoodPlace", BindingFlags.NonPublic | BindingFlags.Instance); deployed = true; Debugger.Log("Building Themes: ZoneBlock Methods detoured!"); } }
public static void Deploy() { if (!deployed) { _PoliciesPanel_RefreshPanel_original = typeof(PoliciesPanel).GetMethod("RefreshPanel", BindingFlags.Instance | BindingFlags.NonPublic); _PoliciesPanel_RefreshPanel_detour = typeof(PoliciesPanelDetour).GetMethod("RefreshPanel", BindingFlags.Instance | BindingFlags.NonPublic); _PoliciesPanel_RefreshPanel_state = RedirectionHelper.RedirectCalls(_PoliciesPanel_RefreshPanel_original, _PoliciesPanel_RefreshPanel_detour); _PoliciesPanel_SetParentButton_original = typeof(PoliciesPanel).GetMethod("SetParentButton", BindingFlags.Instance | BindingFlags.Public); _PoliciesPanel_SetParentButton_detour = typeof(PoliciesPanelDetour).GetMethod("SetParentButton", BindingFlags.Instance | BindingFlags.Public); _PoliciesPanel_SetParentButton_state = RedirectionHelper.RedirectCalls(_PoliciesPanel_SetParentButton_original, _PoliciesPanel_SetParentButton_detour); deployed = true; Debugger.Log("Building Themes: PoliciesPanel Methods detoured!"); } }
public static void Deploy() { if (!deployed) { _ZoneBlock_SimulationStep_original = typeof(ZoneBlock).GetMethod("SimulationStep", BindingFlags.Public | BindingFlags.Instance); _ZoneBlock_SimulationStep_detour = typeof(ZoneBlockDetour).GetMethod("SimulationStep", BindingFlags.Static | BindingFlags.Public); _ZoneBlock_SimulationStep_state = RedirectionHelper.RedirectCalls(_ZoneBlock_SimulationStep_original, _ZoneBlock_SimulationStep_detour); _CheckBlock = typeof(ZoneBlock).GetMethod("CheckBlock", BindingFlags.NonPublic | BindingFlags.Instance); _IsGoodPlace = typeof(ZoneBlock).GetMethod("IsGoodPlace", BindingFlags.NonPublic | BindingFlags.Instance); if (Util.IsModActive(BuildingThemesMod.EIGHTY_ONE_MOD)) { _zoneGridResolution = EIGHTY_ONE_ZONEGRID_RESOLUTION; _zoneGridHalfResolution = EIGHTY_ONE_HALF_ZONEGRID_RESOLUTION; } deployed = true; Debugger.Log("Building Themes: ZoneBlock Methods detoured!"); } }
public static void RevertRedirect(MethodInfo from, RedirectCallsState state) { var fptr1 = from.MethodHandle.GetFunctionPointer(); RevertJumpTo(fptr1, state); }
public static void RevertJumpTo(IntPtr site, RedirectCallsState state) { unsafe { byte* sitePtr = (byte*)site.ToPointer(); *sitePtr = state.a; // mov r11, target *(sitePtr + 1) = state.b; *((ulong*)(sitePtr + 2)) = state.f; *(sitePtr + 10) = state.c; // jmp r11 *(sitePtr + 11) = state.d; *(sitePtr + 12) = state.e; } }