| 732 | #endif |
| 733 | |
| 734 | bool OverrideFunctionWithRedirectJump( |
| 735 | uptr old_func, uptr new_func, uptr *orig_old_func) { |
| 736 | // Check whether the first instruction is a relative jump. |
| 737 | if (*(u8*)old_func != 0xE9) |
| 738 | return false; |
| 739 | |
| 740 | if (orig_old_func) { |
| 741 | uptr relative_offset = *(u32*)(old_func + 1); |
| 742 | uptr absolute_target = old_func + relative_offset + kJumpInstructionLength; |
| 743 | *orig_old_func = absolute_target; |
| 744 | } |
| 745 | |
| 746 | #if SANITIZER_WINDOWS64 |
| 747 | // If needed, get memory space for a trampoline jump. |
| 748 | uptr trampoline = AllocateMemoryForTrampoline(old_func, kDirectBranchLength); |
| 749 | if (!trampoline) |
| 750 | return false; |
| 751 | WriteDirectBranch(trampoline, new_func); |
| 752 | #endif |
| 753 | |
| 754 | // Change memory protection to writable. |
| 755 | DWORD protection = 0; |
| 756 | if (!ChangeMemoryProtection(old_func, kJumpInstructionLength, &protection)) |
| 757 | return false; |
| 758 | |
| 759 | // Write a relative jump to the redirected function. |
| 760 | WriteJumpInstruction(old_func, FIRST_32_SECOND_64(new_func, trampoline)); |
| 761 | |
| 762 | // Restore previous memory protection. |
| 763 | if (!RestoreMemoryProtection(old_func, kJumpInstructionLength, protection)) |
| 764 | return false; |
| 765 | |
| 766 | return true; |
| 767 | } |
| 768 | |
| 769 | bool OverrideFunctionWithHotPatch( |
| 770 | uptr old_func, uptr new_func, uptr *orig_old_func) { |
no test coverage detected