| 108 | } |
| 109 | |
| 110 | bool khook::GetShadowSystemServiceTable() { |
| 111 | if (!_win32kTable) { |
| 112 | #ifndef _WIN64 |
| 113 | // x86 code |
| 114 | UNICODE_STRING name = RTL_CONSTANT_STRING(L"KeServiceDescriptorTable"); |
| 115 | _ntTable = (SystemServiceTable*)MmGetSystemRoutineAddress(&name); |
| 116 | _win32kTable = (SystemServiceTable*)((ULONG_PTR)_ntTable + 0x50); |
| 117 | #else |
| 118 | // x64 code |
| 119 | PEParser parser(_kernelImageBase); |
| 120 | for (int i = 0; parser.GetSectionCount(); i++) { |
| 121 | auto pSec = parser.GetSectionHeader(i); |
| 122 | if (pSec->Characteristics & IMAGE_SCN_MEM_NOT_PAGED && |
| 123 | pSec->Characteristics & IMAGE_SCN_MEM_EXECUTE && |
| 124 | !(pSec->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) && |
| 125 | (*(PULONG)pSec->Name != 'TINI') && |
| 126 | (*(PULONG)pSec->Name != 'EGAP')) { |
| 127 | ULONG_PTR searchAddr = (ULONG_PTR)((PUCHAR)_kernelImageBase + pSec->VirtualAddress); |
| 128 | ULONG_PTR maxAddress = searchAddr + pSec->Misc.VirtualSize; |
| 129 | // Find KiSystemServiceStart |
| 130 | UCHAR pattern[] = { 0x8B, 0xF8, 0xC1, 0xEF, 0x07, 0x83, 0xE7, 0x20, 0x25, 0xFF, 0x0F, 0x00, 0x00 }; |
| 131 | ULONG_PTR label = Helpers::SearchSignature(searchAddr, pattern, sizeof(pattern), pSec->Misc.VirtualSize); |
| 132 | if (label == 0) |
| 133 | return false; |
| 134 | searchAddr = label + sizeof(pattern); |
| 135 | UCHAR signature[] = { 0x4c,0x8d,0x1d }; |
| 136 | ULONG size = maxAddress - searchAddr; |
| 137 | ULONG_PTR addr = Helpers::SearchSignature(searchAddr, signature, sizeof(signature), size); |
| 138 | if (addr == 0) |
| 139 | return false; |
| 140 | ULONG_PTR offsetAddr = addr + sizeof(signature); |
| 141 | ULONG_PTR offset = 0; |
| 142 | memcpy(&offset, (void*)offsetAddr, 4); |
| 143 | if (offset == 0) { |
| 144 | return false; |
| 145 | } |
| 146 | _win32kTable = (SystemServiceTable*)(addr + offset + 7) + 1; |
| 147 | } |
| 148 | } |
| 149 | #endif // |
| 150 | } |
| 151 | |
| 152 | return true; |
| 153 | } |
| 154 | |
| 155 | |
| 156 | bool khook::GetSystemServiceTable() { |
nothing calls this directly
no test coverage detected