Tue, Apr 14, 2020 7:12:48 PM
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -111,6 +111,7 @@
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
|
||||
@@ -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<uint64_t>(buffer), address, size);
|
||||
}
|
||||
|
||||
void WriteMemory(uint64_t address, void* buffer, uint64_t size)
|
||||
{
|
||||
MemCopy(address, reinterpret_cast<uint64_t>(buffer), size);
|
||||
}
|
||||
}
|
||||
@@ -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<PIMAGE_EXPORT_DIRECTORY>(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<uint64_t>(export_data) - export_base;
|
||||
|
||||
const auto name_table = reinterpret_cast<uint32_t*>(export_data->AddressOfNames + delta);
|
||||
const auto ordinal_table = reinterpret_cast<uint16_t*>(export_data->AddressOfNameOrdinals + delta);
|
||||
const auto function_table = reinterpret_cast<uint32_t*>(export_data->AddressOfFunctions + delta);
|
||||
|
||||
for (auto i = 0u; i < export_data->NumberOfNames; ++i)
|
||||
{
|
||||
const std::string current_function_name = std::string(reinterpret_cast<char*>(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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user