You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

87 lines
2.6 KiB

#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<std::uintptr_t>(target_ctx->dirbase));
orig_context.second =
reinterpret_cast<std::uintptr_t>(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<void*>(
this->hyperspace_context.first),
reinterpret_cast<void*>(
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<PEPROCESS>(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<std::uintptr_t>(orig_peproc) >> 12) << 12;
// offset into the page where the actual eprocess begins...
const auto clone_peproc_offset =
reinterpret_cast<std::uintptr_t>(orig_peproc) & (ULONG64)0xFFF;
v_ctx->wkm(clone_peproc,
reinterpret_cast<void*>(orig_peproc_page), PAGE_4KB);
clone_peproc = reinterpret_cast<PEPROCESS>(
reinterpret_cast<std::uintptr_t>(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<std::uintptr_t>(clone_peproc) + KPROCESS_DIRBASE_OFFSET;
v_ctx->wkm<std::uintptr_t>(
dirbase_ptr, hyperspace_context.second);
}
auto hyper_ctx::hyper_jmp(std::uint32_t tid) -> std::pair<bool, PETHREAD>
{
const auto pethread =
reinterpret_cast<std::uintptr_t>(
v_ctx->get_pethread(tid));
if (!pethread)
return { {}, {} };
v_ctx->wkm<PEPROCESS>(
pethread + KTHREAD_PKPROCESS_OFFSET, clone_peproc);
return { true, reinterpret_cast<PETHREAD>(pethread) };
}
auto hyper_ctx::hyper_ret(std::uint32_t tid) -> std::pair<bool, PETHREAD>
{
const auto pethread =
reinterpret_cast<std::uintptr_t>(
v_ctx->get_pethread(tid));
if (!pethread)
return { {}, {} };
v_ctx->wkm<PEPROCESS>(
pethread + KTHREAD_PKPROCESS_OFFSET, orig_peproc);
return { true, reinterpret_cast<PETHREAD>(pethread) };
}
}