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;
|
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>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ namespace Driver
|
|||||||
unsigned long long data2;
|
unsigned long long data2;
|
||||||
int size;
|
int size;
|
||||||
} MemoryCommand;
|
} MemoryCommand;
|
||||||
|
|
||||||
#define VARIABLE_NAME L"yromeMifE" // EfiMemory
|
#define VARIABLE_NAME L"yromeMifE" // EfiMemory
|
||||||
#define COMMAND_MAGIC 0xDEAD
|
#define COMMAND_MAGIC 0xDEAD
|
||||||
|
|
||||||
@@ -25,13 +26,15 @@ namespace Driver
|
|||||||
#define EFI_VARIABLE_APPEND_WRITE 0x00000040
|
#define EFI_VARIABLE_APPEND_WRITE 0x00000040
|
||||||
#define ATTRIBUTES (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS)
|
#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)
|
NTSTATUS SetSystemEnvironmentPrivilege(BOOLEAN Enable, PBOOLEAN WasEnabled)
|
||||||
{
|
{
|
||||||
if (WasEnabled != nullptr)
|
if (WasEnabled != nullptr)
|
||||||
*WasEnabled = FALSE;
|
*WasEnabled = FALSE;
|
||||||
|
|
||||||
BOOLEAN SeSystemEnvironmentWasEnabled;
|
BOOLEAN SeSystemEnvironmentWasEnabled;
|
||||||
const NTSTATUS Status = nt::RtlAdjustPrivilege(22L, // SE_SYSTEM_ENVIRONMENT_PRIVILEGE
|
const NTSTATUS Status = nt::RtlAdjustPrivilege(SE_SYSTEM_ENVIRONMENT_PRIVILEGE,
|
||||||
Enable,
|
Enable,
|
||||||
FALSE,
|
FALSE,
|
||||||
&SeSystemEnvironmentWasEnabled);
|
&SeSystemEnvironmentWasEnabled);
|
||||||
@@ -47,7 +50,7 @@ namespace Driver
|
|||||||
UNICODE_STRING VariableName = RTL_CONSTANT_STRING(VARIABLE_NAME);
|
UNICODE_STRING VariableName = RTL_CONSTANT_STRING(VARIABLE_NAME);
|
||||||
NTSTATUS status = nt::NtSetSystemEnvironmentValueEx(&VariableName,
|
NTSTATUS status = nt::NtSetSystemEnvironmentValueEx(&VariableName,
|
||||||
&DummyGuid,
|
&DummyGuid,
|
||||||
&cmd,
|
cmd,
|
||||||
sizeof(MemoryCommand),
|
sizeof(MemoryCommand),
|
||||||
ATTRIBUTES);
|
ATTRIBUTES);
|
||||||
}
|
}
|
||||||
@@ -55,7 +58,7 @@ namespace Driver
|
|||||||
bool Init()
|
bool Init()
|
||||||
{
|
{
|
||||||
BOOLEAN SeSystemEnvironmentWasEnabled;
|
BOOLEAN SeSystemEnvironmentWasEnabled;
|
||||||
NTSTATUS status = SetSystemEnvironmentPrivilege(TRUE, &SeSystemEnvironmentWasEnabled);
|
NTSTATUS status = SetSystemEnvironmentPrivilege(true, &SeSystemEnvironmentWasEnabled);
|
||||||
return NT_SUCCESS(status);
|
return NT_SUCCESS(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,15 +67,38 @@ namespace Driver
|
|||||||
uintptr_t read = 0;
|
uintptr_t read = 0;
|
||||||
uintptr_t value = 123;
|
uintptr_t value = 123;
|
||||||
|
|
||||||
MemoryCommand cmd;
|
MemoryCommand* cmd = new MemoryCommand();
|
||||||
cmd.operation = 0;
|
cmd->operation = 0;
|
||||||
cmd.magic = COMMAND_MAGIC;
|
cmd->magic = COMMAND_MAGIC;
|
||||||
cmd.data1 = (uintptr_t)&read;
|
cmd->data1 = (uintptr_t)&read;
|
||||||
cmd.data2 = (uintptr_t)&value;
|
cmd->data2 = (uintptr_t)&value;
|
||||||
cmd.size = sizeof(uintptr_t);
|
cmd->size = sizeof(uintptr_t);
|
||||||
|
|
||||||
SendCommand(&cmd);
|
SendCommand(cmd);
|
||||||
|
|
||||||
return (read == 123);
|
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);
|
VirtualFree(buffer, 0, MEM_RELEASE);
|
||||||
return 0;
|
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