Tue, Apr 14, 2020 7:12:48 PM

This commit is contained in:
Samuel Tulach
2020-04-14 19:12:48 +02:00
parent 12d7e0f1d0
commit c62f8fde61
4 changed files with 136 additions and 10 deletions

View File

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

View File

@@ -111,6 +111,7 @@
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

View File

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

View File

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