renamed mem_ctx to ptm_ctx

master
_xeroxz 4 years ago
parent ef58c2c086
commit 6d71fea24e

@ -143,12 +143,12 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
<ClCompile Include="mem_ctx\mem_ctx.cpp" /> <ClCompile Include="ptm_ctx\ptm_ctx.cpp" />
<ClCompile Include="set_mgr\set_mgr.cpp" /> <ClCompile Include="set_mgr\set_mgr.cpp" />
<ClCompile Include="vdm_ctx\vdm_ctx.cpp" /> <ClCompile Include="vdm_ctx\vdm_ctx.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="mem_ctx\mem_ctx.hpp" /> <ClInclude Include="ptm_ctx\ptm_ctx.hpp" />
<ClInclude Include="set_mgr\set_mgr.hpp" /> <ClInclude Include="set_mgr\set_mgr.hpp" />
<ClInclude Include="util\loadup.hpp" /> <ClInclude Include="util\loadup.hpp" />
<ClInclude Include="util\nt.hpp" /> <ClInclude Include="util\nt.hpp" />

@ -26,10 +26,10 @@
<ClCompile Include="vdm_ctx\vdm_ctx.cpp"> <ClCompile Include="vdm_ctx\vdm_ctx.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="mem_ctx\mem_ctx.cpp"> <ClCompile Include="set_mgr\set_mgr.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="set_mgr\set_mgr.cpp"> <ClCompile Include="ptm_ctx\ptm_ctx.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
@ -46,9 +46,6 @@
<ClInclude Include="vdm\vdm.hpp"> <ClInclude Include="vdm\vdm.hpp">
<Filter>Header Files\vdm</Filter> <Filter>Header Files\vdm</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="mem_ctx\mem_ctx.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="util\loadup.hpp"> <ClInclude Include="util\loadup.hpp">
<Filter>Header Files\util</Filter> <Filter>Header Files\util</Filter>
</ClInclude> </ClInclude>
@ -58,6 +55,9 @@
<ClInclude Include="set_mgr\set_mgr.hpp"> <ClInclude Include="set_mgr\set_mgr.hpp">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="ptm_ctx\ptm_ctx.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="icon.rc"> <ResourceCompile Include="icon.rc">

@ -1,4 +1,4 @@
#include "mem_ctx/mem_ctx.hpp" #include "ptm_ctx/ptm_ctx.hpp"
#include "set_mgr/set_mgr.hpp" #include "set_mgr/set_mgr.hpp"
int __cdecl main(int argc, char** argv) int __cdecl main(int argc, char** argv)
@ -23,7 +23,7 @@ int __cdecl main(int argc, char** argv)
}; };
vdm::vdm_ctx vdm(_read_phys, _write_phys); 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 = const auto set_mgr_pethread =
set_mgr::get_setmgr_pethread(vdm); set_mgr::get_setmgr_pethread(vdm);
@ -55,7 +55,6 @@ int __cdecl main(int argc, char** argv)
// abuse test, make a vdm using a mem_ctx... // abuse test, make a vdm using a mem_ctx...
vdm = vdm::vdm_ctx(_read_phys, _write_phys); vdm = vdm::vdm_ctx(_read_phys, _write_phys);
const auto current_pml4 = const auto current_pml4 =
reinterpret_cast<ppml4e>( reinterpret_cast<ppml4e>(
my_proc.set_page(my_proc.dirbase)); my_proc.set_page(my_proc.dirbase));

