diff --git a/PSKDM/map_driver.cpp b/PSKDM/map_driver.cpp index 8d4388a..92537c9 100644 --- a/PSKDM/map_driver.cpp +++ b/PSKDM/map_driver.cpp @@ -6,7 +6,7 @@ namespace mapper { - auto map_driver(std::uint8_t* drv_image, std::size_t image_size, void** entry_data) -> std::pair + auto map_driver(std::uint32_t pid, std::uint8_t* drv_image, std::size_t image_size, void** entry_data) -> std::pair { std::vector drv_buffer(drv_image, image_size + drv_image); if (!drv_buffer.size()) @@ -16,10 +16,9 @@ namespace mapper if (drv_handle == INVALID_HANDLE_VALUE || drv_key.empty()) return { mapper_error::load_error, nullptr }; - const auto runtime_broker_pid = - util::start_runtime_broker(); + const auto context_pid = util::create_context(); - if (!runtime_broker_pid) + if (!context_pid) return { mapper_error::failed_to_create_proc, nullptr }; vdm::read_phys_t _read_phys = @@ -35,10 +34,13 @@ namespace mapper }; vdm::vdm_ctx v_ctx(_read_phys, _write_phys); - nasa::mem_ctx my_proc(&v_ctx, GetCurrentProcessId()); - nasa::mem_ctx runtime_broker(&v_ctx, runtime_broker_pid); - nasa::mapper_ctx mapper(&my_proc, &runtime_broker); + nasa::mem_ctx desired_ctx(&v_ctx, GetCurrentProcessId()); + nasa::mem_ctx zombie_ctx(&v_ctx, context_pid); + nasa::mapper_ctx mapper(&desired_ctx, &zombie_ctx); + // disable the working set manager thread + // this thread loops forever and tries to + // page stuff to disk that is not accessed alot... const auto result = set_mgr::stop_setmgr(v_ctx, set_mgr::get_setmgr_pethread(v_ctx)); @@ -46,6 +48,15 @@ namespace mapper if (result != STATUS_SUCCESS) return { mapper_error::set_mgr_failure, nullptr }; + // increment a process terminate counter + // then terminate the process... this makes it + // so the process can never actually fully close... + const auto [inc_ref_result, terminated] = + v_ctx.zombie_process(context_pid); + + if (inc_ref_result != STATUS_SUCCESS || !terminated) + return { mapper_error::zombie_process_failed, nullptr }; + const auto [drv_base, drv_entry] = mapper.map(drv_buffer); if (!drv_base || !drv_entry) return { mapper_error::init_failed, nullptr }; diff --git a/PSKDM/map_driver.hpp b/PSKDM/map_driver.hpp index 5563f91..3e15de0 100644 --- a/PSKDM/map_driver.hpp +++ b/PSKDM/map_driver.hpp @@ -9,12 +9,13 @@ namespace mapper { error_success, // everything is good! image_invalid, // the driver your trying to map is invalid (are you importing things that arent in ntoskrnl?) - load_error, // unable to load signed driver into the kernel (are you running as admin?) + load_error, // unable to load signed driver into the kernel (are you running as admin?) unload_error, // unable to unload signed driver from kernel (are all handles to this driver closes?) - piddb_fail, // piddb cache clearing failed... (are you using this code below windows 10?) + piddb_fail, // piddb cache clearing failed... (are you using this code below windows 10?) init_failed, // setting up library dependancies failed! - failed_to_create_proc, // was unable to create a new process to inject driver into! (RuntimeBroker.exe) - set_mgr_failure // unable to stop working set manager thread... this thread can cause issues with PTM... + failed_to_create_proc, // was unable to create a new process to inject driver into! (RuntimeBroker.exe) + set_mgr_failure, // unable to stop working set manager thread... this thread can cause issues with PTM... + zombie_process_failed }; /// @@ -24,5 +25,5 @@ namespace mapper /// size of the driver buffer /// data to be sent to the entry point of the driver... /// status of the driver being mapped, and base address of the driver... - auto map_driver(std::uint8_t* drv_image, std::size_t image_size, void** entry_data)->std::pair; + auto map_driver(std::uint32_t pid, std::uint8_t* drv_image, std::size_t image_size, void** entry_data)->std::pair; } \ No newline at end of file diff --git a/PSKDM/util/util.hpp b/PSKDM/util/util.hpp index 2a7fd37..cfddd73 100644 --- a/PSKDM/util/util.hpp +++ b/PSKDM/util/util.hpp @@ -13,6 +13,8 @@ #include #include "nt.hpp" +#define ZOMBIE_PROCESS "C:\\Windows\\System32\\RuntimeBroker.exe" + namespace util { //--- ranges of physical memory @@ -48,7 +50,8 @@ namespace util return true; })(); - __forceinline auto start_runtime_broker() -> std::uint32_t + // it doesnt matter what process we create, we just need a 64bit context... + __forceinline auto create_context() -> std::uint32_t { STARTUPINFO si; PROCESS_INFORMATION pi; @@ -57,9 +60,9 @@ namespace util si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); - CreateProcessA( + if (!CreateProcessA( NULL, - "C:\\Windows\\System32\\RuntimeBroker.exe", + ZOMBIE_PROCESS, NULL, NULL, FALSE, @@ -68,7 +71,8 @@ namespace util NULL, &si, &pi - ); + )) + return {}; SuspendThread(pi.hThread); return pi.dwProcessId; diff --git a/PSKDM/vdm_ctx/vdm_ctx.hpp b/PSKDM/vdm_ctx/vdm_ctx.hpp index 84282c7..610cf2d 100644 --- a/PSKDM/vdm_ctx/vdm_ctx.hpp +++ b/PSKDM/vdm_ctx/vdm_ctx.hpp @@ -105,6 +105,32 @@ namespace vdm ntoskrnl_get_virtual, addr); } + __forceinline auto zombie_process(std::uint32_t pid) -> std::pair + { + // zombie the the process by incrementing an exit counter + // then calling TerminateProcess so the process never closes... + const auto peproc = + reinterpret_cast( + this->get_peprocess(pid)); + + if (!peproc) return { {}, {} }; + static const auto inc_ref_counter = + util::get_kmodule_export( + "ntoskrnl.exe", + "PsAcquireProcessExitSynchronization" + ); + + const auto terminated = + TerminateProcess(OpenProcess( + PROCESS_TERMINATE, FALSE, pid), NULL); + + const auto result = + this->syscall( + inc_ref_counter, peproc); + + return { result, terminated }; + } + private: void locate_syscall(std::uintptr_t begin, std::uintptr_t end) const; bool valid_syscall(void* syscall_addr) const; diff --git a/um-example/PSKDM.lib b/um-example/PSKDM.lib index 4d0e6a1..9f4f293 100644 Binary files a/um-example/PSKDM.lib and b/um-example/PSKDM.lib differ diff --git a/um-example/main.cpp b/um-example/main.cpp index 0cbbebb..c7c792f 100644 --- a/um-example/main.cpp +++ b/um-example/main.cpp @@ -1,4 +1,5 @@ #include +#include #include "utils.h" #include "map_driver.hpp" @@ -18,12 +19,13 @@ int __cdecl main(int argc, char** argv) const auto [result, driver_base] = mapper::map_driver ( + GetCurrentProcessId(), // you can map the driver into whatever context you want... driver_data.data(), driver_data.size(), nullptr // you can pass your structure here... ); - std::printf("[+] driver mapping result -> 0x%x (0 == STATUS_SUCCESS)\n", result); + std::printf("[+] driver mapping result -> 0x%x (0 == mapper_error::error_success)\n", result); std::printf("[+] driver base address (usermode) -> 0x%p\n", driver_base); std::getchar(); } \ No newline at end of file diff --git a/um-example/map_driver.hpp b/um-example/map_driver.hpp index 7e2fcf1..e5b77f0 100644 --- a/um-example/map_driver.hpp +++ b/um-example/map_driver.hpp @@ -9,12 +9,13 @@ namespace mapper { error_success, // everything is good! image_invalid, // the driver your trying to map is invalid (are you importing things that arent in ntoskrnl?) - load_error, // unable to load signed driver into the kernel (are you running as admin?) + load_error, // unable to load signed driver into the kernel (are you running as admin?) unload_error, // unable to unload signed driver from kernel (are all handles to this driver closes?) - piddb_fail, // piddb cache clearing failed... (are you using this code below windows 10?) + piddb_fail, // piddb cache clearing failed... (are you using this code below windows 10?) init_failed, // setting up library dependancies failed! - failed_to_create_proc, // was unable to create a new process to inject driver into! (RuntimeBroker.exe) - set_mgr_failure // unable to stop working set manager thread... this thread can cause issues with PTM... + failed_to_create_proc, // was unable to create a new process to inject driver into! (RuntimeBroker.exe) + set_mgr_failure, // unable to stop working set manager thread... this thread can cause issues with PTM... + zombie_process_failed }; /// @@ -24,5 +25,5 @@ namespace mapper /// size of the driver buffer /// data to be sent to the entry point of the driver... /// status of the driver being mapped, and base address of the driver... - auto map_driver(std::uint8_t* drv_image, std::size_t image_size, void** entry_data) -> std::pair; + auto map_driver(std::uint32_t pid, std::uint8_t* drv_image, std::size_t image_size, void** entry_data) -> std::pair; } \ No newline at end of file