added array index overload + removed some junk code

merge-requests/1/merge v1.0
xerox 4 years ago
parent af95fd12e9
commit 9ab20011fa

@ -23,10 +23,6 @@ namespace nasa
DONT_RESOLVE_DLL_REFERENCES
));
DBG_PRINT("[+] page offset of %s is 0x%llx\n", syscall_hook.first.data(), nt_page_offset);
DBG_PRINT("[+] ntoskrnl_buffer: 0x%p\n", ntoskrnl_buffer);
DBG_PRINT("[+] ntoskrnl_buffer was 0x%p, nt_rva was 0x%p\n", ntoskrnl_buffer, nt_rva);
std::vector<std::thread> search_threads;
//--- for each physical memory range, make a thread to search it
for (auto ranges : util::pmem_ranges)
@ -39,14 +35,10 @@ namespace nasa
for (std::thread& search_thread : search_threads)
search_thread.join();
DBG_PRINT("[+] psyscall_func: 0x%p\n", psyscall_func.load());
}
void kernel_ctx::map_syscall(std::uintptr_t begin, std::uintptr_t end) const
{
printf("[+] scanning from begin: 0x%p to: 0x%p\n", begin, begin + end);
//if the physical memory range is less then or equal to 2mb
if (begin + end <= 0x1000 * 512)
{
@ -365,17 +357,4 @@ namespace nasa
syscall<ExReleaseResourceLite>(release_resource, piddb_lock);
return false;
}
void kernel_ctx::fix_syscall(nasa::mem_ctx& ctx)
{
pt_entries syscall_entries; // not used.
nasa::psyscall_func =
ctx.set_page(
ctx.virt_to_phys(
syscall_entries,
nasa::psyscall_func
));
nasa::unmap_all();
}
}

@ -111,11 +111,6 @@ namespace nasa
// clear piddb cache of a specific driver
//
bool clear_piddb_cache(const std::string& file_name, const std::uint32_t timestamp);
//
// fix syscall to use new page.
//
static void fix_syscall(nasa::mem_ctx& ctx);
private:
//

@ -2,16 +2,25 @@
#include "kernel_ctx/kernel_ctx.h"
#include "mem_ctx/mem_ctx.hpp"
int main()
int __cdecl main(int argc, char** argv)
{
// only time driver needs to be loaded is to init physmeme/kernel_ctx...
nasa::load_drv();
nasa::kernel_ctx kernel;
if (kernel.clear_piddb_cache(nasa::drv_key, util::get_file_header((void*)raw_driver)->TimeDateStamp))
std::cout << "[+] flushed PIDDB Cache for physmeme driver..." << std::endl;
nasa::unload_drv();
nasa::mem_ctx my_proc(kernel, GetCurrentProcessId());
for (auto idx = 0u; idx < 512 * 512 * 512 * 5; ++idx)
my_proc.read_virtual<short>(GetModuleHandleA(NULL));
const std::pair<unsigned, virt_addr_t> my_proc_data = { GetCurrentProcessId(), virt_addr_t{ GetModuleHandle(NULL) } };
std::cout << "[+] my pid: " << std::hex << my_proc_data.first << std::endl;
std::cout << "[+] my base: " << std::showbase << std::hex << my_proc_data.second.value << std::endl;
std::cout << "[+] accessed my base address (512 ^ 4) * 5 times..." << std::endl;
nasa::mem_ctx my_proc(kernel, my_proc_data.first);
const auto module_base = my_proc_data.second;
std::cout << "[+] base address pml4e: " << std::hex << my_proc[module_base.pml4_index].value << std::endl;
std::cout << "[+] base address pdpte: " << std::hex << my_proc[{module_base.pml4_index, module_base.pdpt_index}].value << std::endl;
std::cout << "[+] base address pde: " << std::hex << my_proc[{module_base.pml4_index, module_base.pdpt_index, module_base.pd_index}].value << std::endl;
std::cout << "[+] base address pte: " << std::hex << my_proc[{module_base.pml4_index, module_base.pdpt_index, module_base.pd_index, module_base.pt_index}].value << std::endl;
std::cin.get();
}

