| 817 | } |
| 818 | |
| 819 | bool OverrideFunctionWithTrampoline( |
| 820 | uptr old_func, uptr new_func, uptr *orig_old_func) { |
| 821 | |
| 822 | size_t instructions_length = kBranchLength; |
| 823 | size_t padding_length = 0; |
| 824 | uptr indirect_address = 0; |
| 825 | |
| 826 | if (orig_old_func) { |
| 827 | // Find out the number of bytes of the instructions we need to copy |
| 828 | // to the trampoline. |
| 829 | instructions_length = RoundUpToInstrBoundary(kBranchLength, old_func); |
| 830 | if (!instructions_length) |
| 831 | return false; |
| 832 | |
| 833 | // Put the needed instructions into the trampoline bytes. |
| 834 | uptr trampoline_length = instructions_length + kDirectBranchLength; |
| 835 | uptr trampoline = AllocateMemoryForTrampoline(old_func, trampoline_length); |
| 836 | if (!trampoline) |
| 837 | return false; |
| 838 | if (!CopyInstructions(trampoline, old_func, instructions_length)) |
| 839 | return false; |
| 840 | WriteDirectBranch(trampoline + instructions_length, |
| 841 | old_func + instructions_length); |
| 842 | *orig_old_func = trampoline; |
| 843 | } |
| 844 | |
| 845 | #if SANITIZER_WINDOWS64 |
| 846 | // Check if the targeted address can be encoded in the function padding. |
| 847 | // Otherwise, allocate it in the trampoline region. |
| 848 | if (IsMemoryPadding(old_func - kAddressLength, kAddressLength)) { |
| 849 | indirect_address = old_func - kAddressLength; |
| 850 | padding_length = kAddressLength; |
| 851 | } else { |
| 852 | indirect_address = AllocateMemoryForTrampoline(old_func, kAddressLength); |
| 853 | if (!indirect_address) |
| 854 | return false; |
| 855 | } |
| 856 | #endif |
| 857 | |
| 858 | // Change memory protection to writable. |
| 859 | uptr patch_address = old_func - padding_length; |
| 860 | uptr patch_length = instructions_length + padding_length; |
| 861 | DWORD protection = 0; |
| 862 | if (!ChangeMemoryProtection(patch_address, patch_length, &protection)) |
| 863 | return false; |
| 864 | |
| 865 | // Patch the original function. |
| 866 | WriteBranch(old_func, indirect_address, new_func); |
| 867 | |
| 868 | // Restore previous memory protection. |
| 869 | if (!RestoreMemoryProtection(patch_address, patch_length, protection)) |
| 870 | return false; |
| 871 | |
| 872 | return true; |
| 873 | } |
| 874 | |
| 875 | bool OverrideFunction( |
| 876 | uptr old_func, uptr new_func, uptr *orig_old_func) { |
no test coverage detected