@ -1,8 +1,8 @@
#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), v_ctx(v_ctx),
dirbase(get_dirbase(*v_ctx, pid)), dirbase(get_dirbase(*v_ctx, pid)),
@ -14,8 +14,13 @@ namespace nasa
get_dirbase(*v_ctx, GetCurrentProcessId()))); get_dirbase(*v_ctx, GetCurrentProcessId())));
for (auto idx = 100u; idx > 0u; --idx) for (auto idx = 100u; idx > 0u; --idx)
{
if (!v_ctx->rkm<pml4e>(current_pml4 + (idx * sizeof pml4e)).present) if (!v_ctx->rkm<pml4e>(current_pml4 + (idx * sizeof pml4e)).present)
{
this->pml4e_index = idx; this->pml4e_index = idx;
break;
}
}
// allocate a pdpt // allocate a pdpt
this->new_pdpt.second = this->new_pdpt.second =
@ -84,30 +89,29 @@ namespace nasa
new_pt_entries.pt.second.pfn << 12); new_pt_entries.pt.second.pfn << 12);
} }
mem_ctx::~mem_ctx() ptm_ctx::~ptm_ctx()
{ {
const auto pml4 = const auto pml4 =
reinterpret_cast<ppml4e>( reinterpret_cast<ppml4e>(
set_page(dirbase))[pml4e_index] = pml4e{ NULL }; 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; ++pte_index;
if (pte_index >= 511) if (pte_index > 511)
{ {
++pde_index; ++pde_index;
pte_index = 0; pte_index = 0;
} }
if (pde_index >= 511) if (pde_index > 511)
{ {
++pdpte_index; ++pdpte_index;
pde_index = 0; pde_index = 0;
} }
if (pdpte_index >= 511) if (pdpte_index > 511)
pdpte_index = 0; pdpte_index = 0;
pdpte new_pdpte = { NULL }; pdpte new_pdpte = { NULL };
@ -115,7 +119,6 @@ namespace nasa
new_pdpte.rw = true; new_pdpte.rw = true;
new_pdpte.pfn = reinterpret_cast<std::uintptr_t>(new_pd.first) >> 12; new_pdpte.pfn = reinterpret_cast<std::uintptr_t>(new_pd.first) >> 12;
new_pdpte.user_supervisor = true; new_pdpte.user_supervisor = true;
new_pdpte.accessed = true;
// set pdpte entry // set pdpte entry
*reinterpret_cast<pdpte*>(new_pdpt.second + pdpte_index) = new_pdpte; *reinterpret_cast<pdpte*>(new_pdpt.second + pdpte_index) = new_pdpte;
@ -125,7 +128,6 @@ namespace nasa
new_pde.rw = true; new_pde.rw = true;
new_pde.pfn = reinterpret_cast<std::uintptr_t>(new_pt.first) >> 12; new_pde.pfn = reinterpret_cast<std::uintptr_t>(new_pt.first) >> 12;
new_pde.user_supervisor = true; new_pde.user_supervisor = true;
new_pde.accessed = true;
// set pde entry // set pde entry
*reinterpret_cast<pde*>(new_pd.second + pde_index) = new_pde; *reinterpret_cast<pde*>(new_pd.second + pde_index) = new_pde;
@ -135,7 +137,6 @@ namespace nasa
new_pte.rw = true; new_pte.rw = true;
new_pte.pfn = reinterpret_cast<std::uintptr_t>(addr) >> 12; new_pte.pfn = reinterpret_cast<std::uintptr_t>(addr) >> 12;
new_pte.user_supervisor = true; new_pte.user_supervisor = true;
new_pte.accessed = true;
// set pte entry // set pte entry
*reinterpret_cast<pte*>(new_pt.second + pte_index) = new_pte; *reinterpret_cast<pte*>(new_pt.second + pte_index) = new_pte;
@ -145,7 +146,7 @@ namespace nasa
return get_page(); 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 // builds a new address given the state of all table indexes
virt_addr_t new_addr; virt_addr_t new_addr;
@ -163,25 +164,23 @@ namespace nasa
} }
__except (EXCEPTION_EXECUTE_HANDLER) __except (EXCEPTION_EXECUTE_HANDLER)
{ {
// loop until the TLB has flushed... // try again to access the page...
while (true) __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)
{ {
__try
{
*(std::uint8_t*)new_addr.value = *(std::uint8_t*)new_addr.value;
return new_addr.value;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{}
while (!SwitchToThread()) while (!SwitchToThread())
continue; continue;
} }
} }
return {}; return new_addr.value;
} }
void* mem_ctx::get_dirbase(vdm::vdm_ctx& v_ctx, DWORD pid) void* ptm_ctx::get_dirbase(vdm::vdm_ctx& v_ctx, DWORD pid)
{ {
const auto peproc = const auto peproc =
reinterpret_cast<std::uint64_t>( reinterpret_cast<std::uint64_t>(
@ -191,7 +190,7 @@ namespace nasa
v_ctx.rkm<pte>(peproc + 0x28).pfn << 12); v_ctx.rkm<pte>(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) if (!addr || !dirbase)
return false; return false;
@ -233,7 +232,7 @@ namespace nasa
return true; return true;
} }
auto mem_ctx::get_pte(void* addr, bool use_hyperspace) -> std::pair<ppte, pte> auto ptm_ctx::get_pte(void* addr, bool use_hyperspace) -> std::pair<ppte, pte>
{ {
if (!dirbase || !addr) if (!dirbase || !addr)
return { {}, {} }; return { {}, {} };
@ -245,84 +244,94 @@ namespace nasa
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) if (!dirbase || !addr)
return; return false;
if (use_hyperspace) if (use_hyperspace)
v_ctx->wkm(v_ctx->get_virtual(reinterpret_cast<std::uintptr_t>(addr)), pte); return v_ctx->wkm(
else v_ctx->get_virtual(
write_phys(addr, pte); reinterpret_cast<std::uintptr_t>(addr)), pte);
return write_phys(addr, pte);
} }
auto mem_ctx::get_pde(void* addr, bool use_hyperspace) -> std::pair<ppde, pde> auto ptm_ctx::get_pde(void* addr, bool use_hyperspace) -> std::pair<ppde, pde>
{ {
if (!dirbase || !addr) if (!dirbase || !addr)
return {}; return { {}, {} };
pt_entries entries; pt_entries entries;
if ((use_hyperspace ? hyperspace_entries(entries, addr) : (bool)virt_to_phys(entries, addr))) if ((use_hyperspace ? hyperspace_entries(entries, addr) : (bool)virt_to_phys(entries, addr)))
return { entries.pd.first, entries.pd.second }; 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 (!dirbase || !addr) if (!dirbase || !addr)
return; return false;
if (use_hyperspace) if (use_hyperspace)
v_ctx->wkm(v_ctx->get_virtual(reinterpret_cast<std::uintptr_t>(addr)), pde); return v_ctx->wkm(
else v_ctx->get_virtual(
write_phys(addr, pde); reinterpret_cast<std::uintptr_t>(addr)), pde);
return write_phys(addr, pde);
} }
auto mem_ctx::get_pdpte(void* addr, bool use_hyperspace) -> std::pair<ppdpte, pdpte> auto ptm_ctx::get_pdpte(void* addr, bool use_hyperspace) -> std::pair<ppdpte, pdpte>
{ {
if (!dirbase || !addr) if (!dirbase || !addr)
return {}; return { {}, {} };
pt_entries entries; pt_entries entries;
if ((use_hyperspace ? hyperspace_entries(entries, addr) : (bool)virt_to_phys(entries, addr))) if ((use_hyperspace ? hyperspace_entries(entries, addr) : (bool)virt_to_phys(entries, addr)))
return { entries.pdpt.first, entries.pdpt.second }; 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 (!dirbase || !addr) if (!dirbase || !addr)
return; return false;
if (use_hyperspace) if (use_hyperspace)
v_ctx->wkm(v_ctx->get_virtual(reinterpret_cast<std::uintptr_t>(addr)), pdpte); return v_ctx->wkm(
else v_ctx->get_virtual(
write_phys(addr, pdpte); reinterpret_cast<std::uintptr_t>(addr)), pdpte);
return write_phys(addr, pdpte);
} }
auto mem_ctx::get_pml4e(void* addr, bool use_hyperspace) -> std::pair<ppml4e, pml4e> auto ptm_ctx::get_pml4e(void* addr, bool use_hyperspace) -> std::pair<ppml4e, pml4e>
{ {
if (!dirbase || !addr) if (!dirbase || !addr)
return {}; return { {}, {} };
pt_entries entries; pt_entries entries;
if ((use_hyperspace ? hyperspace_entries(entries, addr) : (bool)virt_to_phys(entries, addr))) if ((use_hyperspace ? hyperspace_entries(entries, addr) : (bool)virt_to_phys(entries, addr)))
return { entries.pml4.first, entries.pml4.second }; 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 (!dirbase || !addr) if (!dirbase || !addr)
return; return false;
if (use_hyperspace) if (use_hyperspace)
v_ctx->wkm(v_ctx->get_virtual(reinterpret_cast<std::uintptr_t>(addr)), pml4e); return v_ctx->wkm(
else v_ctx->get_virtual(
write_phys(addr, pml4e); reinterpret_cast<std::uintptr_t>(addr)), pml4e);
return write_phys(addr, pml4e);
} }
auto mem_ctx::read_virtual(void* buffer, void* addr, std::size_t size) -> std::pair<void*, void*> auto ptm_ctx::read_virtual(void* buffer, void* addr, std::size_t size) -> std::pair<void*, void*>
{ {
if (!buffer || !addr || !size || !dirbase) if (!buffer || !addr || !size || !dirbase)
return {}; return {};
@ -364,7 +373,7 @@ namespace nasa
} }
} }
auto mem_ctx::write_virtual(void* buffer, void* addr, std::size_t size) -> std::pair<void*, void*> auto ptm_ctx::write_virtual(void* buffer, void* addr, std::size_t size) -> std::pair<void*, void*>
{ {
if (!buffer || !addr || !size || !dirbase) if (!buffer || !addr || !size || !dirbase)
return {}; return {};
@ -406,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) if (!buffer || !addr || !size)
return false; return false;
@ -423,7 +432,7 @@ namespace nasa
return true; 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) if (!buffer || !addr || !size)
return false; return false;
@ -440,7 +449,7 @@ namespace nasa
return true; 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 || !dirbase) if (!addr || !dirbase)
return {}; return {};

