コード例 #1
0
        /// <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)
        {
            var state = new RedirectCallsState();

            // R11 is volatile.
            unsafe
            {
                var 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;
        }
コード例 #2
0
        public static void Deploy()
        {
            if (!deployed)
            {
                // Called when placing/removing roads
                // one of these also affects the combined LOD mesh
                // NetLane.CalculateGroupData
                // NetLane.PopulateGroupData
                // NetLane.RereshInstance - init/render

                // Called when rendering detailed net
                // NetLane.RenderInstance - render

                _NetLane_RefreshInstance_original = typeof(NetLane).GetMethod("RefreshInstance", BindingFlags.Instance | BindingFlags.Public);
                _NetLane_RefreshInstance_detour = typeof(NetLaneDetour).GetMethod("RefreshInstance", BindingFlags.Instance | BindingFlags.Public);
                _NetLane_RefreshInstance_state = RedirectionHelper.RedirectCalls(_NetLane_RefreshInstance_original, _NetLane_RefreshInstance_detour);

                _NetLane_RenderInstance_original = typeof(NetLane).GetMethod("RenderInstance", BindingFlags.Instance | BindingFlags.Public);
                _NetLane_RenderInstance_detour = typeof(NetLaneDetour).GetMethod("RenderInstance", BindingFlags.Instance | BindingFlags.Public);
                _NetLane_RenderInstance_state = RedirectionHelper.RedirectCalls(_NetLane_RenderInstance_original, _NetLane_RenderInstance_detour);

                _NetLane_CalculateGroupData_original = typeof(NetLane).GetMethod("CalculateGroupData", BindingFlags.Instance | BindingFlags.Public);
                _NetLane_CalculateGroupData_detour = typeof(NetLaneDetour).GetMethod("CalculateGroupData", BindingFlags.Instance | BindingFlags.Public);
                _NetLane_CalculateGroupData_state = RedirectionHelper.RedirectCalls(_NetLane_CalculateGroupData_original, _NetLane_CalculateGroupData_detour);

                _NetLane_PopulateGroupData_original = typeof(NetLane).GetMethod("PopulateGroupData", BindingFlags.Instance | BindingFlags.Public);
                _NetLane_PopulateGroupData_detour = typeof(NetLaneDetour).GetMethod("PopulateGroupData", BindingFlags.Instance | BindingFlags.Public);
                _NetLane_PopulateGroupData_state = RedirectionHelper.RedirectCalls(_NetLane_PopulateGroupData_original, _NetLane_PopulateGroupData_detour);

                deployed = true;
            }
        }
コード例 #3
0
        public static void Deploy()
        {
            if (deployed) return;

            _RenderManager_UpdateData_original = typeof(RenderManager).GetMethod("UpdateData", BindingFlags.Instance | BindingFlags.Public);
            _RenderManager_UpdateData_detour = typeof(RenderManagerDetour).GetMethod("UpdateData", BindingFlags.Instance | BindingFlags.Public);
            _RenderManager_UpdateData_state = RedirectionHelper.RedirectCalls(_RenderManager_UpdateData_original, _RenderManager_UpdateData_detour);

            deployed = true;
        }
コード例 #4
0
        public static void Deploy()
        {
            if (!deployed)
            {
                _NetLane_RenderInstance_original = typeof(NetSegment).GetMethod("RenderInstance", BindingFlags.Instance | BindingFlags.NonPublic);
                _NetLane_RenderInstance_detour = typeof(NetSegmentDetour).GetMethod("RenderInstance", BindingFlags.Instance | BindingFlags.NonPublic);
                _NetLane_RenderInstance_state = RedirectionHelper.RedirectCalls(_NetLane_RenderInstance_original, _NetLane_RenderInstance_detour);

                deployed = true;
            }
        }
コード例 #5
0
        public static void Deploy()
        {
            if (deployed) return;

            _NetManager_CreateSegment_original = typeof(NetManager).GetMethod("CreateSegment", BindingFlags.Instance | BindingFlags.Public);
            _NetManager_CreateSegment_detour = typeof(NetManagerDetour).GetMethod("CreateSegment", BindingFlags.Instance | BindingFlags.Public);
            _NetManager_CreateSegment_state = RedirectionHelper.RedirectCalls(_NetManager_CreateSegment_original, _NetManager_CreateSegment_detour);

            _NetManager_ReleaseSegment_original = typeof(NetManager).GetMethod("ReleaseSegment", BindingFlags.Instance | BindingFlags.Public);
            _NetManager_ReleaseSegment_detour = typeof(NetManagerDetour).GetMethod("ReleaseSegment", BindingFlags.Instance | BindingFlags.Public);
            _NetManager_ReleaseSegment_state = RedirectionHelper.RedirectCalls(_NetManager_ReleaseSegment_original, _NetManager_ReleaseSegment_detour);

            deployed = true;
        }
コード例 #6
0
 public static void RevertRedirect(MethodInfo from, RedirectCallsState state)
 {
     var fptr1 = from.MethodHandle.GetFunctionPointer();
     RevertJumpTo(fptr1, state);
 }
コード例 #7
0
 public static void RevertJumpTo(IntPtr site, RedirectCallsState state)
 {
     unsafe
     {
         var 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;
     }
 }
コード例 #8
0
        public static void RevertRedirect(MethodInfo from, RedirectCallsState state)
        {
            var fptr1 = from.MethodHandle.GetFunctionPointer();

            RevertJumpTo(fptr1, state);
        }