diff --git a/PSKDM/PSKDM.vcxproj b/PSKDM/PSKDM.vcxproj
index 3e5dc91..84e6de3 100644
--- a/PSKDM/PSKDM.vcxproj
+++ b/PSKDM/PSKDM.vcxproj
@@ -217,7 +217,7 @@
-
+
diff --git a/PSKDM/PSKDM.vcxproj.filters b/PSKDM/PSKDM.vcxproj.filters
index 818bb07..44dc5b9 100644
--- a/PSKDM/PSKDM.vcxproj.filters
+++ b/PSKDM/PSKDM.vcxproj.filters
@@ -67,10 +67,10 @@
Header Files
-
+
Header Files
-
+
Header Files
diff --git a/PSKDM/map_driver.cpp b/PSKDM/map_driver.cpp
index 8d4388a..2685c00 100644
--- a/PSKDM/map_driver.cpp
+++ b/PSKDM/map_driver.cpp
@@ -1,6 +1,6 @@
#include "map_driver.hpp"
#include "mapper_ctx/mapper_ctx.hpp"
-#include "vdm_ctx/vdm_ctx.hpp"
+#include "vdm_ctx/vdm_ctx.h"
#include "vdm/vdm.hpp"
#include "set_mgr/set_mgr.hpp"
@@ -22,30 +22,13 @@ namespace mapper
if (!runtime_broker_pid)
return { mapper_error::failed_to_create_proc, nullptr };
- vdm::read_phys_t _read_phys =
- [&](void* addr, void* buffer, std::size_t size) -> bool
- {
- return vdm::read_phys(addr, buffer, size);
- };
-
- vdm::write_phys_t _write_phys =
- [&](void* addr, void* buffer, std::size_t size) -> bool
- {
- return vdm::write_phys(addr, buffer, size);
- };
-
- vdm::vdm_ctx v_ctx(_read_phys, _write_phys);
- nasa::mem_ctx my_proc(&v_ctx, GetCurrentProcessId());
- nasa::mem_ctx runtime_broker(&v_ctx, runtime_broker_pid);
- nasa::mapper_ctx mapper(&my_proc, &runtime_broker);
-
- const auto result =
- set_mgr::stop_setmgr(v_ctx,
- set_mgr::get_setmgr_pethread(v_ctx));
-
- if (result != STATUS_SUCCESS)
- return { mapper_error::set_mgr_failure, nullptr };
+ vdm::vdm_ctx v_ctx;
+ nasa::mem_ctx my_proc(v_ctx, GetCurrentProcessId());
+ nasa::mem_ctx runtime_broker(v_ctx, runtime_broker_pid);
+ nasa::mapper_ctx mapper(my_proc, runtime_broker);
+ // shoot the tires off the set manager thread.....
+ set_mgr::stop_setmgr(v_ctx, set_mgr::get_setmgr_pethread(v_ctx));
const auto [drv_base, drv_entry] = mapper.map(drv_buffer);
if (!drv_base || !drv_entry)
return { mapper_error::init_failed, nullptr };
diff --git a/PSKDM/map_driver.hpp b/PSKDM/map_driver.hpp
index 5563f91..3291a01 100644
--- a/PSKDM/map_driver.hpp
+++ b/PSKDM/map_driver.hpp
@@ -7,14 +7,13 @@ namespace mapper
{
enum class mapper_error
{
- error_success, // everything is good!
- image_invalid, // the driver your trying to map is invalid (are you importing things that arent in ntoskrnl?)
- load_error, // unable to load signed driver into the kernel (are you running as admin?)
- unload_error, // unable to unload signed driver from kernel (are all handles to this driver closes?)
- piddb_fail, // piddb cache clearing failed... (are you using this code below windows 10?)
- init_failed, // setting up library dependancies failed!
- failed_to_create_proc, // was unable to create a new process to inject driver into! (RuntimeBroker.exe)
- set_mgr_failure // unable to stop working set manager thread... this thread can cause issues with PTM...
+ error_success = 0x000, // everything is good!
+ image_invalid = 0x111, // the driver your trying to map is invalid (are you importing things that arent in ntoskrnl?)
+ load_error = 0x222, // unable to load signed driver into the kernel (are you running as admin?)
+ unload_error = 0x333, // unable to unload signed driver from kernel (are all handles to this driver closes?)
+ piddb_fail = 0x444, // piddb cache clearing failed... (are you using this code below windows 10?)
+ init_failed = 0x555, // setting up library dependancies failed!
+ failed_to_create_proc = 0x777 // was unable to create a new process to inject driver into! (RuntimeBroker.exe)
};
///
@@ -24,5 +23,5 @@ namespace mapper
/// size of the driver buffer
/// data to be sent to the entry point of the driver...
/// status of the driver being mapped, and base address of the driver...
- auto map_driver(std::uint8_t* drv_image, std::size_t image_size, void** entry_data)->std::pair;
+ std::pair map_driver(std::uint8_t* drv_image, std::size_t image_size, void** entry_data);
}
\ No newline at end of file
diff --git a/PSKDM/mapper_ctx/mapper_ctx.cpp b/PSKDM/mapper_ctx/mapper_ctx.cpp
index d9c12bc..829c204 100644
--- a/PSKDM/mapper_ctx/mapper_ctx.cpp
+++ b/PSKDM/mapper_ctx/mapper_ctx.cpp
@@ -4,8 +4,8 @@ namespace nasa
{
mapper_ctx::mapper_ctx
(
- nasa::mem_ctx* map_into,
- nasa::mem_ctx* map_from
+ nasa::mem_ctx& map_into,
+ nasa::mem_ctx& map_from
)
:
map_into(map_into),
@@ -14,7 +14,7 @@ namespace nasa
{
const auto map_into_pml4 =
reinterpret_cast(
- map_into->set_page(map_into->dirbase));
+ map_into.set_page(map_into.get_dirbase()));
// look for an empty pml4e...
for (auto idx = 0u; idx < 256; ++idx)
@@ -30,20 +30,18 @@ namespace nasa
auto mapper_ctx::map(std::vector& raw_image) -> std::pair
{
const auto [drv_alloc, drv_entry_addr] = allocate_driver(raw_image);
- auto [drv_ppml4e, drv_pml4e] = map_from->get_pml4e(drv_alloc);
+ auto [drv_ppml4e, drv_pml4e] = map_from.get_pml4e(drv_alloc);
+ while (!SwitchToThread());
make_kernel_access(drv_alloc);
- while (!map_from->set_pml4e(drv_ppml4e, pml4e{ NULL }))
- continue;
+ map_from.set_pml4e(drv_ppml4e, pml4e{ NULL });
+ while (!SwitchToThread());
drv_pml4e.nx = false;
drv_pml4e.user_supervisor = false;
- // ensure we insert the pml4e...
- while (!map_into->write_phys(
- reinterpret_cast(
- map_into->dirbase) + this->pml4_idx, drv_pml4e))
- continue;
+ map_into.write_phys(reinterpret_cast(
+ map_into.get_dirbase()) + this->pml4_idx, drv_pml4e);
virt_addr_t new_addr = { reinterpret_cast(drv_alloc) };
new_addr.pml4_index = this->pml4_idx;
@@ -52,7 +50,7 @@ namespace nasa
void mapper_ctx::call_entry(void* drv_entry, void** hook_handler) const
{
- map_into->v_ctx->syscall(drv_entry, hook_handler);
+ map_into.v_ctx->syscall(drv_entry, hook_handler);
}
auto mapper_ctx::allocate_driver(std::vector& raw_image) -> std::pair
@@ -62,11 +60,11 @@ namespace nasa
OpenProcess(
PROCESS_ALL_ACCESS,
FALSE,
- map_from->pid
+ map_from.get_pid()
);
if (!process_handle)
- return { {}, {} };
+ return {};
drv_image.fix_imports([&](const char* module_name, const char* export_name)
{
@@ -89,7 +87,7 @@ namespace nasa
));
if (!drv_alloc_base)
- return { {}, {} };
+ return {};
virt_addr_t new_addr = { reinterpret_cast(drv_alloc_base) };
new_addr.pml4_index = this->pml4_idx;
@@ -112,23 +110,15 @@ namespace nasa
return
{
reinterpret_cast(drv_alloc_base),
- reinterpret_cast(drv_image.entry_point() +
- reinterpret_cast(new_addr.value))
+ reinterpret_cast(drv_image.entry_point() + reinterpret_cast(new_addr.value))
};
}
void mapper_ctx::make_kernel_access(void* drv_base)
{
- const auto [ppdpte, pdpte] =
- map_from->get_pdpte(drv_base);
-
- auto ppdpte_phys =
- reinterpret_cast((
- reinterpret_cast(ppdpte) >> 12) << 12); // 0 the last 12 bits...
-
- auto pdpt_mapping =
- reinterpret_cast<::ppdpte>(
- map_from->set_page(ppdpte_phys));
+ const auto [ppdpte, pdpte] = map_from.get_pdpte(drv_base);
+ auto ppdpte_phys = reinterpret_cast((reinterpret_cast(ppdpte) >> 12) << 12); // 0 the last 12 bits...
+ auto pdpt_mapping = reinterpret_cast<::ppdpte>(map_from.set_page(ppdpte_phys));
// set pdptes to CPL0 access only and executable...
for (auto pdpt_idx = 0u; pdpt_idx < 512; ++pdpt_idx)
@@ -139,7 +129,7 @@ namespace nasa
pdpt_mapping[pdpt_idx].nx = false;
auto pd_mapping = reinterpret_cast(
- map_from->set_page(reinterpret_cast(
+ map_from.set_page(reinterpret_cast(
pdpt_mapping[pdpt_idx].pfn << 12)));
// set pdes to CPL0 access only and executable...
@@ -151,7 +141,7 @@ namespace nasa
pd_mapping[pd_idx].nx = false;
auto pt_mapping = reinterpret_cast(
- map_from->set_page(reinterpret_cast(
+ map_from.set_page(reinterpret_cast(
pd_mapping[pd_idx].pfn << 12)));
// set ptes to CPL0 access only and executable...
@@ -166,14 +156,14 @@ namespace nasa
// set page back to pd...
pd_mapping = reinterpret_cast(
- map_from->set_page(reinterpret_cast(
+ map_from.set_page(reinterpret_cast(
pdpt_mapping[pdpt_idx].pfn << 12)));
}
}
// set page back to pdpt...
pdpt_mapping = reinterpret_cast<::ppdpte>(
- map_from->set_page(ppdpte_phys));
+ map_from.set_page(ppdpte_phys));
}
}
}
diff --git a/PSKDM/mapper_ctx/mapper_ctx.hpp b/PSKDM/mapper_ctx/mapper_ctx.hpp
index 4f7f2ec..9ed4800 100644
--- a/PSKDM/mapper_ctx/mapper_ctx.hpp
+++ b/PSKDM/mapper_ctx/mapper_ctx.hpp
@@ -6,14 +6,14 @@ namespace nasa
class mapper_ctx
{
public:
- explicit mapper_ctx(nasa::mem_ctx* map_into, nasa::mem_ctx* map_from);
- auto map(std::vector& raw_image) -> std::pair;
+ explicit mapper_ctx(nasa::mem_ctx& map_into, nasa::mem_ctx& map_from);
+ auto map(std::vector& raw_image)->std::pair;
void call_entry(void* drv_entry, void** hook_handler) const;
private:
std::uint16_t pml4_idx;
- auto allocate_driver(std::vector& raw_image) -> std::pair;
+ auto allocate_driver(std::vector& raw_image)->std::pair;
void make_kernel_access(void* drv_base);
- nasa::mem_ctx* map_into, *map_from;
+ nasa::mem_ctx map_into, map_from;
};
}
\ No newline at end of file
diff --git a/PSKDM/mem_ctx/mem_ctx.cpp b/PSKDM/mem_ctx/mem_ctx.cpp
index 1e487f7..12ebd48 100644
--- a/PSKDM/mem_ctx/mem_ctx.cpp
+++ b/PSKDM/mem_ctx/mem_ctx.cpp
@@ -2,25 +2,20 @@
namespace nasa
{
- mem_ctx::mem_ctx(vdm::vdm_ctx* v_ctx, std::uint32_t pid)
+ mem_ctx::mem_ctx(vdm::vdm_ctx& v_ctx, DWORD pid)
:
- v_ctx(v_ctx),
- 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)).present)
- {
+ if (!v_ctx.rkm(current_pml4 + (idx * sizeof pml4e)).value)
this->pml4e_index = idx;
- break;
- }
- }
// allocate a pdpt
this->new_pdpt.second =
@@ -36,17 +31,13 @@ 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>(this->dirbase) +
- this->pml4e_index, new_pdpt_entries.pml4.second, true);
+ set_pml4e(reinterpret_cast<::ppml4e>(get_dirbase()) + this->pml4e_index, new_pdpt_entries.pml4.second, true);
// make a new pd
this->new_pd.second =
@@ -63,10 +54,7 @@ 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 =
@@ -83,42 +71,42 @@ namespace nasa
// 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()
{
- const auto pml4 =
- reinterpret_cast(
- set_page(dirbase))[pml4e_index] = pml4e{ NULL };
+ set_pml4e(reinterpret_cast<::ppml4e>(get_dirbase()) + this->pml4e_index, pml4e{NULL});
+ while (!SwitchToThread());
}
void* mem_ctx::set_page(void* addr)
{
- ++pte_index;
- if (pte_index > 511)
+ // table entry change.
{
- ++pde_index;
- pte_index = 0;
- }
+ ++pte_index;
+ if (pte_index >= 511)
+ {
+ ++pde_index;
+ pte_index = 0;
+ }
- if (pde_index > 511)
- {
- ++pdpte_index;
- pde_index = 0;
- }
+ if (pde_index >= 511)
+ {
+ ++pdpte_index;
+ pde_index = 0;
+ }
- if (pdpte_index > 511)
- pdpte_index = 0;
+ if (pdpte_index >= 511)
+ pdpte_index = 0;
+ }
pdpte new_pdpte = { NULL };
new_pdpte.present = true;
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;
@@ -128,6 +116,7 @@ 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;
@@ -137,6 +126,7 @@ 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;
@@ -155,39 +145,18 @@ 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, DWORD pid)
{
const auto peproc =
- reinterpret_cast(
- v_ctx.get_peprocess(pid));
+ reinterpret_cast(v_ctx.get_peprocess(pid));
- return reinterpret_cast(
- v_ctx.rkm(peproc + 0x28).pfn << 12);
+ const auto dirbase =
+ v_ctx.rkm(peproc + 0x28);
+
+ return reinterpret_cast(dirbase.pfn << 12);
}
bool mem_ctx::hyperspace_entries(pt_entries& entries, void* addr)
@@ -232,106 +201,95 @@ namespace nasa
return true;
}
- auto mem_ctx::get_pte(void* addr, bool use_hyperspace) -> std::pair
+ std::pair mem_ctx::get_pte(void* addr, bool use_hyperspace)
{
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 {};
}
- bool mem_ctx::set_pte(void* addr, const ::pte& pte, bool use_hyperspace)
+ void mem_ctx::set_pte(void* addr, const ::pte& pte, bool use_hyperspace)
{
if (!dirbase || !addr)
- return false;
+ return;
if (use_hyperspace)
- return v_ctx->wkm(
- v_ctx->get_virtual(
- reinterpret_cast(addr)), pte);
-
- return write_phys(addr, pte);
+ v_ctx->wkm(v_ctx->get_virtual(reinterpret_cast(addr)), pte);
+ else
+ write_phys(addr, pte);
}
- auto mem_ctx::get_pde(void* addr, bool use_hyperspace) -> std::pair
+ std::pair mem_ctx::get_pde(void* addr, bool use_hyperspace)
{
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 {};
}
- bool mem_ctx::set_pde(void* addr, const ::pde& pde, bool use_hyperspace)
+ void mem_ctx::set_pde(void* addr, const ::pde& pde, bool use_hyperspace)
{
- if (!dirbase || !addr)
- return false;
+ if (!this->dirbase || !addr)
+ return;
if (use_hyperspace)
- return v_ctx->wkm(
- v_ctx->get_virtual(
- reinterpret_cast(addr)), pde);
-
- return write_phys(addr, pde);
+ v_ctx->wkm(v_ctx->get_virtual(reinterpret_cast(addr)), pde);
+ else
+ write_phys(addr, pde);
}
- auto mem_ctx::get_pdpte(void* addr, bool use_hyperspace) -> std::pair
+ std::pair mem_ctx::get_pdpte(void* addr, bool use_hyperspace)
{
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 {};
}
- bool mem_ctx::set_pdpte(void* addr, const ::pdpte& pdpte, bool use_hyperspace)
+ void mem_ctx::set_pdpte(void* addr, const ::pdpte& pdpte, bool use_hyperspace)
{
- if (!dirbase || !addr)
- return false;
+ if (!this->dirbase || !addr)
+ return;
if (use_hyperspace)
- return v_ctx->wkm(
- v_ctx->get_virtual(
- reinterpret_cast(addr)), pdpte);
-
- return write_phys(addr, pdpte);
+ v_ctx->wkm(v_ctx->get_virtual(reinterpret_cast(addr)), pdpte);
+ else
+ write_phys(addr, pdpte);
}
- auto mem_ctx::get_pml4e(void* addr, bool use_hyperspace) -> std::pair
+ std::pair mem_ctx::get_pml4e(void* addr, bool use_hyperspace)
{
- if (!dirbase || !addr)
- return { {}, {} };
+ if (!this->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 {};
}
- bool mem_ctx::set_pml4e(void* addr, const ::pml4e& pml4e, bool use_hyperspace)
+ void mem_ctx::set_pml4e(void* addr, const ::pml4e& pml4e, bool use_hyperspace)
{
- if (!dirbase || !addr)
- return false;
+ if (!this->dirbase || !addr)
+ return;
if (use_hyperspace)
- return v_ctx->wkm(
- v_ctx->get_virtual(
- reinterpret_cast(addr)), pml4e);
-
- return write_phys(addr, pml4e);
+ v_ctx->wkm(v_ctx->get_virtual(reinterpret_cast(addr)), pml4e);
+ else
+ write_phys(addr, pml4e);
}
- auto mem_ctx::read_virtual(void* buffer, void* addr, std::size_t size) -> std::pair
+ std::pair mem_ctx::read_virtual(void* buffer, void* addr, std::size_t size)
{
if (!buffer || !addr || !size || !dirbase)
return {};
@@ -373,7 +331,7 @@ namespace nasa
}
}
- auto mem_ctx::write_virtual(void* buffer, void* addr, std::size_t size) -> std::pair
+ std::pair mem_ctx::write_virtual(void* buffer, void* addr, std::size_t size)
{
if (!buffer || !addr || !size || !dirbase)
return {};
@@ -415,10 +373,10 @@ namespace nasa
}
}
- bool mem_ctx::read_phys(void* buffer, void* addr, std::size_t size)
+ void mem_ctx::read_phys(void* buffer, void* addr, std::size_t size)
{
if (!buffer || !addr || !size)
- return false;
+ return;
const auto temp_page = set_page(addr);
__try
@@ -426,16 +384,13 @@ namespace nasa
memcpy(buffer, temp_page, size);
}
__except (EXCEPTION_EXECUTE_HANDLER)
- {
- return false;
- }
- return true;
+ {}
}
- bool mem_ctx::write_phys(void* buffer, void* addr, std::size_t size)
+ void mem_ctx::write_phys(void* buffer, void* addr, std::size_t size)
{
if (!buffer || !addr || !size)
- return false;
+ return;
const auto temp_page = set_page(addr);
__try
@@ -443,15 +398,12 @@ namespace nasa
memcpy(temp_page, buffer, size);
}
__except (EXCEPTION_EXECUTE_HANDLER)
- {
- return false;
- }
- return true;
+ {}
}
void* mem_ctx::virt_to_phys(pt_entries& entries, void* addr)
{
- if (!addr || !dirbase)
+ if (!addr || !this->dirbase)
return {};
const virt_addr_t virt_addr{ addr };
@@ -495,4 +447,37 @@ namespace nasa
return reinterpret_cast((pte.pfn << 12) + virt_addr.offset);
}
+
+ unsigned mem_ctx::get_pid() const
+ {
+ return pid;
+ }
+
+ void* mem_ctx::get_dirbase() const
+ {
+ return 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/PSKDM/mem_ctx/mem_ctx.hpp b/PSKDM/mem_ctx/mem_ctx.hpp
index d0f555f..da40df2 100644
--- a/PSKDM/mem_ctx/mem_ctx.hpp
+++ b/PSKDM/mem_ctx/mem_ctx.hpp
@@ -1,33 +1,36 @@
#pragma once
#include "../util/nt.hpp"
-#include "../vdm_ctx/vdm_ctx.hpp"
+#include "../vdm_ctx/vdm_ctx.h"
namespace nasa
{
class mem_ctx
{
+ friend class mapper_ctx;
public:
- explicit mem_ctx(vdm::vdm_ctx* v_ctx, std::uint32_t pid = GetCurrentProcessId());
+ explicit mem_ctx(vdm::vdm_ctx& v_ctx, DWORD pid = GetCurrentProcessId());
~mem_ctx();
- auto get_pte(void* addr, bool use_hyperspace = false) -> std::pair;
- bool set_pte(void* addr, const ::pte& pte, bool use_hyperspace = false);
+ std::pair get_pte(void* addr, bool use_hyperspace = false);
+ void 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);
+ std::pair get_pde(void* addr, bool use_hyperspace = false);
+ void 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);
+ std::pair get_pdpte(void* addr, bool use_hyperspace = false);
+ void 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);
+ 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, DWORD pid);
- bool read_phys(void* buffer, void* addr, std::size_t size);
- bool write_phys(void* buffer, void* addr, std::size_t size);
+ void read_phys(void* buffer, void* addr, std::size_t size);
+ void write_phys(void* buffer, void* addr, std::size_t size);
template
- __forceinline T read_phys(void* addr)
+ T read_phys(void* addr)
{
T buffer;
read_phys((void*)&buffer, addr, sizeof(T));
@@ -35,13 +38,13 @@ namespace nasa
}
template
- __forceinline bool write_phys(void* addr, const T& data)
+ void write_phys(void* addr, const T& data)
{
- return write_phys((void*)&data, addr, sizeof(T));
+ 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;
+ 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)
@@ -58,15 +61,19 @@ namespace nasa
}
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 get_pid() const;
- unsigned pid;
+ 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;
- private:
std::uint16_t pml4e_index,
pdpte_index,
pde_index,
@@ -76,5 +83,6 @@ namespace nasa
std::pair new_pdpt;
std::pair new_pd;
std::pair new_pt;
+ unsigned pid;
};
}
\ No newline at end of file
diff --git a/PSKDM/set_mgr/set_mgr.hpp b/PSKDM/set_mgr/set_mgr.hpp
index 5b99746..beea970 100644
--- a/PSKDM/set_mgr/set_mgr.hpp
+++ b/PSKDM/set_mgr/set_mgr.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "../vdm_ctx/vdm_ctx.hpp"
+#include "../vdm_ctx/vdm_ctx.h"
using PETHREAD = PVOID;
using PsSuspendThread = NTSTATUS(*)(PETHREAD, PULONG);
diff --git a/PSKDM/vdm_ctx/vdm_ctx.cpp b/PSKDM/vdm_ctx/vdm_ctx.cpp
index 9061160..52581c6 100644
--- a/PSKDM/vdm_ctx/vdm_ctx.cpp
+++ b/PSKDM/vdm_ctx/vdm_ctx.cpp
@@ -1,13 +1,10 @@
-#include "vdm_ctx.hpp"
+#include "vdm_ctx.h"
namespace vdm
{
- vdm_ctx::vdm_ctx(read_phys_t& read_func, write_phys_t& write_func)
- :
- read_phys(read_func),
- write_phys(write_func)
+ vdm_ctx::vdm_ctx()
{
- // already found the syscall's physical page...
+ // if we already found the syscall's physical page...
if (vdm::syscall_address.load())
return;
@@ -37,37 +34,9 @@ namespace vdm
search_thread.join();
}
- void vdm_ctx::set_read(read_phys_t& read_func)
- {
- this->read_phys = read_func;
- }
-
- void vdm_ctx::set_write(write_phys_t& write_func)
- {
- this->write_phys = write_func;
- }
-
- bool vdm_ctx::rkm(void* dst, void* src, std::size_t size)
- {
- static const auto ntoskrnl_memcpy =
- util::get_kmodule_export("ntoskrnl.exe", "memcpy");
-
- return this->syscall(
- ntoskrnl_memcpy, dst, src, 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");
-
- return this->syscall(
- ntoskrnl_memcpy, dst, src, size);
- }
-
void vdm_ctx::locate_syscall(std::uintptr_t address, std::uintptr_t length) const
{
- const auto page_data =
+ const auto page_data =
reinterpret_cast(
VirtualAlloc(
nullptr,
@@ -80,7 +49,7 @@ namespace vdm
if (vdm::syscall_address.load())
break;
- if (!read_phys(reinterpret_cast(address + page), page_data, PAGE_4KB))
+ if (!vdm::read_phys(reinterpret_cast(address + page), page_data, PAGE_4KB))
continue;
// check the first 32 bytes of the syscall, if its the same, test that its the correct
@@ -91,6 +60,7 @@ namespace vdm
reinterpret_cast(
address + page + nt_page_offset));
}
+
VirtualFree(page_data, PAGE_4KB, MEM_DECOMMIT);
}
@@ -111,11 +81,11 @@ namespace vdm
std::uint8_t orig_bytes[sizeof shellcode];
// save original bytes and install shellcode...
- read_phys(syscall_addr, orig_bytes, sizeof orig_bytes);
- write_phys(syscall_addr, shellcode, sizeof shellcode);
+ vdm::read_phys(syscall_addr, orig_bytes, sizeof orig_bytes);
+ vdm::write_phys(syscall_addr, shellcode, sizeof shellcode);
auto result = reinterpret_cast(proc)();
- write_phys(syscall_addr, orig_bytes, sizeof orig_bytes);
+ vdm::write_phys(syscall_addr, orig_bytes, sizeof orig_bytes);
syscall_mutex.unlock();
return result == STATUS_SUCCESS;
}
diff --git a/PSKDM/vdm_ctx/vdm_ctx.hpp b/PSKDM/vdm_ctx/vdm_ctx.h
similarity index 70%
rename from PSKDM/vdm_ctx/vdm_ctx.hpp
rename to PSKDM/vdm_ctx/vdm_ctx.h
index 84282c7..7396687 100644
--- a/PSKDM/vdm_ctx/vdm_ctx.hpp
+++ b/PSKDM/vdm_ctx/vdm_ctx.h
@@ -5,35 +5,28 @@
#include
#include
#include
-#include
#include "../vdm/vdm.hpp"
namespace vdm
{
// change this to whatever you want :^)
constexpr std::pair syscall_hook = { "NtShutdownSystem", "ntdll.dll" };
+
inline std::atomic is_page_found = false;
inline std::atomic syscall_address = nullptr;
+
inline std::uint16_t nt_page_offset;
inline std::uint32_t nt_rva;
inline std::uint8_t* ntoskrnl;
- using read_phys_t = std::function;
- using write_phys_t = std::function;
-
class vdm_ctx
{
public:
- 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);
- bool rkm(void* dst, void* src, std::size_t size);
- bool wkm(void* dst, void* src, std::size_t size);
-
+ vdm_ctx();
template
__forceinline std::invoke_result_t syscall(void* addr, Ts ... args) const
{
- static const auto proc =
+ static const auto proc =
GetProcAddress(
LoadLibraryA(syscall_hook.second),
syscall_hook.first
@@ -53,12 +46,12 @@ namespace vdm
std::uint8_t orig_bytes[sizeof jmp_code];
*reinterpret_cast(jmp_code + 6) = addr;
- read_phys(vdm::syscall_address.load(), orig_bytes, sizeof orig_bytes);
+ vdm::read_phys(vdm::syscall_address.load(), orig_bytes, sizeof orig_bytes);
// execute hook...
- write_phys(vdm::syscall_address.load(), jmp_code, sizeof jmp_code);
+ vdm::write_phys(vdm::syscall_address.load(), jmp_code, sizeof jmp_code);
auto result = reinterpret_cast(proc)(args ...);
- write_phys(vdm::syscall_address.load(), orig_bytes, sizeof orig_bytes);
+ vdm::write_phys(vdm::syscall_address.load(), orig_bytes, sizeof orig_bytes);
syscall_mutex.unlock();
return result;
@@ -67,15 +60,35 @@ namespace vdm
template
__forceinline auto rkm(std::uintptr_t addr) -> T
{
+ static const auto ntoskrnl_memcpy =
+ util::get_kmodule_export("ntoskrnl.exe", "memcpy");
+
T buffer;
- rkm((void*)&buffer, (void*)addr, sizeof T);
+ this->syscall(
+ ntoskrnl_memcpy, &buffer, (void*)addr, sizeof T);
+
return buffer;
}
template
- __forceinline auto wkm(std::uintptr_t addr, const T& value) -> bool
+ __forceinline void wkm(std::uintptr_t addr, const T& value)
{
- return wkm((void*)addr, (void*)&value, sizeof T);
+ static const auto ntoskrnl_memcpy =
+ util::get_kmodule_export("ntoskrnl.exe", "memcpy");
+
+ this->syscall(
+ ntoskrnl_memcpy, (void*)addr, &value, sizeof T);
+ }
+
+ __forceinline auto get_virtual(std::uintptr_t addr) -> std::uintptr_t
+ {
+ static const auto ntoskrnl_get_virtual =
+ util::get_kmodule_export(
+ "ntoskrnl.exe",
+ "MmGetVirtualForPhysical");
+
+ return this->syscall(
+ ntoskrnl_get_virtual, addr);
}
__forceinline auto get_peprocess(std::uint32_t pid) -> PEPROCESS
@@ -93,23 +106,8 @@ namespace vdm
);
return peproc;
}
-
- __forceinline auto get_virtual(std::uintptr_t addr) -> std::uintptr_t
- {
- static const auto ntoskrnl_get_virtual =
- util::get_kmodule_export(
- "ntoskrnl.exe",
- "MmGetVirtualForPhysical");
-
- return this->syscall(
- ntoskrnl_get_virtual, addr);
- }
-
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;
};
}
\ No newline at end of file
diff --git a/um-example/PSKDM.lib b/um-example/PSKDM.lib
index 4d0e6a1..bf5f52e 100644
Binary files a/um-example/PSKDM.lib and b/um-example/PSKDM.lib differ
diff --git a/um-example/main.cpp b/um-example/main.cpp
index 0cbbebb..601130b 100644
--- a/um-example/main.cpp
+++ b/um-example/main.cpp
@@ -20,10 +20,10 @@ int __cdecl main(int argc, char** argv)
(
driver_data.data(),
driver_data.size(),
- nullptr // you can pass your structure here...
+ nullptr
);
- std::printf("[+] driver mapping result -> 0x%x (0 == STATUS_SUCCESS)\n", result);
+ std::printf("[+] driver mapping result -> 0x%x\n", result);
std::printf("[+] driver base address (usermode) -> 0x%p\n", driver_base);
std::getchar();
}
\ No newline at end of file
diff --git a/um-example/map_driver.hpp b/um-example/map_driver.hpp
index 7e2fcf1..3291a01 100644
--- a/um-example/map_driver.hpp
+++ b/um-example/map_driver.hpp
@@ -7,14 +7,13 @@ namespace mapper
{
enum class mapper_error
{
- error_success, // everything is good!
- image_invalid, // the driver your trying to map is invalid (are you importing things that arent in ntoskrnl?)
- load_error, // unable to load signed driver into the kernel (are you running as admin?)
- unload_error, // unable to unload signed driver from kernel (are all handles to this driver closes?)
- piddb_fail, // piddb cache clearing failed... (are you using this code below windows 10?)
- init_failed, // setting up library dependancies failed!
- failed_to_create_proc, // was unable to create a new process to inject driver into! (RuntimeBroker.exe)
- set_mgr_failure // unable to stop working set manager thread... this thread can cause issues with PTM...
+ error_success = 0x000, // everything is good!
+ image_invalid = 0x111, // the driver your trying to map is invalid (are you importing things that arent in ntoskrnl?)
+ load_error = 0x222, // unable to load signed driver into the kernel (are you running as admin?)
+ unload_error = 0x333, // unable to unload signed driver from kernel (are all handles to this driver closes?)
+ piddb_fail = 0x444, // piddb cache clearing failed... (are you using this code below windows 10?)
+ init_failed = 0x555, // setting up library dependancies failed!
+ failed_to_create_proc = 0x777 // was unable to create a new process to inject driver into! (RuntimeBroker.exe)
};
///
@@ -24,5 +23,5 @@ namespace mapper
/// size of the driver buffer
/// data to be sent to the entry point of the driver...
/// status of the driver being mapped, and base address of the driver...
- auto map_driver(std::uint8_t* drv_image, std::size_t image_size, void** entry_data) -> std::pair;
+ std::pair map_driver(std::uint8_t* drv_image, std::size_t image_size, void** entry_data);
}
\ No newline at end of file