From 2330acef93ea12db7bd905e8890e44a973ac68e2 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Thu, 3 Dec 2020 20:22:57 -0800 Subject: [PATCH] updated project to use new PTM --- .../injector_ctx/injector_ctx.cpp | 24 +- .../injector_ctx/injector_ctx.hpp | 10 +- reverse-injector/main.cpp | 18 +- reverse-injector/mem_ctx/mem_ctx.hpp | 87 ------- .../mem_ctx.cpp => ptm_ctx/ptm_ctx.cpp} | 223 +++++++++--------- reverse-injector/ptm_ctx/ptm_ctx.hpp | 80 +++++++ reverse-injector/reverse-injector.vcxproj | 4 +- .../reverse-injector.vcxproj.filters | 12 +- reverse-injector/vdm_ctx/vdm_ctx.cpp | 10 +- reverse-injector/vdm_ctx/vdm_ctx.hpp | 21 +- 10 files changed, 243 insertions(+), 246 deletions(-) delete mode 100644 reverse-injector/mem_ctx/mem_ctx.hpp rename reverse-injector/{mem_ctx/mem_ctx.cpp => ptm_ctx/ptm_ctx.cpp} (66%) create mode 100644 reverse-injector/ptm_ctx/ptm_ctx.hpp diff --git a/reverse-injector/injector_ctx/injector_ctx.cpp b/reverse-injector/injector_ctx/injector_ctx.cpp index 6439def..b64e204 100644 --- a/reverse-injector/injector_ctx/injector_ctx.cpp +++ b/reverse-injector/injector_ctx/injector_ctx.cpp @@ -2,7 +2,7 @@ namespace nasa { - injector_ctx::injector_ctx(nasa::mem_ctx* map_into, nasa::mem_ctx* map_from) + injector_ctx::injector_ctx(ptm::ptm_ctx* map_into, ptm::ptm_ctx* map_from) : map_into(map_into), map_from(map_from), @@ -11,15 +11,14 @@ namespace nasa injector_ctx::~injector_ctx() { - const auto pml4 = reinterpret_cast( - map_into->set_page( - map_into->get_dirbase())); + const auto pml4 = + reinterpret_cast( + map_into->set_page( + map_into->dirbase)); // zero inserted pml4e's... for (const auto [real_idx, inserted_idx] : pml4_index_map) pml4[inserted_idx] = pml4e{ NULL }; - - while (!SwitchToThread()); } bool injector_ctx::init() const @@ -27,12 +26,12 @@ namespace nasa const auto source_pml4 = reinterpret_cast( map_from->set_page( - map_from->get_dirbase())); + map_from->dirbase)); const auto target_pml4 = reinterpret_cast( map_into->set_page( - map_into->get_dirbase())); + map_into->dirbase)); std::vector> present_pml4es; std::vector empty_pml4es; @@ -66,23 +65,23 @@ namespace nasa virt_addr_t virt_addr{ reinterpret_cast(translate) }; try { - virt_addr.pml4_index = pml4_index_map.at(virt_addr.pml4_index); + virt_addr.pml4_index = + pml4_index_map.at(virt_addr.pml4_index); } catch (const std::out_of_range& e) { // the pml4e is not in the map so we need to go get it // and put it inside of the map. also put it inside of // map_into's pml4... - const auto map_into_pml4 = reinterpret_cast( map_into->set_page( - map_into->get_dirbase())); + map_into->dirbase)); const auto map_from_pml4 = reinterpret_cast( map_from->set_page( - map_from->get_dirbase())); + map_from->dirbase)); const auto new_pml4e = map_from_pml4[virt_addr.pml4_index]; @@ -98,6 +97,7 @@ namespace nasa } } } + return reinterpret_cast(virt_addr.value); } } \ No newline at end of file diff --git a/reverse-injector/injector_ctx/injector_ctx.hpp b/reverse-injector/injector_ctx/injector_ctx.hpp index 119b748..baf458a 100644 --- a/reverse-injector/injector_ctx/injector_ctx.hpp +++ b/reverse-injector/injector_ctx/injector_ctx.hpp @@ -1,22 +1,22 @@ #pragma once -#include "../mem_ctx/mem_ctx.hpp" +#include "../ptm_ctx/ptm_ctx.hpp" namespace nasa { class injector_ctx { public: - explicit injector_ctx(nasa::mem_ctx* map_into, nasa::mem_ctx* map_from); + explicit injector_ctx(ptm::ptm_ctx* map_into, ptm::ptm_ctx* map_from); ~injector_ctx(); - std::uintptr_t translate(std::uintptr_t) const; - bool init() const; + auto translate(std::uintptr_t) const -> std::uintptr_t; + auto init() const -> bool; private: // std::uint8_t is 2^8 = 256 which is the same amount // of possible usermode pml4e's... // // also this is "real pml4e index" ---> "inserted pml4e index" mutable std::map pml4_index_map; - nasa::mem_ctx* map_into, *map_from; + ptm::ptm_ctx* map_into, *map_from; }; } \ No newline at end of file diff --git a/reverse-injector/main.cpp b/reverse-injector/main.cpp index 87218cc..99cc693 100644 --- a/reverse-injector/main.cpp +++ b/reverse-injector/main.cpp @@ -1,5 +1,5 @@ #include "vdm_ctx/vdm_ctx.hpp" -#include "mem_ctx/mem_ctx.hpp" +#include "ptm_ctx/ptm_ctx.hpp" #include "injector_ctx/injector_ctx.hpp" #include "set_mgr/set_mgr.hpp" @@ -20,20 +20,20 @@ int __cdecl main(int argc, char** argv) // read physical memory using the driver... vdm::read_phys_t _read_phys = - [&](void* addr, void* buffer, std::size_t size) -> bool + [&](void* addr, void* buffer, std::size_t size) -> bool { return vdm::read_phys(addr, buffer, size); }; // write physical memory using the driver... vdm::write_phys_t _write_phys = - [&](void* addr, void* buffer, std::size_t size) -> bool + [&](void* addr, void* buffer, std::size_t size) -> bool { return vdm::write_phys(addr, buffer, size); }; vdm::vdm_ctx vdm(_read_phys, _write_phys); - nasa::mem_ctx my_proc(vdm); + ptm::ptm_ctx my_proc(&vdm); const auto set_mgr_pethread = set_mgr::get_setmgr_pethread(vdm); const auto result = set_mgr::stop_setmgr(vdm, set_mgr_pethread); @@ -42,13 +42,15 @@ int __cdecl main(int argc, char** argv) std::printf("[+] PsSuspendThread result -> 0x%x\n", result); // read physical memory via paging tables and not with the driver... - _read_phys = [&my_proc](void* addr, void* buffer, std::size_t size) -> bool + _read_phys = + [&my_proc](void* addr, void* buffer, std::size_t size) -> bool { return my_proc.read_phys(buffer, addr, size); }; // write physical memory via paging tables and not with the driver... - _write_phys = [&my_proc](void* addr, void* buffer, std::size_t size) -> bool + _write_phys = + [&my_proc](void* addr, void* buffer, std::size_t size) -> bool { return my_proc.write_phys(buffer, addr, size); }; @@ -62,8 +64,8 @@ int __cdecl main(int argc, char** argv) vdm.set_read(_read_phys); vdm.set_write(_write_phys); - nasa::mem_ctx notepad_proc(vdm, std::atoi(argv[2])); - nasa::injector_ctx injector(&my_proc, ¬epad_proc); + ptm::ptm_ctx target_proc(&vdm, std::atoi(argv[2])); + nasa::injector_ctx injector(&my_proc, &target_proc); if (!injector.init()) { diff --git a/reverse-injector/mem_ctx/mem_ctx.hpp b/reverse-injector/mem_ctx/mem_ctx.hpp deleted file mode 100644 index ebc17d5..0000000 --- a/reverse-injector/mem_ctx/mem_ctx.hpp +++ /dev/null @@ -1,87 +0,0 @@ -#pragma once -#include "../util/nt.hpp" -#include "../vdm_ctx/vdm_ctx.hpp" - -namespace nasa -{ - class mem_ctx - { - public: - mem_ctx(vdm::vdm_ctx& v_ctx, std::uint32_t pid = GetCurrentProcessId()); - ~mem_ctx(); - - std::pair get_pte(void* addr, bool use_hyperspace = false); - void set_pte(void* addr, const ::pte& pte, bool use_hyperspace = false); - - std::pair get_pde(void* addr, bool use_hyperspace = false); - void set_pde(void* addr, const ::pde& pde, bool use_hyperspace = false); - - std::pair get_pdpte(void* addr, bool use_hyperspace = false); - void set_pdpte(void* addr, const ::pdpte& pdpte, bool use_hyperspace = false); - - std::pair get_pml4e(void* addr, bool use_hyperspace = false); - void set_pml4e(void* addr, const ::pml4e& pml4e, bool use_hyperspace = false); - - void* get_dirbase() const; - static void* get_dirbase(vdm::vdm_ctx& v_ctx, std::uint32_t pid); - - bool read_phys(void* buffer, void* addr, std::size_t size); - bool write_phys(void* buffer, void* addr, std::size_t size); - - template - T read_phys(void* addr) - { - T buffer; - read_phys((void*)&buffer, addr, sizeof(T)); - return buffer; - } - - template - void write_phys(void* addr, const T& data) - { - write_phys((void*)&data, addr, sizeof(T)); - } - - std::pair read_virtual(void* buffer, void* addr, std::size_t size); - std::pair write_virtual(void* buffer, void* addr, std::size_t size); - - template - __forceinline T read_virtual(void* addr) - { - T buffer; - read_virtual((void*)&buffer, addr, sizeof(T)); - return buffer; - } - - template - __forceinline void write_virtual(void* addr, const T& data) - { - write_virtual((void*)&data, addr, sizeof(T)); - } - - void* virt_to_phys(pt_entries& entries, void* addr); - void* set_page(void* addr); - void* get_page() const; - unsigned get_pid() const; - - pml4e operator[](std::uint16_t pml4_idx); - pdpte operator[](const std::pair& entry_idx); - pde operator[](const std::tuple& entry_idx); - pte operator[](const std::tuple& entry_idx); - private: - - bool hyperspace_entries(pt_entries& entries, void* addr); - void* dirbase; - vdm::vdm_ctx* v_ctx; - std::uint16_t pml4e_index, - pdpte_index, - pde_index, - pte_index, - page_offset; - - std::pair new_pdpt; - std::pair new_pd; - std::pair new_pt; - unsigned pid; - }; -} \ No newline at end of file diff --git a/reverse-injector/mem_ctx/mem_ctx.cpp b/reverse-injector/ptm_ctx/ptm_ctx.cpp similarity index 66% rename from reverse-injector/mem_ctx/mem_ctx.cpp rename to reverse-injector/ptm_ctx/ptm_ctx.cpp index 8d84258..bb87228 100644 --- a/reverse-injector/mem_ctx/mem_ctx.cpp +++ b/reverse-injector/ptm_ctx/ptm_ctx.cpp @@ -1,21 +1,26 @@ -#include "mem_ctx.hpp" +#include "ptm_ctx.hpp" -namespace nasa +namespace ptm { - mem_ctx::mem_ctx(vdm::vdm_ctx& v_ctx, std::uint32_t pid) + ptm_ctx::ptm_ctx(vdm::vdm_ctx* v_ctx, std::uint32_t pid) : - v_ctx(&v_ctx), - pid(pid), - dirbase(get_dirbase(v_ctx, pid)) + v_ctx(v_ctx), + dirbase(get_dirbase(*v_ctx, pid)), + pid(pid) { // find an empty pml4e inside of current processes pml4... const auto current_pml4 = - v_ctx.get_virtual(reinterpret_cast( - get_dirbase(v_ctx, GetCurrentProcessId()))); + v_ctx->get_virtual(reinterpret_cast( + get_dirbase(*v_ctx, GetCurrentProcessId()))); for (auto idx = 100u; idx > 0u; --idx) - if (!v_ctx.rkm(current_pml4 + (idx * sizeof pml4e)).value) + { + if (!v_ctx->rkm(current_pml4 + (idx * sizeof pml4e)).present) + { this->pml4e_index = idx; + break; + } + } // allocate a pdpt this->new_pdpt.second = @@ -31,13 +36,17 @@ namespace nasa // get page table entries for new pdpt pt_entries new_pdpt_entries; hyperspace_entries(new_pdpt_entries, new_pdpt.second); - this->new_pdpt.first = reinterpret_cast(new_pdpt_entries.pt.second.pfn << 12); + + this->new_pdpt.first = + reinterpret_cast( + new_pdpt_entries.pt.second.pfn << 12); // make a new pml4e that points to our new pdpt. new_pdpt_entries.pml4.second.pfn = new_pdpt_entries.pt.second.pfn; // set the pml4e to point to the new pdpt - set_pml4e(reinterpret_cast<::ppml4e>(get_dirbase()) + this->pml4e_index, new_pdpt_entries.pml4.second, true); + set_pml4e(reinterpret_cast<::ppml4e>(this->dirbase) + + this->pml4e_index, new_pdpt_entries.pml4.second, true); // make a new pd this->new_pd.second = @@ -54,7 +63,10 @@ namespace nasa // get paging table entries for pd pt_entries new_pd_entries; hyperspace_entries(new_pd_entries, this->new_pd.second); - this->new_pd.first = reinterpret_cast(new_pd_entries.pt.second.pfn << 12); + + this->new_pd.first = + reinterpret_cast( + new_pd_entries.pt.second.pfn << 12); // make a new pt this->new_pt.second = @@ -67,36 +79,39 @@ namespace nasa )); PAGE_IN(this->new_pt.second, PAGE_4KB); + // get paging table entries for pt pt_entries new_pt_entries; hyperspace_entries(new_pt_entries, this->new_pt.second); - this->new_pt.first = reinterpret_cast(new_pt_entries.pt.second.pfn << 12); + + this->new_pt.first = + reinterpret_cast( + new_pt_entries.pt.second.pfn << 12); } - mem_ctx::~mem_ctx() + ptm_ctx::~ptm_ctx() { - const auto pml4 = + const auto pml4 = reinterpret_cast( set_page(dirbase))[pml4e_index] = pml4e{ NULL }; } - void* mem_ctx::set_page(void* addr) + void* ptm_ctx::set_page(void* addr) { - // table entry change. ++pte_index; - if (pte_index >= 511) + if (pte_index > 511) { ++pde_index; pte_index = 0; } - if (pde_index >= 511) + if (pde_index > 511) { ++pdpte_index; pde_index = 0; } - if (pdpte_index >= 511) + if (pdpte_index > 511) pdpte_index = 0; pdpte new_pdpte = { NULL }; @@ -104,7 +119,6 @@ namespace nasa new_pdpte.rw = true; new_pdpte.pfn = reinterpret_cast(new_pd.first) >> 12; new_pdpte.user_supervisor = true; - new_pdpte.accessed = true; // set pdpte entry *reinterpret_cast(new_pdpt.second + pdpte_index) = new_pdpte; @@ -114,7 +128,6 @@ namespace nasa new_pde.rw = true; new_pde.pfn = reinterpret_cast(new_pt.first) >> 12; new_pde.user_supervisor = true; - new_pde.accessed = true; // set pde entry *reinterpret_cast(new_pd.second + pde_index) = new_pde; @@ -124,7 +137,6 @@ namespace nasa new_pte.rw = true; new_pte.pfn = reinterpret_cast(addr) >> 12; new_pte.user_supervisor = true; - new_pte.accessed = true; // set pte entry *reinterpret_cast(new_pt.second + pte_index) = new_pte; @@ -134,7 +146,7 @@ namespace nasa return get_page(); } - void* mem_ctx::get_page() const + void* ptm_ctx::get_page() const { // builds a new address given the state of all table indexes virt_addr_t new_addr; @@ -143,21 +155,42 @@ namespace nasa new_addr.pd_index = this->pde_index; new_addr.pt_index = this->pte_index; new_addr.offset = this->page_offset; + + // handle TLB issues, the TLB might need to be flushed for this entry... + __try + { + *(std::uint8_t*)new_addr.value = *(std::uint8_t*)new_addr.value; + return new_addr.value; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + // try again to access the page... + __try + { + *(std::uint8_t*)new_addr.value = *(std::uint8_t*)new_addr.value; + return new_addr.value; + } + // try one last time by yeilding execution... + __except (EXCEPTION_EXECUTE_HANDLER) + { + while (!SwitchToThread()) + continue; + } + } return new_addr.value; } - void* mem_ctx::get_dirbase(vdm::vdm_ctx& v_ctx, std::uint32_t pid) + void* ptm_ctx::get_dirbase(vdm::vdm_ctx& v_ctx, DWORD pid) { const auto peproc = - reinterpret_cast(v_ctx.get_peprocess(pid)); - - const auto dirbase = - v_ctx.rkm(peproc + 0x28); + reinterpret_cast( + v_ctx.get_peprocess(pid)); - return reinterpret_cast(dirbase.pfn << 12); + return reinterpret_cast( + v_ctx.rkm(peproc + 0x28).pfn << 12); } - bool mem_ctx::hyperspace_entries(pt_entries& entries, void* addr) + bool ptm_ctx::hyperspace_entries(pt_entries& entries, void* addr) { if (!addr || !dirbase) return false; @@ -199,95 +232,106 @@ namespace nasa return true; } - std::pair mem_ctx::get_pte(void* addr, bool use_hyperspace) + auto ptm_ctx::get_pte(void* addr, bool use_hyperspace) -> std::pair { if (!dirbase || !addr) - return {}; + return { {}, {} }; pt_entries entries; if ((use_hyperspace ? hyperspace_entries(entries, addr) : (bool)virt_to_phys(entries, addr))) return { entries.pt.first, entries.pt.second }; - return {}; + + return { {}, {} }; } - void mem_ctx::set_pte(void* addr, const ::pte& pte, bool use_hyperspace) + bool ptm_ctx::set_pte(void* addr, const ::pte& pte, bool use_hyperspace) { if (!dirbase || !addr) - return; + return false; if (use_hyperspace) - v_ctx->wkm(v_ctx->get_virtual(reinterpret_cast(addr)), pte); - else - write_phys(addr, pte); + return v_ctx->wkm( + v_ctx->get_virtual( + reinterpret_cast(addr)), pte); + + return write_phys(addr, pte); } - std::pair mem_ctx::get_pde(void* addr, bool use_hyperspace) + auto ptm_ctx::get_pde(void* addr, bool use_hyperspace) -> std::pair { if (!dirbase || !addr) - return {}; + return { {}, {} }; pt_entries entries; if ((use_hyperspace ? hyperspace_entries(entries, addr) : (bool)virt_to_phys(entries, addr))) return { entries.pd.first, entries.pd.second }; - return {}; + return { {}, {} }; } - void mem_ctx::set_pde(void* addr, const ::pde& pde, bool use_hyperspace) + bool ptm_ctx::set_pde(void* addr, const ::pde& pde, bool use_hyperspace) { - if (!this->dirbase || !addr) - return; + if (!dirbase || !addr) + return false; if (use_hyperspace) - v_ctx->wkm(v_ctx->get_virtual(reinterpret_cast(addr)), pde); - else - write_phys(addr, pde); + return v_ctx->wkm( + v_ctx->get_virtual( + reinterpret_cast(addr)), pde); + + return write_phys(addr, pde); } - std::pair mem_ctx::get_pdpte(void* addr, bool use_hyperspace) + auto ptm_ctx::get_pdpte(void* addr, bool use_hyperspace) -> std::pair { if (!dirbase || !addr) - return {}; + return { {}, {} }; pt_entries entries; if ((use_hyperspace ? hyperspace_entries(entries, addr) : (bool)virt_to_phys(entries, addr))) return { entries.pdpt.first, entries.pdpt.second }; - return {}; + + return { {}, {} }; } - void mem_ctx::set_pdpte(void* addr, const ::pdpte& pdpte, bool use_hyperspace) + bool ptm_ctx::set_pdpte(void* addr, const ::pdpte& pdpte, bool use_hyperspace) { - if (!this->dirbase || !addr) - return; + if (!dirbase || !addr) + return false; if (use_hyperspace) - v_ctx->wkm(v_ctx->get_virtual(reinterpret_cast(addr)), pdpte); - else - write_phys(addr, pdpte); + return v_ctx->wkm( + v_ctx->get_virtual( + reinterpret_cast(addr)), pdpte); + + return write_phys(addr, pdpte); } - std::pair mem_ctx::get_pml4e(void* addr, bool use_hyperspace) + auto ptm_ctx::get_pml4e(void* addr, bool use_hyperspace) -> std::pair { - if (!this->dirbase || !addr) - return {}; + if (!dirbase || !addr) + return { {}, {} }; pt_entries entries; if ((use_hyperspace ? hyperspace_entries(entries, addr) : (bool)virt_to_phys(entries, addr))) return { entries.pml4.first, entries.pml4.second }; - return {}; + + return { {}, {} }; } - void mem_ctx::set_pml4e(void* addr, const ::pml4e& pml4e, bool use_hyperspace) + bool ptm_ctx::set_pml4e(void* addr, const ::pml4e& pml4e, bool use_hyperspace) { - if (!this->dirbase || !addr) - return; + if (!dirbase || !addr) + return false; if (use_hyperspace) - v_ctx->wkm(v_ctx->get_virtual(reinterpret_cast(addr)), pml4e); - else - write_phys(addr, pml4e); + return v_ctx->wkm( + v_ctx->get_virtual( + reinterpret_cast(addr)), pml4e); + + return write_phys(addr, pml4e); } - std::pair mem_ctx::read_virtual(void* buffer, void* addr, std::size_t size) + auto ptm_ctx::read_virtual(void* buffer, void* addr, std::size_t size) -> std::pair { if (!buffer || !addr || !size || !dirbase) return {}; @@ -329,7 +373,7 @@ namespace nasa } } - std::pair mem_ctx::write_virtual(void* buffer, void* addr, std::size_t size) + auto ptm_ctx::write_virtual(void* buffer, void* addr, std::size_t size) -> std::pair { if (!buffer || !addr || !size || !dirbase) return {}; @@ -371,7 +415,7 @@ namespace nasa } } - bool mem_ctx::read_phys(void* buffer, void* addr, std::size_t size) + bool ptm_ctx::read_phys(void* buffer, void* addr, std::size_t size) { if (!buffer || !addr || !size) return false; @@ -388,7 +432,7 @@ namespace nasa return true; } - bool mem_ctx::write_phys(void* buffer, void* addr, std::size_t size) + bool ptm_ctx::write_phys(void* buffer, void* addr, std::size_t size) { if (!buffer || !addr || !size) return false; @@ -405,9 +449,9 @@ namespace nasa return true; } - void* mem_ctx::virt_to_phys(pt_entries& entries, void* addr) + void* ptm_ctx::virt_to_phys(pt_entries& entries, void* addr) { - if (!addr || !this->dirbase) + if (!addr || !dirbase) return {}; const virt_addr_t virt_addr{ addr }; @@ -451,37 +495,4 @@ namespace nasa return reinterpret_cast((pte.pfn << 12) + virt_addr.offset); } - - unsigned mem_ctx::get_pid() const - { - return this->pid; - } - - void* mem_ctx::get_dirbase() const - { - return this->dirbase; - } - - pml4e mem_ctx::operator[](std::uint16_t pml4_idx) - { - return read_phys<::pml4e>(reinterpret_cast(this->dirbase) + pml4_idx); - } - - pdpte mem_ctx::operator[](const std::pair& entry_idx) - { - const auto pml4_entry = this->operator[](entry_idx.first); - return read_phys<::pdpte>(reinterpret_cast(pml4_entry.pfn << 12) + entry_idx.second); - } - - pde mem_ctx::operator[](const std::tuple& entry_idx) - { - const auto pdpt_entry = this->operator[]({ std::get<0>(entry_idx), std::get<1>(entry_idx) }); - return read_phys<::pde>(reinterpret_cast(pdpt_entry.pfn << 12) + std::get<2>(entry_idx)); - } - - pte mem_ctx::operator[](const std::tuple& entry_idx) - { - const auto pd_entry = this->operator[]({ std::get<0>(entry_idx), std::get<1>(entry_idx), std::get<2>(entry_idx) }); - return read_phys<::pte>(reinterpret_cast(pd_entry.pfn << 12) + std::get<3>(entry_idx)); - } } \ No newline at end of file diff --git a/reverse-injector/ptm_ctx/ptm_ctx.hpp b/reverse-injector/ptm_ctx/ptm_ctx.hpp new file mode 100644 index 0000000..2ac89e8 --- /dev/null +++ b/reverse-injector/ptm_ctx/ptm_ctx.hpp @@ -0,0 +1,80 @@ +#pragma once +#include "../util/nt.hpp" +#include "../vdm_ctx/vdm_ctx.hpp" + +namespace ptm +{ + class ptm_ctx + { + public: + explicit ptm_ctx(vdm::vdm_ctx* v_ctx, std::uint32_t pid = GetCurrentProcessId()); + ~ptm_ctx(); + + auto get_pte(void* addr, bool use_hyperspace = false) -> std::pair; + bool set_pte(void* addr, const ::pte& pte, bool use_hyperspace = false); + + auto get_pde(void* addr, bool use_hyperspace = false) -> std::pair; + bool set_pde(void* addr, const ::pde& pde, bool use_hyperspace = false); + + auto get_pdpte(void* addr, bool use_hyperspace = false) -> std::pair; + bool set_pdpte(void* addr, const ::pdpte& pdpte, bool use_hyperspace = false); + + auto get_pml4e(void* addr, bool use_hyperspace = false) -> std::pair; + bool set_pml4e(void* addr, const ::pml4e& pml4e, bool use_hyperspace = false); + static void* get_dirbase(vdm::vdm_ctx& v_ctx, DWORD pid); + + bool read_phys(void* buffer, void* addr, std::size_t size); + bool write_phys(void* buffer, void* addr, std::size_t size); + + template + __forceinline T read_phys(void* addr) + { + T buffer; + read_phys((void*)&buffer, addr, sizeof(T)); + return buffer; + } + + template + __forceinline bool write_phys(void* addr, const T& data) + { + return write_phys((void*)&data, addr, sizeof(T)); + } + + auto read_virtual(void* buffer, void* addr, std::size_t size) -> std::pair; + auto write_virtual(void* buffer, void* addr, std::size_t size) -> std::pair; + + template + __forceinline T read_virtual(void* addr) + { + T buffer; + read_virtual((void*)&buffer, addr, sizeof(T)); + return buffer; + } + + template + __forceinline void write_virtual(void* addr, const T& data) + { + write_virtual((void*)&data, addr, sizeof(T)); + } + + void* virt_to_phys(pt_entries& entries, void* addr); + bool hyperspace_entries(pt_entries& entries, void* addr); + + void* set_page(void* addr); + void* get_page() const; + + unsigned pid; + void* dirbase; + vdm::vdm_ctx* v_ctx; + private: + std::uint16_t pml4e_index, + pdpte_index, + pde_index, + pte_index, + page_offset; + + std::pair new_pdpt; + std::pair new_pd; + std::pair new_pt; + }; +} \ No newline at end of file diff --git a/reverse-injector/reverse-injector.vcxproj b/reverse-injector/reverse-injector.vcxproj index 79f49bb..0ff95da 100644 --- a/reverse-injector/reverse-injector.vcxproj +++ b/reverse-injector/reverse-injector.vcxproj @@ -85,13 +85,13 @@ - + - + diff --git a/reverse-injector/reverse-injector.vcxproj.filters b/reverse-injector/reverse-injector.vcxproj.filters index 2ec81b5..4aa2733 100644 --- a/reverse-injector/reverse-injector.vcxproj.filters +++ b/reverse-injector/reverse-injector.vcxproj.filters @@ -23,15 +23,15 @@ Source Files - - Source Files - Source Files Source Files + + Source Files + @@ -52,15 +52,15 @@ Header Files\util - - Header Files - Header Files Header Files + + Header Files + diff --git a/reverse-injector/vdm_ctx/vdm_ctx.cpp b/reverse-injector/vdm_ctx/vdm_ctx.cpp index 1454478..d699f74 100644 --- a/reverse-injector/vdm_ctx/vdm_ctx.cpp +++ b/reverse-injector/vdm_ctx/vdm_ctx.cpp @@ -2,11 +2,7 @@ namespace vdm { - vdm_ctx::vdm_ctx - ( - std::function& read_func, - std::function& write_func - ) + vdm_ctx::vdm_ctx(read_phys_t& read_func, write_phys_t& write_func) : read_phys(read_func), write_phys(write_func) @@ -41,12 +37,12 @@ namespace vdm search_thread.join(); } - void vdm_ctx::set_read(std::function& read_func) + void vdm_ctx::set_read(read_phys_t& read_func) { this->read_phys = read_func; } - void vdm_ctx::set_write(std::function& write_func) + void vdm_ctx::set_write(write_phys_t& write_func) { this->write_phys = write_func; } diff --git a/reverse-injector/vdm_ctx/vdm_ctx.hpp b/reverse-injector/vdm_ctx/vdm_ctx.hpp index 37bc3c4..c8d8878 100644 --- a/reverse-injector/vdm_ctx/vdm_ctx.hpp +++ b/reverse-injector/vdm_ctx/vdm_ctx.hpp @@ -26,14 +26,9 @@ namespace vdm class vdm_ctx { public: - vdm_ctx - ( - std::function& read_func, - std::function& write_func - ); - - void set_read(std::function& read_func); - void set_write(std::function& write_func); + explicit vdm_ctx(read_phys_t& read_func, write_phys_t& write_func); + void set_read(read_phys_t& read_func); + void set_write(write_phys_t& write_func); template __forceinline std::invoke_result_t syscall(void* addr, Ts ... args) const @@ -83,12 +78,12 @@ namespace vdm } template - __forceinline void wkm(std::uintptr_t addr, const T& value) + __forceinline auto wkm(std::uintptr_t addr, const T& value) -> bool { static const auto ntoskrnl_memcpy = util::get_kmodule_export("ntoskrnl.exe", "memcpy"); - this->syscall( + return this->syscall( ntoskrnl_memcpy, (void*)addr, &value, sizeof T); } @@ -118,11 +113,11 @@ namespace vdm ); return peproc; } + private: void locate_syscall(std::uintptr_t begin, std::uintptr_t end) const; bool valid_syscall(void* syscall_addr) const; - - std::function read_phys; - std::function write_phys; + read_phys_t read_phys; + write_phys_t write_phys; }; } \ No newline at end of file