20 BOOL
nt_protect(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect)
24 "NtProtectVirtualMemory"
29 NTSTATUS(NTAPI *_NtProtectVirtualMemory)(
42 SIZE_T protect_size = dwSize;
43 NTSTATUS
status = _NtProtectVirtualMemory(GetCurrentProcess(), &lpAddress, &protect_size, flNewProtect, lpflOldProtect);
58 this->
buffer =
new BYTE[patch_size];
61 memcpy(
buffer, patch_ptr, patch_size);
86 std::map<std::string, FARPROC>::const_iterator itr = hooks_map.find(func_name);
87 if (itr != hooks_map.end()) {
88 FARPROC hook = itr->second;
89 LOG_DEBUG(
"Replacing: %s by: %p.", func_name, hook);
95 std::map<std::string, std::string>::const_iterator itr2 = this->dll_replacements_map.find(lib_name_str);
96 if (itr2 != dll_replacements_map.end()) {
97 const std::string &name = itr2->second;
98 LOG_DEBUG(
"Replacing DLL: %s by: %s.", lib_name_str.c_str(), name.c_str());
109 0x48, 0xB8, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xEE, 0xFF,
112 const size_t hook64_size =
sizeof(hook_64);
114 LOG_WARNING(
"Patching NTDLL is not allowed because of possible stability issues.");
117 DWORD oldProtect = 0;
120 PAGE_EXECUTE_READWRITE,
126 if (backup !=
nullptr) {
129 memcpy(hook_64 + 2, &new_offset,
sizeof(ULONGLONG));
130 memcpy(ptr, hook_64, hook64_size);
132 nt_protect((LPVOID)ptr, hook64_size, oldProtect, &oldProtect);
135 FlushInstructionCache(GetCurrentProcess(), ptr, hook64_size);
144 0xB8, 0xCC, 0xDD, 0xEE, 0xFF,
147 const size_t hook32_size =
sizeof(hook_32);
149 LOG_WARNING(
"Patching NTDLL is not allowed because of possible stability issues.");
152 DWORD oldProtect = 0;
155 PAGE_EXECUTE_READWRITE,
161 if (backup !=
nullptr) {
164 memcpy(hook_32 + 1, &new_offset,
sizeof(DWORD));
165 memcpy(ptr, hook_32, hook32_size);
167 nt_protect((LPVOID)ptr, hook32_size, oldProtect, &oldProtect);
170 FlushInstructionCache(GetCurrentProcess(), ptr, hook32_size);
183inline long long int get_jmp_delta(ULONGLONG currVA,
int instrLen, ULONGLONG destVA)
185 long long int diff = destVA - (currVA + instrLen);
191 DWORD first_dw = delta >>
sizeof(DWORD) * 8;
195 const DWORD max_dword = DWORD(-1);
196 if (first_dw != max_dword) {
199 DWORD delta_dw = DWORD(delta);
200 if (delta_dw & 0x80000000) {
214 if (patch_ptr[0] == OP_JMP || patch_ptr[0] == OP_CALL_DWORD) {
215 ULONGLONG delta =
get_jmp_delta(ULONGLONG(patch_ptr), 5, dest_addr);
217 LOG_WARNING(
"Cannot replace the target: delta 0x%llx is too large for a DWORD.", (
unsigned long long)delta);
221 DWORD delta_dw = DWORD(delta);
222 memcpy(patch_ptr + 1, &delta_dw,
sizeof(DWORD));
225 FlushInstructionCache(GetCurrentProcess(), patch_ptr + 1,
sizeof(DWORD));
bool makeBackup(BYTE *patch_ptr, size_t patch_size)
virtual FARPROC resolve_func(LPCSTR lib_name, LPCSTR func_name)
virtual FARPROC resolve_func(LPCSTR lib_name, LPCSTR func_name)
long long int get_jmp_delta(ULONGLONG currVA, int instrLen, ULONGLONG destVA)
bool is_valid_delta(long long int delta)
Functions related to hooking the loaded PE. Reditecting/replacing a functions with another.
#define LOG_DEBUG(fmt,...)
#define LOG_WARNING(fmt,...)
HMODULE get_module_via_peb(IN OPTIONAL LPCWSTR module_name=nullptr)
BOOL nt_protect(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect)
bool validate_ptr(IN const void *buffer_bgn, IN size_t buffer_size, IN const void *field_bgn, IN size_t field_size)
bool is_pointer_in_ntdll(LPVOID lpAddress)
FARPROC get_exported_func(PVOID modulePtr, LPCSTR wanted_name)
size_t get_module_size_via_peb(IN OPTIONAL HMODULE hModule=nullptr)
bool is_bad_read_ptr(LPCVOID areaStart, SIZE_T areaSize)
bool replace_target(BYTE *ptr, ULONGLONG dest_addr)
size_t redirect_to_local32(void *ptr, DWORD new_offset, PatchBackup *backup=nullptr)
size_t redirect_to_local64(void *ptr, ULONGLONG new_offset, PatchBackup *backup=nullptr)
size_t redirect_to_local(void *ptr, void *new_function_ptr, PatchBackup *backup=nullptr)
Functions for retrieving process information from PEB.
Master include for LibPEConv.