/// <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> private 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; }
public static void Deploy() { Debug.Log("Detouring Input Methods"); if (_isPressedOriginal == null) { throw new NullReferenceException("Original IsPressed method not found"); } if (_isKeyUpOriginal == null) { throw new NullReferenceException("Original IsKeyUp method not found"); } if (_isPressedReplacement == null) { throw new NullReferenceException("New IsPressed method not found"); } if (_isKeyUpReplacement == null) { throw new NullReferenceException("New IsKeyUp method not found"); } _revertState1 = RedirectionHelper.RedirectCalls(_isPressedOriginal, _isPressedReplacement); _revertState2 = RedirectionHelper.RedirectCalls(_isKeyUpOriginal, _isKeyUpReplacement); }
public static void Deploy() { if (_isDeployed) return; _snapDirectionRevertState = RedirectionHelper.RedirectCalls(SnapDirectionOriginalMethodInfo, SnapDirectionOverrideMethodInfo); _snapRevertState = RedirectionHelper.RedirectCalls(SnapOriginalMethodInfo, SnapOverrideMethodInfo); _isDeployed = true; }
public static void Deploy() { if (_originalGetLengthSnapMethodInfo == null) { throw new NullReferenceException("Original GetLengthSnap method not found"); } if (_newGetLengthSnapMethodInfo == null) { throw new NullReferenceException("New GetLengthSnap method not found"); } _revertState = RedirectionHelper.RedirectCalls(_originalGetLengthSnapMethodInfo, _newGetLengthSnapMethodInfo); }
private 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; } }
public static void RevertRedirect(MethodInfo from, RedirectCallsState state) { var fptr1 = from.MethodHandle.GetFunctionPointer(); RevertJumpTo(fptr1, state); }