#include "injector_ctx.hpp" namespace nasa { injector_ctx::injector_ctx(nasa::mem_ctx* map_into, nasa::mem_ctx* map_from) : map_into(map_into), map_from(map_from) {} injector_ctx::~injector_ctx() { const auto pml4 = reinterpret_cast( this->map_into->set_page( this->map_into->get_dirbase())); // zero inserted pml4e's... for (const auto [real_idx, inserted_idx] : this->pml4_index_map) pml4[inserted_idx] = pml4e{ NULL }; while (!SwitchToThread()); } bool injector_ctx::init() const { const auto source_pml4 = reinterpret_cast( map_from->set_page( map_from->get_dirbase())); const auto target_pml4 = reinterpret_cast( map_into->set_page( map_into->get_dirbase())); std::vector> present_pml4es; std::vector empty_pml4es; // find present pml4e's in usermode, and also find empty pml4e's in usermode... for (auto idx = 0u; idx < 256; ++idx) { if (source_pml4[idx].present) present_pml4es.push_back({ idx, source_pml4[idx] }); if (!target_pml4[idx].present) empty_pml4es.push_back(idx); } // pretty much never going to happen but just in case :^) if (present_pml4es.size() > empty_pml4es.size()) return false; // setup translation table and insert pml4e's... for (auto idx = 0u; idx < present_pml4es.size(); ++idx) { this->pml4_index_map.insert({ present_pml4es[idx].first, empty_pml4es[idx] }); target_pml4[empty_pml4es[idx]] = present_pml4es[idx].second; } return true; } // translate the pml4 index to the correct pml4 index... std::uintptr_t injector_ctx::translate(std::uintptr_t translate) const { virt_addr_t virt_addr{ reinterpret_cast(translate) }; virt_addr.pml4_index = pml4_index_map[virt_addr.pml4_index]; return reinterpret_cast(virt_addr.value); } }