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 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; std::vector<std::thread> search_threads;
//--- for each physical memory range, make a thread to search it //--- for each physical memory range, make a thread to search it
for (auto ranges : util::pmem_ranges) for (auto ranges : util::pmem_ranges)
@ -39,14 +35,10 @@ namespace nasa
for (std::thread& search_thread : search_threads) for (std::thread& search_thread : search_threads)
search_thread.join(); 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 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 the physical memory range is less then or equal to 2mb
if (begin + end <= 0x1000 * 512) if (begin + end <= 0x1000 * 512)
{ {
@ -365,17 +357,4 @@ namespace nasa
syscall<ExReleaseResourceLite>(release_resource, piddb_lock); syscall<ExReleaseResourceLite>(release_resource, piddb_lock);
return false; 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 // clear piddb cache of a specific driver
// //
bool clear_piddb_cache(const std::string& file_name, const std::uint32_t timestamp); 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: private:
// //

@ -2,16 +2,25 @@
#include "kernel_ctx/kernel_ctx.h" #include "kernel_ctx/kernel_ctx.h"
#include "mem_ctx/mem_ctx.hpp" #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::load_drv();
nasa::kernel_ctx kernel; 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::unload_drv();
nasa::mem_ctx my_proc(kernel, GetCurrentProcessId()); const std::pair<unsigned, virt_addr_t> my_proc_data = { GetCurrentProcessId(), virt_addr_t{ GetModuleHandle(NULL) } };
for (auto idx = 0u; idx < 512 * 512 * 512 * 5; ++idx) std::cout << "[+] my pid: " << std::hex << my_proc_data.first << std::endl;
my_proc.read_virtual<short>(GetModuleHandleA(NULL)); 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(); std::cin.get();
} }

@ -253,11 +253,7 @@ namespace nasa
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.pt.first, entries.pt.second };
::pte pte;
memcpy(&pte, &entries.pt.second, sizeof(pte));
return { entries.pt.first, pte };
}
return {}; return {};
} }
@ -279,15 +275,7 @@ namespace nasa
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 };
::pde pde;
memcpy(
&pde,
&entries.pd.second,
sizeof(pde)
);
return { entries.pd.first, pde };
}
return {}; return {};
} }
@ -309,15 +297,7 @@ namespace nasa
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 };
::pdpte pdpte;
memcpy(
&pdpte,
&entries.pdpt.second,
sizeof(pdpte)
);
return { entries.pdpt.first, pdpte };
}
return {}; return {};
} }
@ -339,15 +319,7 @@ namespace nasa
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 };
::pml4e pml4e;
memcpy(
&pml4e,
&entries.pml4.second,
sizeof(pml4e)
);
return { entries.pml4.first, pml4e };
}
return {}; return {};
} }
@ -371,7 +343,8 @@ namespace nasa
if (size <= PAGE_SIZE - virt_addr.offset) if (size <= PAGE_SIZE - virt_addr.offset)
{ {
pt_entries entries; pt_entries entries;
read_phys( read_phys
(
buffer, buffer,
virt_to_phys(entries, addr), virt_to_phys(entries, addr),
size size
@ -386,13 +359,16 @@ namespace nasa
else else
{ {
// cut remainder // cut remainder
const auto [new_buffer_addr, new_addr] = read_virtual( const auto [new_buffer_addr, new_addr] = read_virtual
(
buffer, buffer,
addr, addr,
PAGE_SIZE - virt_addr.offset PAGE_SIZE - virt_addr.offset
); );
// forward work load // forward work load
return read_virtual( return read_virtual
(
new_buffer_addr, new_buffer_addr,
new_addr, new_addr,
size - (PAGE_SIZE - virt_addr.offset) size - (PAGE_SIZE - virt_addr.offset)
@ -409,13 +385,15 @@ namespace nasa
if (size <= PAGE_SIZE - virt_addr.offset) if (size <= PAGE_SIZE - virt_addr.offset)
{ {
pt_entries entries; pt_entries entries;
write_phys( write_phys
(
buffer, buffer,
virt_to_phys(entries, addr), virt_to_phys(entries, addr),
size size
); );
return { return
{
reinterpret_cast<void*>(reinterpret_cast<std::uintptr_t>(buffer) + size), reinterpret_cast<void*>(reinterpret_cast<std::uintptr_t>(buffer) + size),
reinterpret_cast<void*>(reinterpret_cast<std::uintptr_t>(addr) + size) reinterpret_cast<void*>(reinterpret_cast<std::uintptr_t>(addr) + size)
}; };
@ -423,14 +401,16 @@ namespace nasa
else else
{ {
// cut remainder // cut remainder
const auto [new_buffer_addr, new_addr] = write_virtual( const auto [new_buffer_addr, new_addr] = write_virtual
(
buffer, buffer,
addr, addr,
PAGE_SIZE - virt_addr.offset PAGE_SIZE - virt_addr.offset
); );
// forward work load // forward work load
return write_virtual( return write_virtual
(
new_buffer_addr, new_buffer_addr,
new_addr, new_addr,
size - (PAGE_SIZE - virt_addr.offset) size - (PAGE_SIZE - virt_addr.offset)
@ -443,7 +423,7 @@ namespace nasa
if (!buffer || !addr || !size) if (!buffer || !addr || !size)
return; return;
auto temp_page = set_page(addr); const auto temp_page = set_page(addr);
if (temp_page) if (temp_page)
memcpy(buffer, temp_page, size); memcpy(buffer, temp_page, size);
} }
@ -453,7 +433,7 @@ namespace nasa
if (!buffer || !addr || !size) if (!buffer || !addr || !size)
return; return;
auto temp_page = set_page(addr); const auto temp_page = set_page(addr);
if (temp_page) if (temp_page)
memcpy(temp_page, buffer, size); memcpy(temp_page, buffer, size);
} }
@ -515,4 +495,27 @@ namespace nasa
{ {
return dirbase; 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> template <class T>
T read_phys(void* addr) T read_phys(void* addr)
{ {
if (!addr) if (!addr) return {};
return {};
T buffer; T buffer;
read_phys((void*)&buffer, addr, sizeof(T)); read_phys((void*)&buffer, addr, sizeof(T));
return buffer; return buffer;
@ -67,8 +66,7 @@ namespace nasa
template <class T> template <class T>
void write_phys(void* addr, const T& data) void write_phys(void* addr, const T& data)
{ {
if (!addr) if (!addr) return;
return;
write_phys((void*)&data, addr, sizeof(T)); write_phys((void*)&data, addr, sizeof(T));
} }
@ -78,8 +76,7 @@ namespace nasa
template <class T> template <class T>
T read_virtual(void* addr) T read_virtual(void* addr)
{ {
if (!addr) if (!addr) return {};
return {};
T buffer; T buffer;
read_virtual((void*)&buffer, addr, sizeof(T)); read_virtual((void*)&buffer, addr, sizeof(T));
return buffer; return buffer;
@ -102,7 +99,11 @@ namespace nasa
void* set_page(void* addr); void* set_page(void* addr);
void* get_page() const; void* get_page() const;
unsigned get_pid() 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: private:
// //
@ -110,7 +111,7 @@ namespace nasa
// //
bool hyperspace_entries(pt_entries& entries, void* addr); bool hyperspace_entries(pt_entries& entries, void* addr);
void* dirbase; void* dirbase;
kernel_ctx* k_ctx;
std::uint16_t pde_index, pte_index, pdpte_index, page_offset; std::uint16_t pde_index, pte_index, pdpte_index, page_offset;
/// first == physical /// first == physical

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

Loading…
Cancel
Save