diff --git a/client/efi-mapper/kdmapper/efi_driver.cpp b/client/efi-mapper/kdmapper/efi_driver.cpp index 0d31b58..81ddf39 100644 --- a/client/efi-mapper/kdmapper/efi_driver.cpp +++ b/client/efi-mapper/kdmapper/efi_driver.cpp @@ -41,8 +41,13 @@ bool efi_driver::MemCopy(HANDLE device_handle, uint64_t destination, uint64_t so MemoryCommand* cmd = new MemoryCommand(); cmd->operation = 0; cmd->magic = COMMAND_MAGIC; - cmd->data1 = destination; - cmd->data2 = source; + + uintptr_t data[10]; + data[0] = destination; + data[1] = source; + + memcpy(&cmd->data, &data[0], sizeof(data)); + cmd->size = (int)size; SendCommand(cmd); @@ -82,8 +87,19 @@ uint64_t efi_driver::AllocatePool(HANDLE device_handle, nt::POOL_TYPE pool_type, uint64_t allocated_pool = 0; - if (!CallKernelFunction(device_handle, &allocated_pool, kernel_ExAllocatePool, pool_type, size)) - return 0; + MemoryCommand* cmd = new MemoryCommand(); + cmd->operation = 1; + cmd->magic = COMMAND_MAGIC; + + uintptr_t data[10]; + data[0] = kernel_ExAllocatePool; + data[1] = pool_type; + data[2] = size; + data[3] = (uintptr_t)&allocated_pool; + + memcpy(&cmd->data, &data[0], sizeof(data)); + + SendCommand(cmd); return allocated_pool; } @@ -98,7 +114,19 @@ bool efi_driver::FreePool(HANDLE device_handle, uint64_t address) if (!kernel_ExFreePool) kernel_ExFreePool = GetKernelModuleExport(device_handle, utils::GetKernelModuleAddress("ntoskrnl.exe"), "ExFreePool"); - return CallKernelFunction(device_handle, nullptr, kernel_ExFreePool, address); + MemoryCommand* cmd = new MemoryCommand(); + cmd->operation = 2; + cmd->magic = COMMAND_MAGIC; + + uintptr_t data[10]; + data[0] = kernel_ExFreePool; + data[1] = address; + + memcpy(&cmd->data, &data[0], sizeof(data)); + + SendCommand(cmd); + + return true; // yolo? } uint64_t efi_driver::GetKernelModuleExport(HANDLE device_handle, uint64_t kernel_module_base, const std::string & function_name) @@ -193,6 +221,36 @@ bool efi_driver::GetNtGdiDdDDIReclaimAllocations2KernelInfo(HANDLE device_handle return true; } +bool efi_driver::GetNtGdiGetCOPPCompatibleOPMInformationInfo(HANDLE device_handle, uint64_t* out_kernel_function_ptr, uint8_t* out_kernel_original_bytes) +{ + // 48ff2551d81f00 jmp cs:__imp_NtGdiGetCOPPCompatibleOPMInformation + // cccccccccc padding + + static uint64_t kernel_function_ptr = 0; + static uint8_t kernel_original_jmp_bytes[12] = { 0 }; + + if (!kernel_function_ptr || kernel_original_jmp_bytes[0] == 0) + { + const uint64_t kernel_NtGdiGetCOPPCompatibleOPMInformation = GetKernelModuleExport(device_handle, utils::GetKernelModuleAddress("win32kfull.sys"), "NtGdiGetCOPPCompatibleOPMInformation"); + + if (!kernel_NtGdiGetCOPPCompatibleOPMInformation) + { + std::cout << "[-] Failed to get export win32kfull.NtGdiGetCOPPCompatibleOPMInformation" << std::endl; + return false; + } + + kernel_function_ptr = kernel_NtGdiGetCOPPCompatibleOPMInformation; + + if (!ReadMemory(device_handle, kernel_function_ptr, kernel_original_jmp_bytes, sizeof(kernel_original_jmp_bytes))) + return false; + } + + *out_kernel_function_ptr = kernel_function_ptr; + memcpy(out_kernel_original_bytes, kernel_original_jmp_bytes, sizeof(kernel_original_jmp_bytes)); + + return true; +} + bool efi_driver::ClearMmUnloadedDrivers(HANDLE device_handle) { ULONG buffer_size = 0; diff --git a/client/efi-mapper/kdmapper/efi_driver.hpp b/client/efi-mapper/kdmapper/efi_driver.hpp index 9e32232..83cab96 100644 --- a/client/efi-mapper/kdmapper/efi_driver.hpp +++ b/client/efi-mapper/kdmapper/efi_driver.hpp @@ -14,8 +14,7 @@ namespace efi_driver { int magic; int operation; - unsigned long long data1; - unsigned long long data2; + unsigned long long data[10]; int size; } MemoryCommand; @@ -45,69 +44,6 @@ namespace efi_driver 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 GetNtGdiDdDDIReclaimAllocations2KernelInfo(HANDLE device_handle, uint64_t* out_kernel_function_ptr, uint64_t* out_kernel_original_function_address); + bool GetNtGdiGetCOPPCompatibleOPMInformationInfo(HANDLE device_handle, uint64_t* out_kernel_function_ptr, uint8_t* out_kernel_original_bytes); bool ClearMmUnloadedDrivers(HANDLE device_handle); - - template - bool CallKernelFunction(HANDLE device_handle, T* out_result, uint64_t kernel_function_address, const A ...arguments) - { - constexpr auto call_void = std::is_same_v; - - if constexpr (!call_void) - { - if (!out_result) - return false; - } - else - { - UNREFERENCED_PARAMETER(out_result); - } - - if (!kernel_function_address) - return false; - - // Setup function call - - const auto NtGdiDdDDIReclaimAllocations2 = reinterpret_cast(GetProcAddress(LoadLibrary("gdi32full.dll"), "NtGdiDdDDIReclaimAllocations2")); - - if (!NtGdiDdDDIReclaimAllocations2) - { - std::cout << "[-] Failed to get export gdi32full.NtGdiDdDDIReclaimAllocations2" << std::endl; - return false; - } - - // Get function pointer (@win32kbase!gDxgkInterface table) used by NtGdiDdDDIReclaimAllocations2 and save the original address (dxgkrnl!DxgkReclaimAllocations2) - - uint64_t kernel_function_ptr = 0; - uint64_t kernel_original_function_address = 0; - - if (!GetNtGdiDdDDIReclaimAllocations2KernelInfo(device_handle, &kernel_function_ptr, &kernel_original_function_address)) - return false; - - // Overwrite the pointer with kernel_function_address - - if (!WriteMemory(device_handle, kernel_function_ptr, &kernel_function_address, sizeof(kernel_function_address))) - return false; - - // Call function - - if constexpr (!call_void) - { - using FunctionFn = T(__stdcall*)(A...); - const auto Function = static_cast(NtGdiDdDDIReclaimAllocations2); - - *out_result = Function(arguments...); - } - else - { - using FunctionFn = void(__stdcall*)(A...); - const auto Function = static_cast(NtGdiDdDDIReclaimAllocations2); - - Function(arguments...); - } - - // Restore the pointer - - WriteMemory(device_handle, kernel_function_ptr, &kernel_original_function_address, sizeof(kernel_original_function_address)); - return true; - } -} \ No newline at end of file +} diff --git a/client/efi-mapper/kdmapper/kdmapper.cpp b/client/efi-mapper/kdmapper/kdmapper.cpp index efc3f9f..74003a3 100644 --- a/client/efi-mapper/kdmapper/kdmapper.cpp +++ b/client/efi-mapper/kdmapper/kdmapper.cpp @@ -79,18 +79,23 @@ uint64_t kdmapper::MapDriver(HANDLE iqvw64e_device_handle, const std::string& dr std::cout << "[<] Calling DriverEntry 0x" << reinterpret_cast(address_of_entry_point) << std::endl; - NTSTATUS status = 0; + long status = 0; // NTSTATUS - if (!efi_driver::CallKernelFunction(iqvw64e_device_handle, &status, address_of_entry_point)) - { - std::cout << "[-] Failed to call driver entry" << std::endl; - break; - } + efi_driver::MemoryCommand* cmd = new efi_driver::MemoryCommand(); + cmd->operation = 5; + cmd->magic = COMMAND_MAGIC; + + uintptr_t data[10]; + data[0] = address_of_entry_point; + data[1] = (uintptr_t)&status; + + memcpy(&cmd->data, &data[0], sizeof(data)); + + efi_driver::SendCommand(cmd); std::cout << "[+] DriverEntry returned 0x" << std::hex << std::setw(8) << std::setfill('0') << std::uppercase << status << std::nouppercase << std::dec << std::endl; // Erase PE headers - efi_driver::SetMemory(iqvw64e_device_handle, kernel_image_base, 0, nt_headers->OptionalHeader.SizeOfHeaders); return kernel_image_base; diff --git a/client/efi-mapper/kdmapper/kdmapper.vcxproj b/client/efi-mapper/kdmapper/kdmapper.vcxproj index 74263bd..8fe7fa4 100644 --- a/client/efi-mapper/kdmapper/kdmapper.vcxproj +++ b/client/efi-mapper/kdmapper/kdmapper.vcxproj @@ -1,141 +1,144 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 15.0 - {518E0636-BA8F-459D-ACAC-81BD33475E3E} - kdmapper - 10.0 - - - - Application - true - v142 - MultiByte - - - Application - false - v142 - true - MultiByte - - - Application - true - v142 - MultiByte - false - - - Application - false - v142 - true - MultiByte - false - - - - - - - - - - - - - - - - - - - - - - - Level3 - Disabled - true - true - - - - - Level4 - true - true - stdcpp17 - false - - - - - Level3 - MaxSpeed - true - true - true - true - - - true - true - - - - - Level4 - MaxSpeed - true - true - true - true - true - stdcpp17 - - - true - true - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {518E0636-BA8F-459D-ACAC-81BD33475E3E} + kdmapper + 10.0 + + + + Application + true + v142 + MultiByte + + + Application + false + v142 + true + MultiByte + + + Application + true + v142 + MultiByte + false + + + Application + false + v142 + true + MultiByte + false + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + true + true + + + + + Level4 + true + true + stdcpp17 + false + + + version.lib;%(AdditionalDependencies) + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + Level4 + MaxSpeed + true + true + true + true + true + stdcpp17 + + + true + true + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/client/efi-mapper/kdmapper/main.cpp b/client/efi-mapper/kdmapper/main.cpp index 982113e..5a7d824 100644 --- a/client/efi-mapper/kdmapper/main.cpp +++ b/client/efi-mapper/kdmapper/main.cpp @@ -1,7 +1,7 @@ #include "kdmapper.hpp" int main(const int argc, char** argv) -{ +{ if (argc != 2 || std::filesystem::path(argv[1]).extension().string().compare(".sys")) { std::cout << "[-] Incorrect usage" << std::endl; diff --git a/client/efi-mapper/kdmapper/portable_executable.cpp b/client/efi-mapper/kdmapper/portable_executable.cpp index d705dd3..2a37639 100644 --- a/client/efi-mapper/kdmapper/portable_executable.cpp +++ b/client/efi-mapper/kdmapper/portable_executable.cpp @@ -23,6 +23,7 @@ portable_executable::vec_relocs portable_executable::GetRelocs(void* image_base) return {}; vec_relocs relocs; + return relocs; // gonna probably kill me for this but for some reason drivers without reallocation seems falsely reporting some shit memory regions causing mapper to crash auto current_base_relocation = reinterpret_cast(reinterpret_cast(image_base) + nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); const auto reloc_end = reinterpret_cast(current_base_relocation) + nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; diff --git a/driver/main.c b/driver/main.c index e43bd21..a14b0af 100644 --- a/driver/main.c +++ b/driver/main.c @@ -2,6 +2,8 @@ // instead of SysV ABI, we now have to do transitions // GNU-EFI has a functionality for this (thanks god) #define GNU_EFI_USE_MS_ABI 1 +#define stdcall __attribute__((stdcall)) // wHy NoT tO jUsT uSe MsVc +#define fastcall __attribute__((fastcall)) // Mandatory defines #include @@ -42,11 +44,17 @@ typedef struct _MemoryCommand { int magic; int operation; - unsigned long long data1; - unsigned long long data2; + unsigned long long data[10]; int size; } MemoryCommand; +// Functions (Windows only) +typedef uintptr_t (stdcall *ExAllocatePool)(int type, uintptr_t size); +typedef void (stdcall *ExFreePool)(uintptr_t address); +typedef void (stdcall *StandardFuncStd)(); +typedef void (fastcall *StandardFuncFast)(); +typedef unsigned long (stdcall *DriverEntry)(void* driver, void* registry); + // Function that actually performs the r/w EFI_STATUS RunCommand(MemoryCommand* cmd) @@ -62,10 +70,60 @@ RunCommand(MemoryCommand* cmd) if (cmd->operation == 0) { // Same as memcpy function - CopyMem(cmd->data1, cmd->data2, cmd->size); + CopyMem(cmd->data[0], cmd->data[1], cmd->size); + return EFI_SUCCESS; } + // Call ExAllocatePool + if (cmd->operation == 1) + { + void* function = cmd->data[0]; // Pointer to the function (supplied by client) + ExAllocatePool exalloc = (ExAllocatePool)function; + int temp = cmd->data[1]; // gcc you ok? + uintptr_t allocbase = exalloc(temp, cmd->data[2]); + *(uintptr_t*)cmd->data[3] = allocbase; + } + + // Call ExFreePool + if (cmd->operation == 2) + { + void* function = cmd->data[0]; + ExFreePool exfree = (ExFreePool)function; + exfree(cmd->data[1]); + } + + // Call any void function (__stdcall) + if (cmd->operation == 3) + { + void* function = cmd->data[0]; + StandardFuncStd stand = (StandardFuncStd)function; + stand(); + } + + // Call any void function (__fastcall) + if (cmd->operation == 4) + { + void* function = cmd->data[0]; + StandardFuncFast stand = (StandardFuncFast)function; + stand(); + } + + // Call driver entry + if (cmd->operation == 5) + { + void* function = cmd->data[0]; + DriverEntry entry = (DriverEntry)function; + + // gcc compiles long as 8 byte + // msvc compiles long as 4 byte + // we are gonna use int + // you can't even imagine how long I was fking + // with this + int status = entry(0, 0); + *(int*)cmd->data[1] = status; + } + // Invalid command return EFI_UNSUPPORTED; } @@ -249,7 +307,7 @@ efi_main(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) TPL_NOTIFY, SetVirtualAddressMapEvent, NULL, - VirtualGuid, + &VirtualGuid, &NotifyEvent); // Return if event create failed @@ -264,7 +322,7 @@ efi_main(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) TPL_NOTIFY, ExitBootServicesEvent, NULL, - ExitGuid, + &ExitGuid, &ExitEvent); // Return if event create failed (yet again) diff --git a/update.sh b/update.sh old mode 100644 new mode 100755