From c62f8fde616d7de6c7d8ca3cc3cc15f2349b4e14 Mon Sep 17 00:00:00 2001 From: Samuel Tulach Date: Tue, 14 Apr 2020 19:12:48 +0200 Subject: [PATCH] Tue, Apr 14, 2020 7:12:48 PM --- client/client/client/client.cpp | 7 +++ client/client/client/client.vcxproj | 1 + client/client/client/driver.h | 46 +++++++++++---- client/client/client/utils.h | 92 +++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 10 deletions(-) diff --git a/client/client/client/client.cpp b/client/client/client/client.cpp index 41b0136..2414ad0 100644 --- a/client/client/client/client.cpp +++ b/client/client/client/client.cpp @@ -41,4 +41,11 @@ int main() { std::cout << "[-] Driver test failed" << std::endl; } + + uint64_t kernel_function_ptr = 0; + uint64_t kernel_original_function_address = 0; + + Utils::GetNtGdiDdDDIReclaimAllocations2KernelInfo(&kernel_function_ptr, &kernel_original_function_address); + + printf("%llx %llx\n", kernel_function_ptr, kernel_original_function_address); } diff --git a/client/client/client/client.vcxproj b/client/client/client/client.vcxproj index b49ec66..e0161ec 100644 --- a/client/client/client/client.vcxproj +++ b/client/client/client/client.vcxproj @@ -111,6 +111,7 @@ Console true + ntdll.lib;%(AdditionalDependencies) diff --git a/client/client/client/driver.h b/client/client/client/driver.h index e05cc00..8e44acf 100644 --- a/client/client/client/driver.h +++ b/client/client/client/driver.h @@ -10,6 +10,7 @@ namespace Driver unsigned long long data2; int size; } MemoryCommand; + #define VARIABLE_NAME L"yromeMifE" // EfiMemory #define COMMAND_MAGIC 0xDEAD @@ -25,13 +26,15 @@ namespace Driver #define EFI_VARIABLE_APPEND_WRITE 0x00000040 #define ATTRIBUTES (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS) + #define SE_SYSTEM_ENVIRONMENT_PRIVILEGE (22L) + NTSTATUS SetSystemEnvironmentPrivilege(BOOLEAN Enable, PBOOLEAN WasEnabled) { if (WasEnabled != nullptr) *WasEnabled = FALSE; BOOLEAN SeSystemEnvironmentWasEnabled; - const NTSTATUS Status = nt::RtlAdjustPrivilege(22L, // SE_SYSTEM_ENVIRONMENT_PRIVILEGE + const NTSTATUS Status = nt::RtlAdjustPrivilege(SE_SYSTEM_ENVIRONMENT_PRIVILEGE, Enable, FALSE, &SeSystemEnvironmentWasEnabled); @@ -47,7 +50,7 @@ namespace Driver UNICODE_STRING VariableName = RTL_CONSTANT_STRING(VARIABLE_NAME); NTSTATUS status = nt::NtSetSystemEnvironmentValueEx(&VariableName, &DummyGuid, - &cmd, + cmd, sizeof(MemoryCommand), ATTRIBUTES); } @@ -55,7 +58,7 @@ namespace Driver bool Init() { BOOLEAN SeSystemEnvironmentWasEnabled; - NTSTATUS status = SetSystemEnvironmentPrivilege(TRUE, &SeSystemEnvironmentWasEnabled); + NTSTATUS status = SetSystemEnvironmentPrivilege(true, &SeSystemEnvironmentWasEnabled); return NT_SUCCESS(status); } @@ -64,15 +67,38 @@ namespace Driver uintptr_t read = 0; uintptr_t value = 123; - MemoryCommand cmd; - cmd.operation = 0; - cmd.magic = COMMAND_MAGIC; - cmd.data1 = (uintptr_t)&read; - cmd.data2 = (uintptr_t)&value; - cmd.size = sizeof(uintptr_t); + MemoryCommand* cmd = new MemoryCommand(); + cmd->operation = 0; + cmd->magic = COMMAND_MAGIC; + cmd->data1 = (uintptr_t)&read; + cmd->data2 = (uintptr_t)&value; + cmd->size = sizeof(uintptr_t); - SendCommand(&cmd); + SendCommand(cmd); return (read == 123); } + + void MemCopy(uintptr_t destination, uintptr_t source, int size) + { + MemoryCommand* cmd = new MemoryCommand(); + cmd->operation = 0; + cmd->magic = COMMAND_MAGIC; + cmd->data1 = destination; + cmd->data2 = source; + cmd->size = size; + + SendCommand(cmd); + } + + // there is no way for us to check if it succeeed to it's yolooo + void ReadMemory(uint64_t address, void* buffer, uint64_t size) + { + MemCopy(reinterpret_cast(buffer), address, size); + } + + void WriteMemory(uint64_t address, void* buffer, uint64_t size) + { + MemCopy(address, reinterpret_cast(buffer), size); + } } \ No newline at end of file diff --git a/client/client/client/utils.h b/client/client/client/utils.h index 1022e46..4cd8998 100644 --- a/client/client/client/utils.h +++ b/client/client/client/utils.h @@ -41,4 +41,96 @@ namespace Utils VirtualFree(buffer, 0, MEM_RELEASE); return 0; } + + uint64_t GetKernelModuleExport(uint64_t kernel_module_base, const std::string& function_name) + { + if (!kernel_module_base) + return 0; + + IMAGE_DOS_HEADER dos_header = { 0 }; + IMAGE_NT_HEADERS64 nt_headers = { 0 }; + + Driver::ReadMemory(kernel_module_base, &dos_header, sizeof(dos_header)); + + if (dos_header.e_magic != IMAGE_DOS_SIGNATURE) + return 0; + + Driver::ReadMemory(kernel_module_base + dos_header.e_lfanew, &nt_headers, sizeof(nt_headers)); + + if (nt_headers.Signature != IMAGE_NT_SIGNATURE) + return 0; + + const auto export_base = nt_headers.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; + const auto export_base_size = nt_headers.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; + + if (!export_base || !export_base_size) + return 0; + + const auto export_data = reinterpret_cast(VirtualAlloc(nullptr, export_base_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE)); + + Driver::ReadMemory(kernel_module_base + export_base, export_data, export_base_size); + + const auto delta = reinterpret_cast(export_data) - export_base; + + const auto name_table = reinterpret_cast(export_data->AddressOfNames + delta); + const auto ordinal_table = reinterpret_cast(export_data->AddressOfNameOrdinals + delta); + const auto function_table = reinterpret_cast(export_data->AddressOfFunctions + delta); + + for (auto i = 0u; i < export_data->NumberOfNames; ++i) + { + const std::string current_function_name = std::string(reinterpret_cast(name_table[i] + delta)); + + if (!_stricmp(current_function_name.c_str(), function_name.c_str())) + { + const auto function_ordinal = ordinal_table[i]; + 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) + { + VirtualFree(export_data, 0, MEM_RELEASE); + return 0; // No forwarded exports on 64bit? + } + + VirtualFree(export_data, 0, MEM_RELEASE); + return function_address; + } + } + + VirtualFree(export_data, 0, MEM_RELEASE); + return 0; + } + + bool GetNtGdiDdDDIReclaimAllocations2KernelInfo(uint64_t* out_kernel_function_ptr, uint64_t* out_kernel_original_function_address) + { + // 488b05650e1400 mov rax, qword ptr [rip+offset] + // ff150f211600 call cs:__guard_dispatch_icall_fptr + + static uint64_t kernel_function_ptr = 0; + static uint64_t kernel_original_function_address = 0; + + if (!kernel_function_ptr || !kernel_original_function_address) + { + const uint64_t kernel_NtGdiDdDDIReclaimAllocations2 = GetKernelModuleExport(GetKernelModuleAddress("win32kbase.sys"), "NtGdiDdDDIReclaimAllocations2"); + + if (!kernel_NtGdiDdDDIReclaimAllocations2) + { + std::cout << "[-] Failed to get export win32kbase.NtGdiDdDDIReclaimAllocations2" << std::endl; + return false; + } + + const uint64_t kernel_function_ptr_offset_address = kernel_NtGdiDdDDIReclaimAllocations2 + 0x7; + int32_t function_ptr_offset = 0; // offset is a SIGNED integer + + Driver::ReadMemory(kernel_function_ptr_offset_address, &function_ptr_offset, sizeof(function_ptr_offset)); + + kernel_function_ptr = kernel_NtGdiDdDDIReclaimAllocations2 + 0xB + function_ptr_offset; + + Driver::ReadMemory(kernel_function_ptr, &kernel_original_function_address, sizeof(kernel_original_function_address)); + } + + *out_kernel_function_ptr = kernel_function_ptr; + *out_kernel_original_function_address = kernel_original_function_address; + + return true; + } } \ No newline at end of file