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