diff options
author | Zeex <zeex@rocketmail.com> | 2023-02-10 00:00:32 +0600 |
---|---|---|
committer | Zeex <zeex@rocketmail.com> | 2023-02-10 00:02:01 +0600 |
commit | 85a2406774613c7aa942a41b5651c7af79f7c702 (patch) | |
tree | efba1620400e97d6f83c5bf14e246a79074ed6bb /subhook_windows.c | |
parent | 4f173b23239c017a9f3e53364fe371975aca2321 (diff) | |
download | subhook-85a2406774613c7aa942a41b5651c7af79f7c702.zip subhook-85a2406774613c7aa942a41b5651c7af79f7c702.tar.gz subhook-85a2406774613c7aa942a41b5651c7af79f7c702.tar.bz2 |
Add flag to support allocation of trampolines within 32-bit offset range of target code on 64-bit Windows
Plus minor formatting fixes and more documentation for flags.
Fixes #9
Diffstat (limited to 'subhook_windows.c')
-rw-r--r-- | subhook_windows.c | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/subhook_windows.c b/subhook_windows.c index 321207e..8c9b477 100644 --- a/subhook_windows.c +++ b/subhook_windows.c @@ -27,6 +27,8 @@ #include <stddef.h> #include <windows.h> +typedef __int64 QWORD; + #define SUBHOOK_CODE_PROTECT_FLAGS PAGE_EXECUTE_READWRITE int subhook_unprotect(void *address, size_t size) { @@ -38,7 +40,38 @@ int subhook_unprotect(void *address, size_t size) { return !result; } -void *subhook_alloc_code(size_t size) { +void *subhook_alloc_code(void *target_address, size_t size) { + SYSTEM_INFO sys_info; + DWORD page_size = 0x1000; + QWORD offset; + +#if defined _M_AMD64 || defined __amd64__ + if (target_address != NULL) { + GetSystemInfo(&sys_info); + page_size = sys_info.dwPageSize; + + QWORD pivot = (QWORD)target_address & ~((QWORD)page_size - 1); + void *result; + + for (offset = page_size; offset <= ((QWORD)1 << 31); offset += page_size) { + result = VirtualAlloc((void *)(pivot - offset), + size, + MEM_COMMIT | MEM_RESERVE, + SUBHOOK_CODE_PROTECT_FLAGS); + if (result != NULL) { + return result; + } + result = VirtualAlloc((void *)(pivot + offset), + size, + MEM_COMMIT | MEM_RESERVE, + SUBHOOK_CODE_PROTECT_FLAGS); + if (result != NULL) { + return result; + } + } + } +#endif + return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, |