@ -2,25 +2,25 @@
#include "../util/nt.hpp" #include "../util/nt.hpp"
#include "../vdm_ctx/vdm_ctx.hpp" #include "../vdm_ctx/vdm_ctx.hpp"
namespace nasa namespace ptm
{ {
class mem_ctx class ptm_ctx
{ {
public: public:
explicit mem_ctx(vdm::vdm_ctx* v_ctx, std::uint32_t pid = GetCurrentProcessId()); explicit ptm_ctx(vdm::vdm_ctx* v_ctx, std::uint32_t pid = GetCurrentProcessId());
~mem_ctx(); ~ptm_ctx();
auto get_pte(void* addr, bool use_hyperspace = false) -> std::pair<ppte, pte>; auto get_pte(void* addr, bool use_hyperspace = false) -> std::pair<ppte, pte>;
void set_pte(void* addr, const ::pte& pte, bool use_hyperspace = false); bool set_pte(void* addr, const ::pte& pte, bool use_hyperspace = false);
auto get_pde(void* addr, bool use_hyperspace = false) -> std::pair<ppde, pde>; auto get_pde(void* addr, bool use_hyperspace = false) -> std::pair<ppde, pde>;
void set_pde(void* addr, const ::pde& pde, bool use_hyperspace = false); bool set_pde(void* addr, const ::pde& pde, bool use_hyperspace = false);
auto get_pdpte(void* addr, bool use_hyperspace = false) -> std::pair<ppdpte, pdpte>; auto get_pdpte(void* addr, bool use_hyperspace = false) -> std::pair<ppdpte, pdpte>;
void set_pdpte(void* addr, const ::pdpte& pdpte, bool use_hyperspace = false); bool set_pdpte(void* addr, const ::pdpte& pdpte, bool use_hyperspace = false);
auto get_pml4e(void* addr, bool use_hyperspace = false) -> std::pair<ppml4e, pml4e>; auto get_pml4e(void* addr, bool use_hyperspace = false) -> std::pair<ppml4e, pml4e>;
void set_pml4e(void* addr, const ::pml4e& pml4e, bool use_hyperspace = false); bool set_pml4e(void* addr, const ::pml4e& pml4e, bool use_hyperspace = false);
static void* get_dirbase(vdm::vdm_ctx& v_ctx, DWORD pid); static void* get_dirbase(vdm::vdm_ctx& v_ctx, DWORD pid);
bool read_phys(void* buffer, void* addr, std::size_t size); bool read_phys(void* buffer, void* addr, std::size_t size);
@ -35,9 +35,9 @@ namespace nasa
} }
template <class T> template <class T>
__forceinline void write_phys(void* addr, const T& data) __forceinline bool write_phys(void* addr, const T& data)
{ {
write_phys((void*)&data, addr, sizeof(T)); return write_phys((void*)&data, addr, sizeof(T));
} }
auto read_virtual(void* buffer, void* addr, std::size_t size) -> std::pair<void*, void*>; auto read_virtual(void* buffer, void* addr, std::size_t size) -> std::pair<void*, void*>;

@ -47,21 +47,21 @@ namespace vdm
this->write_phys = write_func; this->write_phys = write_func;
} }
void vdm_ctx::rkm(void* dst, void* src, std::size_t size) bool vdm_ctx::rkm(void* dst, void* src, std::size_t size)
{ {
static const auto ntoskrnl_memcpy = static const auto ntoskrnl_memcpy =
util::get_kmodule_export("ntoskrnl.exe", "memcpy"); util::get_kmodule_export("ntoskrnl.exe", "memcpy");
this->syscall<decltype(&memcpy)>( return this->syscall<decltype(&memcpy)>(
ntoskrnl_memcpy, dst, src, size); ntoskrnl_memcpy, dst, src, size);
} }
void vdm_ctx::wkm(void* dst, void* src, std::size_t size) bool vdm_ctx::wkm(void* dst, void* src, std::size_t size)
{ {
static const auto ntoskrnl_memcpy = static const auto ntoskrnl_memcpy =
util::get_kmodule_export("ntoskrnl.exe", "memcpy"); util::get_kmodule_export("ntoskrnl.exe", "memcpy");
this->syscall<decltype(&memcpy)>( return this->syscall<decltype(&memcpy)>(
ntoskrnl_memcpy, dst, src, size); ntoskrnl_memcpy, dst, src, size);
} }

