/* == 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); }
/* == 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; long initialSearchPointer = originalJmpTarget; GetSearchRange(ref initialSearchPointer, out long searchLength); /* Get original opcodes after original JMP instruction. */ IntPtr startRemainingOpcodes = (IntPtr)jumpDetails.JumpOpcodeEnd; int lengthRemainingOpcodes = (int)(newAddress - (long)startRemainingOpcodes); var remainingInstructions = TryReadFromMemory(startRemainingOpcodes, 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); // Catch all return addresses in page range. var pageRange = new AddressRange(initialSearchPointer, initialSearchPointer + searchLength); var jumpTargetRange = new AddressRange((long)startRemainingOpcodes, newAddress); patch.Patches = PatchJumpTargets(pageRange, originalJmpTarget, jumpTargetRange, newOriginalPrologue); }