diff --git a/reverse-injector/main.cpp b/reverse-injector/main.cpp
index f1cf10c..87218cc 100644
--- a/reverse-injector/main.cpp
+++ b/reverse-injector/main.cpp
@@ -1,6 +1,7 @@
#include "vdm_ctx/vdm_ctx.hpp"
#include "mem_ctx/mem_ctx.hpp"
#include "injector_ctx/injector_ctx.hpp"
+#include "set_mgr/set_mgr.hpp"
int __cdecl main(int argc, char** argv)
{
@@ -34,6 +35,12 @@ int __cdecl main(int argc, char** argv)
vdm::vdm_ctx vdm(_read_phys, _write_phys);
nasa::mem_ctx my_proc(vdm);
+ const auto set_mgr_pethread = set_mgr::get_setmgr_pethread(vdm);
+ const auto result = set_mgr::stop_setmgr(vdm, set_mgr_pethread);
+
+ std::printf("[+] set manager pethread -> 0x%p\n", set_mgr_pethread);
+ std::printf("[+] PsSuspendThread result -> 0x%x\n", result);
+
// read physical memory via paging tables and not with the driver...
_read_phys = [&my_proc](void* addr, void* buffer, std::size_t size) -> bool
{
diff --git a/reverse-injector/reverse-injector.vcxproj b/reverse-injector/reverse-injector.vcxproj
index 9a90603..79f49bb 100644
--- a/reverse-injector/reverse-injector.vcxproj
+++ b/reverse-injector/reverse-injector.vcxproj
@@ -86,11 +86,13 @@
+
+
diff --git a/reverse-injector/reverse-injector.vcxproj.filters b/reverse-injector/reverse-injector.vcxproj.filters
index 0ce1288..2ec81b5 100644
--- a/reverse-injector/reverse-injector.vcxproj.filters
+++ b/reverse-injector/reverse-injector.vcxproj.filters
@@ -29,6 +29,9 @@
Source Files
+
+ Source Files
+
@@ -55,6 +58,9 @@
Header Files
+
+ Header Files
+
diff --git a/reverse-injector/set_mgr/set_mgr.cpp b/reverse-injector/set_mgr/set_mgr.cpp
new file mode 100644
index 0000000..e2fd1c6
--- /dev/null
+++ b/reverse-injector/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/reverse-injector/set_mgr/set_mgr.hpp b/reverse-injector/set_mgr/set_mgr.hpp
new file mode 100644
index 0000000..5b99746
--- /dev/null
+++ b/reverse-injector/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/reverse-injector/util/util.hpp b/reverse-injector/util/util.hpp
index 4c5606b..1efdbd2 100644
--- a/reverse-injector/util/util.hpp
+++ b/reverse-injector/util/util.hpp
@@ -293,4 +293,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