在Windows10 高版本中 ,因为页表隔离补丁(?),__readmsr(0xC0000082) 返回KiSystemCall64Shadow,这玩意无法直接搜索到 KeServiceDescriptorTable,以前获取SystemServiceDescriptorTable的方法失效。
这里是新的,效果图。
代码抄的https://github.com/fIappy/infhook19041 嘤嘤嘤
核心代码如下:
NTSTATUS getKernelModuleByName(const char* moduleName, std::uintptr_t* moduleStart, std::size_t* moduleSize) {
if (!moduleStart || !moduleSize)
return STATUS_INVALID_PARAMETER;
std::size_t size{};
ZwQuerySystemInformation(0xB, nullptr, size, reinterpret_cast<PULONG>(&size));/* 0xB SystemModuleInformation */
const auto listHeader = ExAllocatePool(NonPagedPool, size);
if (!listHeader)
return STATUS_MEMORY_NOT_ALLOCATED;
if (const auto status = ZwQuerySystemInformation(0xB, listHeader, size, reinterpret_cast<PULONG>(&size)))
return status;
auto currentModule = reinterpret_cast<PSYSTEM_MODULE_INFORMATION>(listHeader)->Module;
for (std::size_t i{}; i < reinterpret_cast<PSYSTEM_MODULE_INFORMATION>(listHeader)->Count; ++i, ++currentModule) {
const auto currentModuleName = reinterpret_cast<const char*>(currentModule->FullPathName + currentModule->OffsetToFileName);
if (!strcmp(moduleName, currentModuleName)) {
*moduleStart = reinterpret_cast<std::uintptr_t>(currentModule->ImageBase);
*moduleSize = currentModule->ImageSize;
return STATUS_SUCCESS;
}
}
return STATUS_NOT_FOUND;
}
std::uintptr_t getImageSectionByName(const std::uintptr_t imageBase, const char* sectionName, std::size_t* sizeOut) {
if (reinterpret_cast<PIMAGE_DOS_HEADER>(imageBase)->e_magic != 0x5A4D)
return {};
const auto ntHeader = reinterpret_cast<PIMAGE_NT_HEADERS64>(
imageBase + reinterpret_cast<PIMAGE_DOS_HEADER>(imageBase)->e_lfanew);
const auto sectionCount = ntHeader->FileHeader.NumberOfSections;
auto sectionHeader = IMAGE_FIRST_SECTION(ntHeader);
for (std::size_t i{}; i < sectionCount; ++i, ++sectionHeader) {
if (!strcmp(sectionName, reinterpret_cast<const char*>(sectionHeader->Name))) {
if (sizeOut)
*sizeOut = sectionHeader->Misc.VirtualSize;
return imageBase + sectionHeader->VirtualAddress;
}
}
return {};
}
std::uintptr_t scanPattern(std::uint8_t* base, const std::size_t size, char* pattern, char* mask) {
const auto patternSize = strlen(mask);
for (std::size_t i = {}; i < size - patternSize; i++) {
for (std::size_t j = {}; j < patternSize; j++) {
if (mask[j] != '?' && *reinterpret_cast<std::uint8_t*>(base + i + j) != static_cast<std::uint8_t>(pattern[j]))
break;
if (j == patternSize - 1)
return reinterpret_cast<std::uintptr_t>(base) + i;
}
}
return {};
}
std::uintptr_t getServiceDescriptorTable() {
std::uintptr_t ntoskrnlBase {};
std::size_t ntoskrnlSize {};
if (!NT_SUCCESS(getKernelModuleByName("ntoskrnl.exe", &ntoskrnlBase, &ntoskrnlSize)))
return {};
std::size_t ntoskrnlTextSize {};
const auto ntoskrnlText = getImageSectionByName(ntoskrnlBase, ".text", &ntoskrnlTextSize);
if(!ntoskrnlText)
return {};
auto keServiceDescriptorTableShadow = scanPattern(reinterpret_cast<std::uint8_t*>(ntoskrnlText), ntoskrnlTextSize,
"\xC1\xEF\x07\x83\xE7\x20\x25\xFF\x0F", "xxxxxxxxx");
if (!keServiceDescriptorTableShadow)
return {};
keServiceDescriptorTableShadow += 21;
keServiceDescriptorTableShadow += *reinterpret_cast<std::int32_t*>(keServiceDescriptorTableShadow) + sizeof(std::int32_t);
return keServiceDescriptorTableShadow;
}
std::uintptr_t GetSystemServiceDescriptorTableFunction(std::int32_t Index)
{
if (keServiceDescriptorTable == NULL)
keServiceDescriptorTable = getServiceDescriptorTable();
const auto serviceTable = *reinterpret_cast<std::int32_t**>(keServiceDescriptorTable);
return reinterpret_cast<std::uintptr_t>(serviceTable) + (serviceTable[Index & 0xFFF] >> 4);
}
完整工程下载地址:
https://download.csdn.net/download/u011442768/13029151