/// <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;
     }
 }
Beispiel #13
0
        public static void RevertRedirect(MethodInfo from, RedirectCallsState state)
        {
            var fptr1 = from.MethodHandle.GetFunctionPointer();

            RevertJumpTo(fptr1, state);
        }