| 697 | |
| 698 | #if !SANITIZER_WINDOWS64 |
| 699 | bool OverrideFunctionWithDetour( |
| 700 | uptr old_func, uptr new_func, uptr *orig_old_func) { |
| 701 | const int kDetourHeaderLen = 5; |
| 702 | const u16 kDetourInstruction = 0xFF8B; |
| 703 | |
| 704 | uptr header = (uptr)old_func - kDetourHeaderLen; |
| 705 | uptr patch_length = kDetourHeaderLen + kShortJumpInstructionLength; |
| 706 | |
| 707 | // Validate that the function is hookable. |
| 708 | if (*(u16*)old_func != kDetourInstruction || |
| 709 | !IsMemoryPadding(header, kDetourHeaderLen)) |
| 710 | return false; |
| 711 | |
| 712 | // Change memory protection to writable. |
| 713 | DWORD protection = 0; |
| 714 | if (!ChangeMemoryProtection(header, patch_length, &protection)) |
| 715 | return false; |
| 716 | |
| 717 | // Write a relative jump to the redirected function. |
| 718 | WriteJumpInstruction(header, new_func); |
| 719 | |
| 720 | // Write the short jump to the function prefix. |
| 721 | WriteShortJumpInstruction(old_func, header); |
| 722 | |
| 723 | // Restore previous memory protection. |
| 724 | if (!RestoreMemoryProtection(header, patch_length, protection)) |
| 725 | return false; |
| 726 | |
| 727 | if (orig_old_func) |
| 728 | *orig_old_func = old_func + kShortJumpInstructionLength; |
| 729 | |
| 730 | return true; |
| 731 | } |
| 732 | #endif |
| 733 | |
| 734 | bool OverrideFunctionWithRedirectJump( |
no test coverage detected