|
|
@ -8,9 +8,12 @@ namespace nasa
|
|
|
|
dirbase(get_dirbase(krnl_ctx, pid)),
|
|
|
|
dirbase(get_dirbase(krnl_ctx, pid)),
|
|
|
|
pid(pid)
|
|
|
|
pid(pid)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// find an empty pml4e...
|
|
|
|
|
|
|
|
for (auto idx = 100u; idx > 0u; --idx)
|
|
|
|
|
|
|
|
if (!k_ctx->rkm<pml4e>(k_ctx->get_virtual((reinterpret_cast<::ppml4e>(get_dirbase()) + idx))).present)
|
|
|
|
|
|
|
|
this->pml4e_index = idx;
|
|
|
|
|
|
|
|
|
|
|
|
// allocate a pdpt
|
|
|
|
// allocate a pdpt
|
|
|
|
//
|
|
|
|
|
|
|
|
this->new_pdpt.second =
|
|
|
|
this->new_pdpt.second =
|
|
|
|
reinterpret_cast<ppdpte>(
|
|
|
|
reinterpret_cast<ppdpte>(
|
|
|
|
VirtualAlloc(
|
|
|
|
VirtualAlloc(
|
|
|
@ -21,30 +24,18 @@ namespace nasa
|
|
|
|
));
|
|
|
|
));
|
|
|
|
PAGE_IN(this->new_pdpt.second, PAGE_SIZE);
|
|
|
|
PAGE_IN(this->new_pdpt.second, PAGE_SIZE);
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// get page table entries for new pdpt
|
|
|
|
// get page table entries for new pdpt
|
|
|
|
//
|
|
|
|
|
|
|
|
pt_entries new_pdpt_entries;
|
|
|
|
pt_entries new_pdpt_entries;
|
|
|
|
hyperspace_entries(
|
|
|
|
hyperspace_entries(new_pdpt_entries, new_pdpt.second);
|
|
|
|
new_pdpt_entries,
|
|
|
|
|
|
|
|
new_pdpt.second
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
this->new_pdpt.first = reinterpret_cast<ppdpte>(new_pdpt_entries.pt.second.pfn << 12);
|
|
|
|
this->new_pdpt.first = reinterpret_cast<ppdpte>(new_pdpt_entries.pt.second.pfn << 12);
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// make a new pml4e that points to our new pdpt.
|
|
|
|
// make a new pml4e that points to our new pdpt.
|
|
|
|
//
|
|
|
|
|
|
|
|
new_pdpt_entries.pml4.second.pfn = new_pdpt_entries.pt.second.pfn;
|
|
|
|
new_pdpt_entries.pml4.second.pfn = new_pdpt_entries.pt.second.pfn;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// set the pml4e to point to the new pdpt
|
|
|
|
// 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>(get_dirbase()) + PML4E_INDEX, new_pdpt_entries.pml4.second, true);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// make a new pd
|
|
|
|
// make a new pd
|
|
|
|
//
|
|
|
|
|
|
|
|
this->new_pd.second =
|
|
|
|
this->new_pd.second =
|
|
|
|
reinterpret_cast<ppde>(
|
|
|
|
reinterpret_cast<ppde>(
|
|
|
|
VirtualAlloc(
|
|
|
|
VirtualAlloc(
|
|
|
@ -78,31 +69,22 @@ namespace nasa
|
|
|
|
));
|
|
|
|
));
|
|
|
|
PAGE_IN(this->new_pt.second, PAGE_SIZE);
|
|
|
|
PAGE_IN(this->new_pt.second, PAGE_SIZE);
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// get paging table entries for pt
|
|
|
|
// get paging table entries for pt
|
|
|
|
//
|
|
|
|
|
|
|
|
pt_entries new_pt_entries;
|
|
|
|
pt_entries new_pt_entries;
|
|
|
|
hyperspace_entries(
|
|
|
|
hyperspace_entries(new_pt_entries, this->new_pt.second);
|
|
|
|
new_pt_entries,
|
|
|
|
|
|
|
|
this->new_pt.second
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
this->new_pt.first = reinterpret_cast<ppte>(new_pt_entries.pt.second.pfn << 12);
|
|
|
|
this->new_pt.first = reinterpret_cast<ppte>(new_pt_entries.pt.second.pfn << 12);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
mem_ctx::~mem_ctx()
|
|
|
|
mem_ctx::~mem_ctx()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
//
|
|
|
|
|
|
|
|
// remove pml4e
|
|
|
|
// remove pml4e
|
|
|
|
//
|
|
|
|
|
|
|
|
pml4e null_value{ NULL };
|
|
|
|
pml4e null_value{ NULL };
|
|
|
|
set_pml4e(reinterpret_cast<::ppml4e>(get_dirbase()) + PML4E_INDEX, null_value, true);
|
|
|
|
set_pml4e(reinterpret_cast<::ppml4e>(get_dirbase()) + this->pml4e_index, null_value, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void* mem_ctx::set_page(void* addr)
|
|
|
|
void* mem_ctx::set_page(void* addr)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
//
|
|
|
|
|
|
|
|
// table entry change.
|
|
|
|
// table entry change.
|
|
|
|
//
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
++pte_index;
|
|
|
|
++pte_index;
|
|
|
|
if (pte_index >= 511)
|
|
|
|
if (pte_index >= 511)
|
|
|
@ -128,9 +110,7 @@ namespace nasa
|
|
|
|
new_pdpte.user_supervisor = true;
|
|
|
|
new_pdpte.user_supervisor = true;
|
|
|
|
new_pdpte.accessed = 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;
|
|
|
|
|
|
|
|
|
|
|
|
pde new_pde = { NULL };
|
|
|
|
pde new_pde = { NULL };
|
|
|
@ -140,9 +120,7 @@ namespace nasa
|
|
|
|
new_pde.user_supervisor = true;
|
|
|
|
new_pde.user_supervisor = true;
|
|
|
|
new_pde.accessed = 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;
|
|
|
|
|
|
|
|
|
|
|
|
pte new_pte = { NULL };
|
|
|
|
pte new_pte = { NULL };
|
|
|
@ -152,25 +130,19 @@ namespace nasa
|
|
|
|
new_pte.user_supervisor = true;
|
|
|
|
new_pte.user_supervisor = true;
|
|
|
|
new_pte.accessed = 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;
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// set page offset
|
|
|
|
// set page offset
|
|
|
|
//
|
|
|
|
|
|
|
|
this->page_offset = virt_addr_t{ addr }.offset;
|
|
|
|
this->page_offset = virt_addr_t{ addr }.offset;
|
|
|
|
return get_page();
|
|
|
|
return get_page();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void* mem_ctx::get_page() const
|
|
|
|
void* mem_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;
|
|
|
|
new_addr.pml4_index = PML4E_INDEX;
|
|
|
|
new_addr.pml4_index = this->pml4e_index;
|
|
|
|
new_addr.pdpt_index = this->pdpte_index;
|
|
|
|
new_addr.pdpt_index = this->pdpte_index;
|
|
|
|
new_addr.pd_index = this->pde_index;
|
|
|
|
new_addr.pd_index = this->pde_index;
|
|
|
|
new_addr.pt_index = this->pte_index;
|
|
|
|
new_addr.pt_index = this->pte_index;
|
|
|
@ -180,18 +152,11 @@ namespace nasa
|
|
|
|
|
|
|
|
|
|
|
|
void* mem_ctx::get_dirbase(kernel_ctx& k_ctx, DWORD pid)
|
|
|
|
void* mem_ctx::get_dirbase(kernel_ctx& k_ctx, DWORD pid)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (!pid)
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const auto peproc =
|
|
|
|
const auto peproc =
|
|
|
|
reinterpret_cast<std::uint64_t>(k_ctx.get_peprocess(pid));
|
|
|
|
reinterpret_cast<std::uint64_t>(k_ctx.get_peprocess(pid));
|
|
|
|
|
|
|
|
|
|
|
|
if (!peproc)
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pte dirbase = k_ctx.rkm<pte>(
|
|
|
|
pte dirbase = k_ctx.rkm<pte>(
|
|
|
|
reinterpret_cast<void*>(peproc + 0x28)
|
|
|
|
reinterpret_cast<void*>(peproc + 0x28));
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return reinterpret_cast<void*>(dirbase.pfn << 12);
|
|
|
|
return reinterpret_cast<void*>(dirbase.pfn << 12);
|
|
|
|
}
|
|
|
|
}
|
|
|
|