/* == Patch Function == * * First a function stub is generated containing: * 1. Opcodes between Instruction.PC and "newAddress" * 2. a jmp to "newAddress". * * Then these functions look at the original JMP target and look for jumps back to * the end of the instruction. * * Patches are then generated that convert those jumps back to jumps to the location of * function stub. * * Patches are added to patch.Patches. */ private void PatchReturnAddresses(JumpDetails jumpDetails, FunctionPatch patch, long newAddress) { long originalJmpTarget = jumpDetails.JumpOpcodeTarget; GetSearchRange(ref originalJmpTarget, out long searchLength); /* Get original opcodes after original JMP instruction. */ IntPtr startRemainingOpcodes = (IntPtr)jumpDetails.JumpOpcodeEnd; int lengthRemainingOpcodes = (int)(newAddress - (long)startRemainingOpcodes); CurrentProcess.ReadRaw(startRemainingOpcodes, out byte[] remainingInstructions, lengthRemainingOpcodes); /* Build function stub + patches. */ // Must guarantee relative jumps to be patches can reach our new prologue // as such must get range of search first before creating stub. long maxDisplacement = Int32.MaxValue - searchLength; IntPtr newOriginalPrologue = Utilities.InsertJump(remainingInstructions, Is64Bit(), newAddress, originalJmpTarget, maxDisplacement); var patches = PatchJumpTargets(new AddressRange(originalJmpTarget, originalJmpTarget + searchLength), new AddressRange((long)startRemainingOpcodes, newAddress), (long)newOriginalPrologue); patch.Patches.AddRange(patches); }
public void CallRewrittenPushReturn() { var functionPatcher = new FunctionPatcher(ArchitectureMode); CurrentProcess.ReadRaw(_pushReturnPtr, out byte[] originalBytes, _pushReturnLength); var patch = functionPatcher.Patch(originalBytes.ToList(), _pushReturnPtr); var buffer = Utilities.FindOrCreateBufferInRange(patch.NewFunction.Count); var newFunctionAddress = buffer.Add(patch.NewFunction.ToArray()); var wrapper = Wrapper.Create <DummyFunctions.ReturnNumberDelegate>((long)newFunctionAddress); Assert.Equal(DummyFunctions.Five, wrapper()); }
/// <summary> /// Attempts to read out a number of bytes from unmanaged memory. /// </summary> /// <param name="address">Address to read from.</param> /// <param name="size">The size of memory.</param> private byte[] TryReadFromMemory(IntPtr address, int size) { byte[] memory; try { CurrentProcess.ReadRaw(address, out memory, size); } catch (Exception) { /* Ignore exception, and only take 2nd one. */ CurrentProcess.SafeReadRaw(address, out memory, size); } return(memory); }