You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
4.1 KiB
120 lines
4.1 KiB
#include "kmem_ctx.hpp"
|
|
|
|
namespace nasa
|
|
{
|
|
kmem_ctx::kmem_ctx(vdm::vdm_ctx* vdm)
|
|
: vdm(vdm)
|
|
{
|
|
const auto runtime_broker_pid =
|
|
util::start_runtime_broker();
|
|
|
|
zombie(runtime_broker_pid);
|
|
const auto runtime_broker_peproc =
|
|
vdm->get_peprocess(runtime_broker_pid);
|
|
|
|
set_process_name(runtime_broker_peproc, L"/proc/kmem");
|
|
mem_ctx runtime_ctx(*vdm, runtime_broker_pid);
|
|
|
|
const auto pml4 =
|
|
reinterpret_cast<ppml4e>(
|
|
runtime_ctx.set_page(
|
|
runtime_ctx.get_dirbase()));
|
|
|
|
// shoot the legs off the table, make it to do a back flip...
|
|
// (aka put kernel pml4e's into usermode/below MmHighestUserAddress so NtReadVirtualMemory
|
|
// and NtWriteVirtualMemory/all winapis will work)...
|
|
memcpy(pml4, pml4 + 255, 256 * sizeof pml4e);
|
|
}
|
|
|
|
auto kmem_ctx::translate(std::uintptr_t kva) -> std::uintptr_t
|
|
{
|
|
virt_addr_t old_addr{ reinterpret_cast<void*>(kva) };
|
|
virt_addr_t new_addr{ NULL };
|
|
new_addr.pml4_index = old_addr.pml4_index - 255;
|
|
new_addr.pdpt_index = old_addr.pdpt_index;
|
|
new_addr.pd_index = old_addr.pd_index;
|
|
new_addr.pt_index = old_addr.pt_index;
|
|
return reinterpret_cast<std::uintptr_t>(new_addr.value);
|
|
}
|
|
|
|
auto kmem_ctx::get_handle()->HANDLE
|
|
{
|
|
return OpenProcess(PROCESS_ALL_ACCESS, FALSE, util::get_pid("/proc/kmem"));
|
|
}
|
|
|
|
void kmem_ctx::zombie(std::uint32_t pid) const
|
|
{
|
|
// zombie the the process by incrementing an exit counter
|
|
// then calling TerminateProcess so the process never closes...
|
|
const auto runtime_broker_peproc =
|
|
reinterpret_cast<std::uintptr_t>(
|
|
vdm->get_peprocess(pid));
|
|
|
|
static const auto inc_ref_counter =
|
|
util::get_kmodule_export(
|
|
"ntoskrnl.exe",
|
|
"PsAcquireProcessExitSynchronization"
|
|
);
|
|
|
|
const auto result =
|
|
vdm->syscall<NTSTATUS(*)(std::uintptr_t)>(
|
|
inc_ref_counter, runtime_broker_peproc);
|
|
|
|
const auto handle = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
|
|
TerminateProcess(handle, NULL);
|
|
CloseHandle(handle);
|
|
}
|
|
|
|
bool kmem_ctx::set_process_name(PEPROCESS peproc, const wchar_t* new_name)
|
|
{
|
|
static const auto process_image_name =
|
|
reinterpret_cast<std::uintptr_t>(
|
|
util::get_kmodule_export(
|
|
"ntoskrnl.exe", "SeLocateProcessImageName"));
|
|
|
|
if (!process_image_name)
|
|
return false;
|
|
|
|
// SeLocateProcessImageName --> PsGetAllocatedFullProcessImageNameEx
|
|
// PAGE : 00000001406B1A50 SeLocateProcessImageName proc near
|
|
// PAGE : 00000001406B1A50 48 83 EC 28 sub rsp, 28h
|
|
// PAGE : 00000001406B1A54 E8 0B 00 00 00 call PsGetAllocatedFullProcessImageNameEx <====== + 5
|
|
// PAGE : 00000001406B1A59 48 83 C4 28 add rsp, 28h
|
|
// PAGE : 00000001406B1A5D C3 retn
|
|
// PAGE : 00000001406B1A5D SeLocateProcessImageName endp
|
|
const auto get_process_name =
|
|
(process_image_name + 9 + vdm->rkm<std::uint32_t>(process_image_name + 5)); // <====== + 5
|
|
|
|
// PAGE : 00000001406B1A64 48 83 EC 28 sub rsp, 28h
|
|
// PAGE : 00000001406B1A68 48 83 B9 10 07 00 00 00 cmp qword ptr[rcx + 710h], 0
|
|
// PAGE : 00000001406B1A70 B8 25 02 00 C0 mov eax, 0C0000225h
|
|
// PAGE : 00000001406B1A75 0F 85 0B E9 10 00 jnz loc_1407C0386
|
|
// PAGE : 00000001406B1A7B 48 83 B9 68 04 00 00 00 cmp qword ptr[rcx + 468h], 0 <===== + 26
|
|
const auto process_name_idx =
|
|
vdm->rkm<std::uint32_t>(get_process_name + 26); // <===== + 26
|
|
|
|
// _SE_AUDIT_PROCESS_CREATION_INFO SeAuditProcessCreationInfo
|
|
// _SE_AUDIT_PROCESS_CREATION_INFO --> POBJECT_NAME_INFORMATION == PUNICODE_STRING...
|
|
const auto unicode_string_ptr =
|
|
vdm->rkm<std::uintptr_t>(
|
|
reinterpret_cast<std::uintptr_t>(peproc) + process_name_idx);
|
|
|
|
if (!unicode_string_ptr)
|
|
return false;
|
|
|
|
auto process_unicode_str =
|
|
vdm->rkm<UNICODE_STRING>(unicode_string_ptr);
|
|
|
|
if (!process_unicode_str.Buffer)
|
|
return false;
|
|
|
|
// set new name...
|
|
vdm->wkm((void*)process_unicode_str.Buffer, (void*)new_name, std::wcslen(new_name) * sizeof(wchar_t));
|
|
|
|
// set new unicode string info...
|
|
process_unicode_str.Length = std::wcslen(new_name) * sizeof(wchar_t);
|
|
process_unicode_str.MaximumLength = std::wcslen(new_name) * sizeof(wchar_t);
|
|
vdm->wkm<UNICODE_STRING>(unicode_string_ptr, process_unicode_str);
|
|
return true;
|
|
}
|
|
} |