public void CallPatchedRIPRelativeReturnJump() { // Build RIP Relative Jump to ReturnSix var buffer = Utilities.FindOrCreateBufferInRange(100); long jmpTarget = (long)_dummyFunctions.ReturnSix; var ripRelativeJmp = new string[] { $"{_use32}", $"jmp qword [rip + 0]" // FASM offsets from end of instruction. }; var asm = _assembler.Assemble(ripRelativeJmp); var relativePtr = buffer.Add(asm); buffer.Add(ref jmpTarget, false, 1); // TODO: Hack! SharpDisasm does not correctly disasm multiple `jmp [rip + 0]` opcodes in sequence because of mixing code + data (pointer). // See other instance of this for notes. byte[] int3Bytes = { 0xCC, 0xCC, 0xCC, 0xCC }; buffer.Add(int3Bytes); // Create a wrapper and call to confirm jump works. var wrapper = Wrapper.Create <DummyFunctions.ReturnNumberDelegate>((long)relativePtr); Assert.Equal(DummyFunctions.Six, wrapper()); // Now try to retarget jump to ReturnFive var patcher = new FunctionPatcher(ArchitectureMode); long searchTarget = jmpTarget; FunctionPatcherTesting.GetSearchRange(patcher, ref searchTarget, out long searchLength); var patches = FunctionPatcherTesting.PatchJumpTargets(patcher, new AddressRange(searchTarget, searchTarget + searchLength), new AddressRange(jmpTarget, jmpTarget), (long)_dummyFunctions.ReturnFive); Assert.True(patches.Count > 0); foreach (var patch in patches) { patch.Apply(); } Assert.Equal(DummyFunctions.Five, wrapper()); }
public void CallPatchedPushReturnReturnJump() { // Build RIP Relative Jump to ReturnSix var buffer = Utilities.FindOrCreateBufferInRange(100); long jmpTarget = (long)_dummyFunctions.ReturnSix; var pushReturnJmp = new string[] { $"{_use32}", $"push {jmpTarget}", "ret" }; var asm = _assembler.Assemble(pushReturnJmp); var pushReturnPtr = buffer.Add(asm); // Create a wrapper and call to confirm jump works. var wrapper = Wrapper.Create <DummyFunctions.ReturnNumberDelegate>((long)pushReturnPtr); Assert.Equal(DummyFunctions.Six, wrapper()); // Now try to retarget jump to ReturnFive var patcher = new FunctionPatcher(ArchitectureMode); long searchTarget = jmpTarget; FunctionPatcherTesting.GetSearchRange(patcher, ref searchTarget, out long searchLength); var patches = FunctionPatcherTesting.PatchJumpTargets(patcher, new AddressRange(searchTarget, searchTarget + searchLength), new AddressRange(jmpTarget, jmpTarget), (long)_dummyFunctions.ReturnFive); Assert.True(patches.Count > 0); foreach (var patch in patches) { patch.Apply(); } Assert.Equal(DummyFunctions.Five, wrapper()); }
public void CallPatchedPushReturnReturnJump() { // Build RIP Relative Jump to ReturnSix var buffer = Utilities.FindOrCreateBufferInRange(100); nuint jmpTarget = _dummyFunctions.ReturnSix; var pushReturnJmp = new string[] { $"{Macros._use32}", $"push {jmpTarget}", "ret" }; var asm = _assembler.Assemble(pushReturnJmp); var pushReturnPtr = buffer.Add(asm); // Create a wrapper and call to confirm jump works. var wrapper = ReloadedHooks.Instance.CreateWrapper <DummyFunctions.ReturnNumberDelegate>((long)pushReturnPtr, out _); Assert.Equal(DummyFunctions.Six, wrapper()); // Now try to retarget jump to ReturnFive var patcher = new FunctionPatcher(Environment.Is64BitProcess); nuint searchTarget = jmpTarget; FunctionPatcherTesting.GetSearchRange(patcher, ref searchTarget, out nuint searchLength); var patches = FunctionPatcherTesting.PatchJumpTargets(patcher, new AddressRange(searchTarget, searchTarget + searchLength), new AddressRange(jmpTarget, jmpTarget), _dummyFunctions.ReturnFive); Assert.True(patches.Count > 0); foreach (var patch in patches) { patch.Apply(); } Assert.Equal(DummyFunctions.Five, wrapper()); }
public void CallPatchedRelativeReturnJump() { // Build RIP Relative Jump to ReturnSix var buffer = Utilities.FindOrCreateBufferInRange(100); long jmpTarget = (long)_dummyFunctions.ReturnSix; var relativeJmp = new string[] { $"{Macros._use32}", $"jmp {(long)jmpTarget - (long)buffer.Properties.WritePointer}", // FASM relative offsets are relative to start of instruction. }; var asm = _assembler.Assemble(relativeJmp); var relativePtr = buffer.Add(asm, 1); // Create a wrapper and call to confirm jump works. var wrapper = ReloadedHooks.Instance.CreateWrapper <DummyFunctions.ReturnNumberDelegate>((long)relativePtr, out _); Assert.Equal(DummyFunctions.Six, wrapper()); // Now try to retarget jump to ReturnFive var patcher = new FunctionPatcher(ArchitectureMode); long searchTarget = jmpTarget; FunctionPatcherTesting.GetSearchRange(patcher, ref searchTarget, out long searchLength); var patches = FunctionPatcherTesting.PatchJumpTargets(patcher, new AddressRange(searchTarget, searchTarget + searchLength), new AddressRange(jmpTarget, jmpTarget), (long)_dummyFunctions.ReturnFive); Assert.True(patches.Count > 0); foreach (var patch in patches) { patch.Apply(); } Assert.Equal(DummyFunctions.Five, wrapper()); }