|
|
|
@ -18,13 +18,30 @@ namespace hyperspace
|
|
|
|
|
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);
|
|
|
|
|
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));
|
|
|
|
|
v_ctx->wkm(clone_peproc, orig_peproc, 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
|
|
|
|
@ -34,26 +51,37 @@ namespace hyperspace
|
|
|
|
|
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);
|
|
|
|
|
v_ctx->wkm<std::uintptr_t>(
|
|
|
|
|
dirbase_ptr, hyperspace_context.second);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto hyper_ctx::hyper_jmp(std::uint32_t tid) -> void
|
|
|
|
|
auto hyper_ctx::hyper_jmp(std::uint32_t tid) -> std::pair<bool, PETHREAD>
|
|
|
|
|
{
|
|
|
|
|
const auto current_thread =
|
|
|
|
|
const auto pethread =
|
|
|
|
|
reinterpret_cast<std::uintptr_t>(
|
|
|
|
|
v_ctx->get_current_thread());
|
|
|
|
|
v_ctx->get_pethread(tid));
|
|
|
|
|
|
|
|
|
|
if (!pethread)
|
|
|
|
|
return { {}, {} };
|
|
|
|
|
|
|
|
|
|
v_ctx->wkm<PEPROCESS>(
|
|
|
|
|
current_thread + KTHREAD_PKPROCESS_OFFSET, clone_peproc);
|
|
|
|
|
pethread + KTHREAD_PKPROCESS_OFFSET, clone_peproc);
|
|
|
|
|
|
|
|
|
|
return { true, reinterpret_cast<PETHREAD>(pethread) };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto hyper_ctx::hyper_ret(std::uint32_t tid) -> void
|
|
|
|
|
auto hyper_ctx::hyper_ret(std::uint32_t tid) -> std::pair<bool, PETHREAD>
|
|
|
|
|
{
|
|
|
|
|
const auto current_thread =
|
|
|
|
|
const auto pethread =
|
|
|
|
|
reinterpret_cast<std::uintptr_t>(
|
|
|
|
|
v_ctx->get_current_thread());
|
|
|
|
|
v_ctx->get_pethread(tid));
|
|
|
|
|
|
|
|
|
|
if (!pethread)
|
|
|
|
|
return { {}, {} };
|
|
|
|
|
|
|
|
|
|
v_ctx->wkm<PEPROCESS>(
|
|
|
|
|
current_thread + KTHREAD_PKPROCESS_OFFSET, orig_peproc);
|
|
|
|
|
pethread + KTHREAD_PKPROCESS_OFFSET, orig_peproc);
|
|
|
|
|
|
|
|
|
|
return { true, reinterpret_cast<PETHREAD>(pethread) };
|
|
|
|
|
}
|
|
|
|
|
}
|