| 104 | } |
| 105 | |
| 106 | int HookIATProcedure(HMODULE hModule, LPCSTR procName, FARPROC replacement) { |
| 107 | if (hModule == nullptr || procName == nullptr || replacement == nullptr) { |
| 108 | LOGE(L"HookIATProcedure: invalid arguments: hModule=%p, procName=%hs, replacement=%p", |
| 109 | hModule, procName ? procName : "(NULL)", replacement); |
| 110 | return 0; |
| 111 | } |
| 112 | LOGI(L"HookIATProcedure: start, hModule=%p, procName=%hs, replacement=%p", hModule, procName, replacement); |
| 113 | PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER) hModule; |
| 114 | PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS) ((BYTE *) hModule + pDosHeader->e_lfanew); |
| 115 | PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR) |
| 116 | ((BYTE *) hModule + pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); |
| 117 | int count = 0; |
| 118 | for (; pImportDesc->Name != 0; pImportDesc++) { |
| 119 | PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA) ((BYTE *) hModule + pImportDesc->FirstThunk); |
| 120 | PIMAGE_THUNK_DATA pOrgThunk = (PIMAGE_THUNK_DATA) ((BYTE *) hModule + pImportDesc->OriginalFirstThunk); |
| 121 | for (; pThunk->u1.Function != 0; pThunk++, pOrgThunk++) { |
| 122 | if (IMAGE_SNAP_BY_ORDINAL(pOrgThunk->u1.Ordinal)) { |
| 123 | continue; |
| 124 | } |
| 125 | PIMAGE_IMPORT_BY_NAME pImport = (PIMAGE_IMPORT_BY_NAME) ((BYTE *) hModule + pOrgThunk->u1.AddressOfData); |
| 126 | if (!isAddressReadable((char *) pImport->Name)) { |
| 127 | LOGE(L"HookIATProcedure: pImport->Name is not readable: %p", pImport->Name); |
| 128 | WCHAR buffer[1024] = {}; |
| 129 | GetModuleFileNameW(hModule, buffer, _countof(buffer)); |
| 130 | LOGE(L"HookIATProcedure: abort IAT hook, hModule=%s(%p), procName=%hs, replacement=%p", |
| 131 | buffer, hModule, procName, replacement); |
| 132 | return -1; |
| 133 | } |
| 134 | if (strcmp((char *) pImport->Name, procName) == 0) { |
| 135 | LOGI(L"HookIATProcedure: Found %hs at %p", procName, pThunk); |
| 136 | DWORD oldProtect = 0; |
| 137 | VirtualProtect(pThunk, sizeof(PVOID), PAGE_READWRITE, &oldProtect); |
| 138 | pThunk->u1.Function = (DWORD_PTR) replacement; |
| 139 | VirtualProtect(pThunk, sizeof(PVOID), oldProtect, &oldProtect); |
| 140 | count++; |
| 141 | } |
| 142 | } |
| 143 | } |
| 144 | LOGI(L"HookIATProcedure: end, count=%d", count); |
| 145 | return count; |
| 146 | } |
| 147 | |
| 148 | void checkEnableDebugConsole() { |
| 149 | WCHAR exePath[1024] = {}; |
no test coverage detected