@ -27,8 +27,8 @@ namespace vdm
explicit vdm_ctx(read_phys_t& read_func, write_phys_t& 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_read(read_phys_t& read_func);
void set_write(write_phys_t& write_func); void set_write(write_phys_t& write_func);
void rkm(void* dst, void* src, std::size_t size); bool rkm(void* dst, void* src, std::size_t size);
void wkm(void* dst, void* src, std::size_t size); bool wkm(void* dst, void* src, std::size_t size);
template <class T, class ... Ts> template <class T, class ... Ts>
__forceinline std::invoke_result_t<T, Ts...> syscall(void* addr, Ts ... args) const __forceinline std::invoke_result_t<T, Ts...> syscall(void* addr, Ts ... args) const
@ -68,14 +68,15 @@ namespace vdm
__forceinline auto rkm(std::uintptr_t addr) -> T __forceinline auto rkm(std::uintptr_t addr) -> T
{ {
T buffer; T buffer;
rkm((void*)&buffer, (void*)addr, sizeof T); if (!rkm((void*)&buffer, (void*)addr, sizeof T))
return {};
return buffer; return buffer;
} }
template <class T> template <class T>
__forceinline void wkm(std::uintptr_t addr, const T& value) __forceinline bool wkm(std::uintptr_t addr, const T& value)
{ {
wkm((void*)addr, (void*)&value, sizeof T); return wkm((void*)addr, (void*)&value, sizeof T);
} }
__forceinline auto get_peprocess(std::uint32_t pid) -> PEPROCESS __forceinline auto get_peprocess(std::uint32_t pid) -> PEPROCESS
@ -108,7 +109,6 @@ namespace vdm
private: private:
void locate_syscall(std::uintptr_t begin, std::uintptr_t end) const; void locate_syscall(std::uintptr_t begin, std::uintptr_t end) const;
bool valid_syscall(void* syscall_addr) const; bool valid_syscall(void* syscall_addr) const;
read_phys_t read_phys; read_phys_t read_phys;
write_phys_t write_phys; write_phys_t write_phys;
}; };

Loading…
Cancel
Save