#include "hyper_ctx.hpp" namespace hyperspace { hyper_ctx::hyper_ctx(ptm::ptm_ctx* target_ctx) : target_ctx(target_ctx), v_ctx(target_ctx->v_ctx) { orig_context.first = v_ctx->get_virtual( reinterpret_cast(target_ctx->dirbase)); orig_context.second = reinterpret_cast(target_ctx->dirbase); // make a new context 1:1 with the target process... hyperspace_context.first = v_ctx->kalloc(PAGE_4KB); hyperspace_context.second = v_ctx->get_physical(this->hyperspace_context.first); v_ctx->wkm(reinterpret_cast( this->hyperspace_context.first), reinterpret_cast( this->orig_context.first), PAGE_4KB); // make a new kprocess 1:1 with the target process... orig_peproc = v_ctx->get_peprocess(target_ctx->pid); clone_peproc = reinterpret_cast(v_ctx->kalloc(PAGE_4KB)); // usually PEPROCESS's are 0x80 into a page... // there is some structure above an EPROCESS i do not know what it is // but there is indeed one there so we are gunna copy that bitch! const auto orig_peproc_page = (reinterpret_cast(orig_peproc) >> 12) << 12; // offset into the page where the actual eprocess begins... const auto clone_peproc_offset = reinterpret_cast(orig_peproc) & (ULONG64)0xFFF; v_ctx->wkm(clone_peproc, reinterpret_cast(orig_peproc_page), PAGE_4KB); clone_peproc = reinterpret_cast( reinterpret_cast(clone_peproc) + clone_peproc_offset); // 1: kd > dt !_KPROCESS // nt!_KPROCESS // + 0x000 Header : _DISPATCHER_HEADER // + 0x018 ProfileListHead : _LIST_ENTRY // + 0x028 DirectoryTableBase : Uint8B <=== swap this with new pml4... const auto dirbase_ptr = reinterpret_cast(clone_peproc) + KPROCESS_DIRBASE_OFFSET; v_ctx->wkm( dirbase_ptr, hyperspace_context.second); } auto hyper_ctx::hyper_jmp(std::uint32_t tid) -> std::pair { const auto pethread = reinterpret_cast( v_ctx->get_pethread(tid)); if (!pethread) return { {}, {} }; v_ctx->wkm( pethread + KTHREAD_PKPROCESS_OFFSET, clone_peproc); return { true, reinterpret_cast(pethread) }; } auto hyper_ctx::hyper_ret(std::uint32_t tid) -> std::pair { const auto pethread = reinterpret_cast( v_ctx->get_pethread(tid)); if (!pethread) return { {}, {} }; v_ctx->wkm( pethread + KTHREAD_PKPROCESS_OFFSET, orig_peproc); return { true, reinterpret_cast(pethread) }; } }