@ -253,11 +253,7 @@ namespace nasa
pt_entries entries;
if (use_hyperspace ? hyperspace_entries(entries, addr) : (bool)virt_to_phys(entries, addr))
{
::pte pte;
memcpy(&pte, &entries.pt.second, sizeof(pte));
return { entries.pt.first, pte };
}
return { entries.pt.first, entries.pt.second };
return {};
}
@ -279,15 +275,7 @@ namespace nasa
pt_entries entries;
if (use_hyperspace ? hyperspace_entries(entries, addr) : (bool)virt_to_phys(entries, addr))
{
::pde pde;
memcpy(
&pde,
&entries.pd.second,
sizeof(pde)
);
return { entries.pd.first, pde };
}
return { entries.pd.first, entries.pd.second };
return {};
}
@ -309,15 +297,7 @@ namespace nasa
pt_entries entries;
if (use_hyperspace ? hyperspace_entries(entries, addr) : (bool)virt_to_phys(entries, addr))
{
::pdpte pdpte;
memcpy(
&pdpte,
&entries.pdpt.second,
sizeof(pdpte)
);
return { entries.pdpt.first, pdpte };
}
return { entries.pdpt.first, entries.pdpt.second };
return {};
}
@ -339,15 +319,7 @@ namespace nasa
pt_entries entries;
if (use_hyperspace ? hyperspace_entries(entries, addr) : (bool)virt_to_phys(entries, addr))
{
::pml4e pml4e;
memcpy(
&pml4e,
&entries.pml4.second,
sizeof(pml4e)
);
return { entries.pml4.first, pml4e };
}
return { entries.pml4.first, entries.pml4.second };
return {};
}
@ -371,7 +343,8 @@ namespace nasa
if (size <= PAGE_SIZE - virt_addr.offset)
{
pt_entries entries;
read_phys(
read_phys
(
buffer,
virt_to_phys(entries, addr),
size
@ -386,13 +359,16 @@ namespace nasa
else
{
// cut remainder
const auto [new_buffer_addr, new_addr] = read_virtual(
const auto [new_buffer_addr, new_addr] = read_virtual
(
buffer,
addr,
PAGE_SIZE - virt_addr.offset
);
// forward work load
return read_virtual(
return read_virtual
(
new_buffer_addr,
new_addr,
size - (PAGE_SIZE - virt_addr.offset)
@ -409,13 +385,15 @@ namespace nasa
if (size <= PAGE_SIZE - virt_addr.offset)
{
pt_entries entries;
write_phys(
write_phys
(
buffer,
virt_to_phys(entries, addr),
size
);
return {
return
{
reinterpret_cast<void*>(reinterpret_cast<std::uintptr_t>(buffer) + size),
reinterpret_cast<void*>(reinterpret_cast<std::uintptr_t>(addr) + size)
};
@ -423,14 +401,16 @@ namespace nasa
else
{
// cut remainder
const auto [new_buffer_addr, new_addr] = write_virtual(
const auto [new_buffer_addr, new_addr] = write_virtual
(
buffer,
addr,
PAGE_SIZE - virt_addr.offset
);
// forward work load
return write_virtual(
return write_virtual
(
new_buffer_addr,
new_addr,
size - (PAGE_SIZE - virt_addr.offset)
@ -443,7 +423,7 @@ namespace nasa
if (!buffer || !addr || !size)
return;
auto temp_page = set_page(addr);
const auto temp_page = set_page(addr);
if (temp_page)
memcpy(buffer, temp_page, size);
}
@ -453,7 +433,7 @@ namespace nasa
if (!buffer || !addr || !size)
return;
auto temp_page = set_page(addr);
const auto temp_page = set_page(addr);
if (temp_page)
memcpy(temp_page, buffer, size);
}
@ -515,4 +495,27 @@ namespace nasa
{
return dirbase;
}
pml4e mem_ctx::operator[](std::uint16_t pml4_idx)
{
return read_phys<::pml4e>(reinterpret_cast<ppml4e>(this->dirbase) + pml4_idx);
}
pdpte mem_ctx::operator[](const std::pair<std::uint16_t, std::uint16_t>& entry_idx)
{
const auto pml4_entry = this->operator[](entry_idx.first);
return read_phys<::pdpte>(reinterpret_cast<ppdpte>(pml4_entry.pfn << 12) + entry_idx.second);
}
pde mem_ctx::operator[](const std::tuple<std::uint16_t, std::uint16_t, std::uint16_t>& entry_idx)
{
const auto pdpt_entry = this->operator[]({ std::get<0>(entry_idx), std::get<1>(entry_idx) });
return read_phys<::pde>(reinterpret_cast<ppde>(pdpt_entry.pfn << 12) + std::get<2>(entry_idx));
}
pte mem_ctx::operator[](const std::tuple<std::uint16_t, std::uint16_t, std::uint16_t, std::uint16_t>& 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<ppte>(pd_entry.pfn << 12) + std::get<3>(entry_idx));
}
}

@ -57,8 +57,7 @@ namespace nasa
template <class T>
T read_phys(void* addr)
{
if (!addr)
return {};
if (!addr) return {};
T buffer;
read_phys((void*)&buffer, addr, sizeof(T));
return buffer;
@ -67,8 +66,7 @@ namespace nasa
template <class T>
void write_phys(void* addr, const T& data)
{
if (!addr)
return;
if (!addr) return;
write_phys((void*)&data, addr, sizeof(T));
}
@ -78,8 +76,7 @@ namespace nasa
template <class T>
T read_virtual(void* addr)
{
if (!addr)
return {};
if (!addr) return {};
T buffer;
read_virtual((void*)&buffer, addr, sizeof(T));
return buffer;
@ -102,7 +99,11 @@ namespace nasa
void* set_page(void* addr);
void* get_page() const;
unsigned get_pid() const;
kernel_ctx* k_ctx;
pml4e operator[](std::uint16_t pml4_idx);
pdpte operator[](const std::pair<std::uint16_t, std::uint16_t>& entry_idx);
pde operator[](const std::tuple<std::uint16_t, std::uint16_t, std::uint16_t>& entry_idx);
pte operator[](const std::tuple<std::uint16_t, std::uint16_t, std::uint16_t, std::uint16_t>& entry_idx);
private:
//
@ -110,7 +111,7 @@ namespace nasa
//
bool hyperspace_entries(pt_entries& entries, void* addr);
void* dirbase;
kernel_ctx* k_ctx;
std::uint16_t pde_index, pte_index, pdpte_index, page_offset;
/// first == physical

@ -1,6 +1,8 @@
#pragma once
#include <Windows.h>
#include <winternl.h>
#include <cstdint>
#include <cstddef>
#pragma comment(lib, "ntdll.lib")
#if _DEBUG
@ -246,105 +248,105 @@ using ZwLockVirtualMemory = NTSTATUS (__fastcall*)(
typedef union _virt_addr_t
{
PVOID value;
void* value;
struct
{
ULONG64 offset : 12;
ULONG64 pt_index : 9;
ULONG64 pd_index : 9;
ULONG64 pdpt_index : 9;
ULONG64 pml4_index : 9;
ULONG64 reserved : 16;
std::uint64_t offset : 12;
std::uint64_t pt_index : 9;
std::uint64_t pd_index : 9;
std::uint64_t pdpt_index : 9;
std::uint64_t pml4_index : 9;
std::uint64_t reserved : 16;
};
} virt_addr_t, *pvirt_addr_t;
static_assert(sizeof(virt_addr_t) == sizeof(PVOID), "Size mismatch, only 64-bit supported.");
typedef union _pml4e
{
ULONG64 value;
std::uint64_t value;
struct
{
ULONG64 present : 1; // Must be 1, region invalid if 0.
ULONG64 ReadWrite : 1; // If 0, writes not allowed.
ULONG64 user_supervisor : 1; // If 0, user-mode accesses not allowed.
ULONG64 PageWriteThrough : 1; // Determines the memory type used to access PDPT.
ULONG64 page_cache : 1; // Determines the memory type used to access PDPT.
ULONG64 accessed : 1; // If 0, this entry has not been used for translation.
ULONG64 Ignored1 : 1;
ULONG64 page_size : 1; // Must be 0 for PML4E.
ULONG64 Ignored2 : 4;
ULONG64 pfn : 36; // The page frame number of the PDPT of this PML4E.
ULONG64 Reserved : 4;
ULONG64 Ignored3 : 11;
ULONG64 nx : 1; // If 1, instruction fetches not allowed.
std::uint64_t present : 1; // Must be 1, region invalid if 0.
std::uint64_t ReadWrite : 1; // If 0, writes not allowed.
std::uint64_t user_supervisor : 1; // If 0, user-mode accesses not allowed.
std::uint64_t PageWriteThrough : 1; // Determines the memory type used to access PDPT.
std::uint64_t page_cache : 1; // Determines the memory type used to access PDPT.
std::uint64_t accessed : 1; // If 0, this entry has not been used for translation.
std::uint64_t Ignored1 : 1;
std::uint64_t page_size : 1; // Must be 0 for PML4E.
std::uint64_t Ignored2 : 4;
std::uint64_t pfn : 36; // The page frame number of the PDPT of this PML4E.
std::uint64_t Reserved : 4;
std::uint64_t Ignored3 : 11;
std::uint64_t nx : 1; // If 1, instruction fetches not allowed.
};
} pml4e, * ppml4e;
static_assert(sizeof(pml4e) == sizeof(PVOID), "Size mismatch, only 64-bit supported.");
typedef union _pdpte
{
ULONG64 value;
std::uint64_t value;
struct
{
ULONG64 present : 1; // Must be 1, region invalid if 0.
ULONG64 rw : 1; // If 0, writes not allowed.
ULONG64 user_supervisor : 1; // If 0, user-mode accesses not allowed.
ULONG64 PageWriteThrough : 1; // Determines the memory type used to access PD.
ULONG64 page_cache : 1; // Determines the memory type used to access PD.
ULONG64 accessed : 1; // If 0, this entry has not been used for translation.
ULONG64 Ignored1 : 1;
ULONG64 page_size : 1; // If 1, this entry maps a 1GB page.
ULONG64 Ignored2 : 4;
ULONG64 pfn : 36; // The page frame number of the PD of this PDPTE.
ULONG64 Reserved : 4;
ULONG64 Ignored3 : 11;
ULONG64 nx : 1; // If 1, instruction fetches not allowed.
std::uint64_t present : 1; // Must be 1, region invalid if 0.
std::uint64_t rw : 1; // If 0, writes not allowed.
std::uint64_t user_supervisor : 1; // If 0, user-mode accesses not allowed.
std::uint64_t PageWriteThrough : 1; // Determines the memory type used to access PD.
std::uint64_t page_cache : 1; // Determines the memory type used to access PD.
std::uint64_t accessed : 1; // If 0, this entry has not been used for translation.
std::uint64_t Ignored1 : 1;
std::uint64_t page_size : 1; // If 1, this entry maps a 1GB page.
std::uint64_t Ignored2 : 4;
std::uint64_t pfn : 36; // The page frame number of the PD of this PDPTE.
std::uint64_t Reserved : 4;
std::uint64_t Ignored3 : 11;
std::uint64_t nx : 1; // If 1, instruction fetches not allowed.
};
} pdpte, * ppdpte;
static_assert(sizeof(pdpte) == sizeof(PVOID), "Size mismatch, only 64-bit supported.");
typedef union _pde
{
ULONG64 value;
std::uint64_t value;
struct
{
ULONG64 present : 1; // Must be 1, region invalid if 0.
ULONG64 rw : 1; // If 0, writes not allowed.
ULONG64 user_supervisor : 1; // If 0, user-mode accesses not allowed.
ULONG64 PageWriteThrough : 1; // Determines the memory type used to access PT.
ULONG64 page_cache : 1; // Determines the memory type used to access PT.
ULONG64 accessed : 1; // If 0, this entry has not been used for translation.
ULONG64 Ignored1 : 1;
ULONG64 page_size : 1; // If 1, this entry maps a 2MB page.
ULONG64 Ignored2 : 4;
ULONG64 pfn : 36; // The page frame number of the PT of this PDE.
ULONG64 Reserved : 4;
ULONG64 Ignored3 : 11;
ULONG64 nx : 1; // If 1, instruction fetches not allowed.
std::uint64_t present : 1; // Must be 1, region invalid if 0.
std::uint64_t rw : 1; // If 0, writes not allowed.
std::uint64_t user_supervisor : 1; // If 0, user-mode accesses not allowed.
std::uint64_t PageWriteThrough : 1; // Determines the memory type used to access PT.
std::uint64_t page_cache : 1; // Determines the memory type used to access PT.
std::uint64_t accessed : 1; // If 0, this entry has not been used for translation.
std::uint64_t Ignored1 : 1;
std::uint64_t page_size : 1; // If 1, this entry maps a 2MB page.
std::uint64_t Ignored2 : 4;
std::uint64_t pfn : 36; // The page frame number of the PT of this PDE.
std::uint64_t Reserved : 4;
std::uint64_t Ignored3 : 11;
std::uint64_t nx : 1; // If 1, instruction fetches not allowed.
};
} pde, * ppde;
static_assert(sizeof(pde) == sizeof(PVOID), "Size mismatch, only 64-bit supported.");
typedef union _pte
{
ULONG64 value;
std::uint64_t value;
struct
{
ULONG64 present : 1; // Must be 1, region invalid if 0.
ULONG64 rw : 1; // If 0, writes not allowed.
ULONG64 user_supervisor : 1; // If 0, user-mode accesses not allowed.
ULONG64 PageWriteThrough : 1; // Determines the memory type used to access the memory.
ULONG64 page_cache : 1; // Determines the memory type used to access the memory.
ULONG64 accessed : 1; // If 0, this entry has not been used for translation.
ULONG64 Dirty : 1; // If 0, the memory backing this page has not been written to.
ULONG64 PageAccessType : 1; // Determines the memory type used to access the memory.
ULONG64 Global : 1; // If 1 and the PGE bit of CR4 is set, translations are global.
ULONG64 Ignored2 : 3;
ULONG64 pfn : 36; // The page frame number of the backing physical page.
ULONG64 reserved : 4;
ULONG64 Ignored3 : 7;
ULONG64 ProtectionKey : 4; // If the PKE bit of CR4 is set, determines the protection key.
ULONG64 nx : 1; // If 1, instruction fetches not allowed.
std::uint64_t present : 1; // Must be 1, region invalid if 0.
std::uint64_t rw : 1; // If 0, writes not allowed.
std::uint64_t user_supervisor : 1; // If 0, user-mode accesses not allowed.
std::uint64_t PageWriteThrough : 1; // Determines the memory type used to access the memory.
std::uint64_t page_cache : 1; // Determines the memory type used to access the memory.
std::uint64_t accessed : 1; // If 0, this entry has not been used for translation.
std::uint64_t Dirty : 1; // If 0, the memory backing this page has not been written to.
std::uint64_t PageAccessType : 1; // Determines the memory type used to access the memory.
std::uint64_t Global : 1; // If 1 and the PGE bit of CR4 is set, translations are global.
std::uint64_t Ignored2 : 3;
std::uint64_t pfn : 36; // The page frame number of the backing physical page.
std::uint64_t reserved : 4;
std::uint64_t Ignored3 : 7;
std::uint64_t ProtectionKey : 4; // If the PKE bit of CR4 is set, determines the protection key.
std::uint64_t nx : 1; // If 1, instruction fetches not allowed.
};
} pte, * ppte;
static_assert(sizeof(pte) == sizeof(PVOID), "Size mismatch, only 64-bit supported.");

Loading…
Cancel
Save