diff --git a/kmem/kmem.vcxproj b/kmem/kmem.vcxproj index 2c80fe3..f6c291c 100644 --- a/kmem/kmem.vcxproj +++ b/kmem/kmem.vcxproj @@ -86,11 +86,13 @@ + + diff --git a/kmem/kmem.vcxproj.filters b/kmem/kmem.vcxproj.filters index a144f80..9de80d6 100644 --- a/kmem/kmem.vcxproj.filters +++ b/kmem/kmem.vcxproj.filters @@ -29,6 +29,9 @@ Source Files + + Source Files + @@ -55,6 +58,9 @@ Header Files + + Header Files + diff --git a/kmem/main.cpp b/kmem/main.cpp index d2c49a5..99eac32 100644 --- a/kmem/main.cpp +++ b/kmem/main.cpp @@ -1,4 +1,5 @@ #include "kmem_ctx/kmem_ctx.hpp" +#include "set_mgr/set_mgr.hpp" int __cdecl main(int argc, char** argv) { @@ -12,8 +13,6 @@ int __cdecl main(int argc, char** argv) return vdm::write_phys(addr, buffer, size); }; - auto kmem_handle = nasa::kmem_ctx::get_handle(); - // translation just subtracts pml4 index bit field by 255... const auto ntoskrnl_base = util::get_kmodule_base("ntoskrnl.exe"); const auto ntoskrnl_translated = nasa::kmem_ctx::translate(ntoskrnl_base); @@ -21,56 +20,41 @@ int __cdecl main(int argc, char** argv) std::printf("[+] ntoskrnl base -> 0x%p\n", ntoskrnl_base); std::printf("[+] ntoskrnl translated -> 0x%p\n", ntoskrnl_translated); - if (kmem_handle == INVALID_HANDLE_VALUE) + const auto [drv_handle, drv_key] = vdm::load_drv(); + if (drv_handle == INVALID_HANDLE_VALUE) { - const auto [drv_handle, drv_key] = vdm::load_drv(); - if (drv_handle == INVALID_HANDLE_VALUE) - { - std::printf("[!] invalid handle...\n"); - std::getchar(); - return -1; - } - - vdm::vdm_ctx vdm(_read_phys, _write_phys); - nasa::kmem_ctx kmem(&vdm); + std::printf("[!] invalid handle...\n"); + std::getchar(); + return -1; + } - kmem_handle = kmem.get_handle(); - unsigned short mz = 0u; - std::size_t bytes_handled; + vdm::vdm_ctx vdm(_read_phys, _write_phys); + nasa::kmem_ctx kmem(&vdm); - // ReadProcessMemory kernel memory example... - auto result = - ReadProcessMemory( - kmem_handle, - reinterpret_cast(ntoskrnl_translated), - &mz, sizeof mz, - &bytes_handled - ); + auto set_mgr_pethread = set_mgr::get_setmgr_pethread(vdm); + auto result = set_mgr::stop_setmgr(vdm, set_mgr_pethread); - std::printf("[+] ReadProcessMemory Result -> %d, mz -> 0x%x\n", result, mz); + std::printf("[+] set manager pethread -> 0x%p\n", set_mgr_pethread); + std::printf("[+] suspend thread result -> 0x%p\n", result); - if (!vdm::unload_drv(drv_handle, drv_key)) - { - std::printf("[!] unable to unload driver...\n"); - std::getchar(); - return -1; - } - } - else + auto kmem_handle = nasa::kmem_ctx::get_handle(); + unsigned short mz = 0u; + std::size_t bytes_handled; + + // ReadProcessMemory kernel memory example... + result = ReadProcessMemory( + kmem_handle, + reinterpret_cast(ntoskrnl_translated), + &mz, sizeof mz, + &bytes_handled + ); + + std::printf("[+] ReadProcessMemory Result -> %d, mz -> 0x%x\n", result, mz); + if (!vdm::unload_drv(drv_handle, drv_key)) { - unsigned short mz = 0u; - std::size_t bytes_handled; - - // ReadProcessMemory kernel memory example... - auto result = - ReadProcessMemory( - kmem_handle, - reinterpret_cast(ntoskrnl_translated), - &mz, sizeof mz, - &bytes_handled - ); - - std::printf("[+] ReadProcessMemory Result -> %d, mz -> 0x%x\n", result, mz); + std::printf("[!] unable to unload driver...\n"); + std::getchar(); + return -1; } std::printf("[+] press enter to exit...\n"); std::getchar(); diff --git a/kmem/set_mgr/set_mgr.cpp b/kmem/set_mgr/set_mgr.cpp new file mode 100644 index 0000000..e2fd1c6 --- /dev/null +++ b/kmem/set_mgr/set_mgr.cpp @@ -0,0 +1,77 @@ +#include "set_mgr.hpp" + +namespace set_mgr +{ + auto get_setmgr_pethread(vdm::vdm_ctx& v_ctx)->PETHREAD + { + ULONG return_len = 0u; + std::size_t alloc_size = 0x1000u; + auto process_info = reinterpret_cast(malloc(alloc_size)); + + while (NtQuerySystemInformation + ( + SystemProcessInformation, + process_info, + alloc_size, + &return_len + ) == STATUS_INFO_LENGTH_MISMATCH) + process_info = reinterpret_cast( + realloc(process_info, alloc_size += 0x1000)); + + const auto og_ptr = process_info; + while (process_info && process_info->UniqueProcessId != (HANDLE)4) + process_info = reinterpret_cast( + reinterpret_cast(process_info) + process_info->NextEntryOffset); + + auto thread_info = reinterpret_cast( + reinterpret_cast(process_info) + sizeof SYSTEM_PROCESS_INFORMATION); + + static const auto ntoskrnl_base = + util::get_kmodule_base("ntoskrnl.exe"); + + const auto [ke_balance_um, ke_balance_rva] = + util::memory::sig_scan( + KE_BALANCE_SIG, KE_BALANCE_MASK); + + auto rip_rva = *reinterpret_cast(ke_balance_um + 19); + const auto ke_balance_set = ntoskrnl_base + ke_balance_rva + 23 + rip_rva; + + const auto [suspend_in_um, suspend_rva] = + util::memory::sig_scan(SUSPEND_THREAD_SIG, SUSPEND_THREAD_MASK); + + rip_rva = *reinterpret_cast(suspend_in_um + 1); + const auto ps_suspend_thread = reinterpret_cast(ntoskrnl_base + rip_rva + 5 + suspend_rva); + + static const auto lookup_pethread = + util::get_kmodule_export("ntoskrnl.exe", "PsLookupThreadByThreadId"); + + for (auto idx = 0u; idx < process_info->NumberOfThreads; ++idx) + { + if (thread_info[idx].StartAddress == reinterpret_cast(ke_balance_set)) + { + PETHREAD pethread; + auto result = v_ctx.syscall( + lookup_pethread, thread_info[idx].ClientId.UniqueThread, &pethread); + + free(og_ptr); + return pethread; + } + } + + free(og_ptr); + return {}; + } + + auto stop_setmgr(vdm::vdm_ctx& v_ctx, PETHREAD pethread) -> NTSTATUS + { + static const auto ntoskrnl_base = + util::get_kmodule_base("ntoskrnl.exe"); + + const auto [suspend_in_um, suspend_rva] = + util::memory::sig_scan(SUSPEND_THREAD_SIG, SUSPEND_THREAD_MASK); + + const auto rip_rva = *reinterpret_cast(suspend_in_um + 1); + const auto ps_suspend_thread = reinterpret_cast(ntoskrnl_base + rip_rva + 5 + suspend_rva); + return v_ctx.syscall(ps_suspend_thread, pethread, nullptr); + } +} \ No newline at end of file diff --git a/kmem/set_mgr/set_mgr.hpp b/kmem/set_mgr/set_mgr.hpp new file mode 100644 index 0000000..5b99746 --- /dev/null +++ b/kmem/set_mgr/set_mgr.hpp @@ -0,0 +1,18 @@ +#pragma once +#include "../vdm_ctx/vdm_ctx.hpp" + +using PETHREAD = PVOID; +using PsSuspendThread = NTSTATUS(*)(PETHREAD, PULONG); +using PsLookupThreadByThreadId = NTSTATUS(*)(HANDLE, PETHREAD*); + +#define KE_BALANCE_SIG "\x65\x48\x8B\x04\x25\x00\x00\x00\x00\x48\x8B\x88\x00\x00\x00\x00\x48\x8D\x05" +#define KE_BALANCE_MASK "xxxxx????xxx????xxx" + +#define SUSPEND_THREAD_SIG "\xE8\x00\x00\x00\x00\x8B\xF8\xBA\x50\x73\x53\x75" +#define SUSPEND_THREAD_MASK "x????xxxxxxx" + +namespace set_mgr +{ + auto get_setmgr_pethread(vdm::vdm_ctx& v_ctx)->PETHREAD; + auto stop_setmgr(vdm::vdm_ctx& v_ctx, PETHREAD pethread)->NTSTATUS; +} \ No newline at end of file diff --git a/kmem/util/util.hpp b/kmem/util/util.hpp index fd07443..65a8fa1 100644 --- a/kmem/util/util.hpp +++ b/kmem/util/util.hpp @@ -320,4 +320,54 @@ namespace util } return NULL; } + + namespace memory + { + template + __forceinline auto sig_scan(const char(&signature)[pattern_length], const char(&mask)[pattern_length]) -> std::pair + { + static const auto ntoskrnl_module = + LoadLibraryEx( + "ntoskrnl.exe", + NULL, + DONT_RESOLVE_DLL_REFERENCES + ); + + static const auto p_idh = reinterpret_cast(ntoskrnl_module); + if (p_idh->e_magic != IMAGE_DOS_SIGNATURE) + return { {}, {} }; + + static const auto p_inh = reinterpret_cast((LPBYTE)ntoskrnl_module + p_idh->e_lfanew); + if (p_inh->Signature != IMAGE_NT_SIGNATURE) + return { {}, {} }; + + const auto pattern_view = + std::string_view + { + reinterpret_cast(ntoskrnl_module), + p_inh->OptionalHeader.SizeOfImage + }; + + std::array, pattern_length - 1> pattern{}; + for (std::size_t index = 0; index < pattern_length - 1; index++) + pattern[index] = { signature[index], mask[index] }; + + auto resultant_address = std::search + ( + pattern_view.cbegin(), + pattern_view.cend(), + pattern.cbegin(), + pattern.cend(), + [](char left, std::pair right) -> bool { + return (right.second == '?' || left == right.first); + }); + + const auto found_address = + resultant_address == pattern_view.cend() ? 0 : + reinterpret_cast(resultant_address.operator->()); + + const auto rva = found_address - reinterpret_cast(ntoskrnl_module); + return { found_address, rva }; + } + } } \ No newline at end of file