diff --git a/PTM/PTM.vcxproj b/PTM/PTM.vcxproj
index 1c69570..f1de913 100644
--- a/PTM/PTM.vcxproj
+++ b/PTM/PTM.vcxproj
@@ -143,12 +143,12 @@
-
+
-
+
diff --git a/PTM/PTM.vcxproj.filters b/PTM/PTM.vcxproj.filters
index 9d3ae23..21b4e21 100644
--- a/PTM/PTM.vcxproj.filters
+++ b/PTM/PTM.vcxproj.filters
@@ -26,10 +26,10 @@
Source Files
-
+
Source Files
-
+
Source Files
@@ -46,9 +46,6 @@
Header Files\vdm
-
- Header Files
-
Header Files\util
@@ -58,6 +55,9 @@
Header Files
+
+ Header Files
+
diff --git a/PTM/main.cpp b/PTM/main.cpp
index 21b82f8..550eb7a 100644
--- a/PTM/main.cpp
+++ b/PTM/main.cpp
@@ -1,4 +1,4 @@
-#include "mem_ctx/mem_ctx.hpp"
+#include "ptm_ctx/ptm_ctx.hpp"
#include "set_mgr/set_mgr.hpp"
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);
- nasa::mem_ctx my_proc(&vdm);
+ ptm::ptm_ctx my_proc(&vdm);
const auto set_mgr_pethread =
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...
vdm = vdm::vdm_ctx(_read_phys, _write_phys);
-
const auto current_pml4 =
reinterpret_cast(
my_proc.set_page(my_proc.dirbase));
diff --git a/PTM/mem_ctx/mem_ctx.cpp b/PTM/ptm_ctx/ptm_ctx.cpp
similarity index 81%
rename from PTM/mem_ctx/mem_ctx.cpp
rename to PTM/ptm_ctx/ptm_ctx.cpp
index 162fde2..bb87228 100644
--- a/PTM/mem_ctx/mem_ctx.cpp
+++ b/PTM/ptm_ctx/ptm_ctx.cpp
@@ -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),
dirbase(get_dirbase(*v_ctx, pid)),
@@ -14,8 +14,13 @@ namespace nasa
get_dirbase(*v_ctx, GetCurrentProcessId())));
for (auto idx = 100u; idx > 0u; --idx)
+ {
if (!v_ctx->rkm(current_pml4 + (idx * sizeof pml4e)).present)
+ {
this->pml4e_index = idx;
+ break;
+ }
+ }
// allocate a pdpt
this->new_pdpt.second =
@@ -84,30 +89,29 @@ namespace nasa
new_pt_entries.pt.second.pfn << 12);
}
- mem_ctx::~mem_ctx()
+ ptm_ctx::~ptm_ctx()
{
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 };
@@ -115,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;
@@ -125,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;
@@ -135,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;
@@ -145,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;
@@ -163,25 +164,23 @@ namespace nasa
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
- // loop until the TLB has flushed...
- while (true)
+ // 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)
{
- __try
- {
- *(std::uint8_t*)new_addr.value = *(std::uint8_t*)new_addr.value;
- return new_addr.value;
- }
- __except(EXCEPTION_EXECUTE_HANDLER)
- {}
-
while (!SwitchToThread())
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 =
reinterpret_cast(
@@ -191,7 +190,7 @@ namespace nasa
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;
@@ -233,7 +232,7 @@ namespace nasa
return true;
}
- auto mem_ctx::get_pte(void* addr, bool use_hyperspace) -> std::pair
+ auto ptm_ctx::get_pte(void* addr, bool use_hyperspace) -> std::pair
{
if (!dirbase || !addr)
return { {}, {} };
@@ -245,84 +244,94 @@ namespace nasa
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);
}
- auto mem_ctx::get_pde(void* addr, bool use_hyperspace) -> std::pair
+ 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 (!dirbase || !addr)
- return;
+ 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);
}
- auto mem_ctx::get_pdpte(void* addr, bool use_hyperspace) -> std::pair
+ 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 (!dirbase || !addr)
- return;
+ 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);
}
- auto mem_ctx::get_pml4e(void* addr, bool use_hyperspace) -> std::pair
+ auto ptm_ctx::get_pml4e(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.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)
- return;
+ 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);
}
- auto mem_ctx::read_virtual(void* buffer, void* addr, std::size_t size) -> std::pair
+ auto ptm_ctx::read_virtual(void* buffer, void* addr, std::size_t size) -> std::pair
{
if (!buffer || !addr || !size || !dirbase)
return {};
@@ -364,7 +373,7 @@ namespace nasa
}
}
- auto mem_ctx::write_virtual(void* buffer, void* addr, std::size_t size) -> std::pair
+ auto ptm_ctx::write_virtual(void* buffer, void* addr, std::size_t size) -> std::pair
{
if (!buffer || !addr || !size || !dirbase)
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)
return false;
@@ -423,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;
@@ -440,7 +449,7 @@ 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 || !dirbase)
return {};
diff --git a/PTM/mem_ctx/mem_ctx.hpp b/PTM/ptm_ctx/ptm_ctx.hpp
similarity index 79%
rename from PTM/mem_ctx/mem_ctx.hpp
rename to PTM/ptm_ctx/ptm_ctx.hpp
index 602224c..2ac89e8 100644
--- a/PTM/mem_ctx/mem_ctx.hpp
+++ b/PTM/ptm_ctx/ptm_ctx.hpp
@@ -2,25 +2,25 @@
#include "../util/nt.hpp"
#include "../vdm_ctx/vdm_ctx.hpp"
-namespace nasa
+namespace ptm
{
- class mem_ctx
+ class ptm_ctx
{
public:
- explicit mem_ctx(vdm::vdm_ctx* v_ctx, std::uint32_t pid = GetCurrentProcessId());
- ~mem_ctx();
+ 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;
- 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;
- 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;
- 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;
- 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);
bool read_phys(void* buffer, void* addr, std::size_t size);
@@ -35,9 +35,9 @@ namespace nasa
}
template
- __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;
diff --git a/PTM/vdm_ctx/vdm_ctx.cpp b/PTM/vdm_ctx/vdm_ctx.cpp
index 8d59289..9061160 100644
--- a/PTM/vdm_ctx/vdm_ctx.cpp
+++ b/PTM/vdm_ctx/vdm_ctx.cpp
@@ -47,21 +47,21 @@ namespace vdm
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 =
util::get_kmodule_export("ntoskrnl.exe", "memcpy");
- this->syscall(
+ return this->syscall(
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 =
util::get_kmodule_export("ntoskrnl.exe", "memcpy");
- this->syscall(
+ return this->syscall(
ntoskrnl_memcpy, dst, src, size);
}
diff --git a/PTM/vdm_ctx/vdm_ctx.hpp b/PTM/vdm_ctx/vdm_ctx.hpp
index 428aa16..551ad22 100644
--- a/PTM/vdm_ctx/vdm_ctx.hpp
+++ b/PTM/vdm_ctx/vdm_ctx.hpp
@@ -27,8 +27,8 @@ namespace vdm
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);
- void rkm(void* dst, void* src, std::size_t size);
- void wkm(void* dst, void* src, std::size_t size);
+ bool rkm(void* dst, void* src, std::size_t size);
+ bool wkm(void* dst, void* src, std::size_t size);
template
__forceinline std::invoke_result_t syscall(void* addr, Ts ... args) const
@@ -68,14 +68,15 @@ namespace vdm
__forceinline auto rkm(std::uintptr_t addr) -> T
{
T buffer;
- rkm((void*)&buffer, (void*)addr, sizeof T);
+ if (!rkm((void*)&buffer, (void*)addr, sizeof T))
+ return {};
return buffer;
}
template
- __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
@@ -108,7 +109,6 @@ namespace vdm
private:
void locate_syscall(std::uintptr_t begin, std::uintptr_t end) const;
bool valid_syscall(void* syscall_addr) const;
-
read_phys_t read_phys;
write_phys_t write_phys;
};