From 9ab20011fa437ae021ac5cc738893f995aba58f1 Mon Sep 17 00:00:00 2001 From: xerox Date: Tue, 25 Aug 2020 02:30:08 -0700 Subject: [PATCH] added array index overload + removed some junk code --- nasa-tables/kernel_ctx/kernel_ctx.cpp | 21 ---- nasa-tables/kernel_ctx/kernel_ctx.h | 5 - nasa-tables/main.cpp | 19 +++- nasa-tables/mem_ctx/mem_ctx.cpp | 85 +++++++++-------- nasa-tables/mem_ctx/mem_ctx.hpp | 17 ++-- nasa-tables/util/nt.hpp | 132 +++++++++++++------------- 6 files changed, 134 insertions(+), 145 deletions(-) diff --git a/nasa-tables/kernel_ctx/kernel_ctx.cpp b/nasa-tables/kernel_ctx/kernel_ctx.cpp index db396f6..c841ae5 100644 --- a/nasa-tables/kernel_ctx/kernel_ctx.cpp +++ b/nasa-tables/kernel_ctx/kernel_ctx.cpp @@ -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 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(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(); - } } \ No newline at end of file diff --git a/nasa-tables/kernel_ctx/kernel_ctx.h b/nasa-tables/kernel_ctx/kernel_ctx.h index b84e3fa..c06451c 100644 --- a/nasa-tables/kernel_ctx/kernel_ctx.h +++ b/nasa-tables/kernel_ctx/kernel_ctx.h @@ -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: // diff --git a/nasa-tables/main.cpp b/nasa-tables/main.cpp index 7c8ac2c..5aa6f3a 100644 --- a/nasa-tables/main.cpp +++ b/nasa-tables/main.cpp @@ -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(GetModuleHandleA(NULL)); + const std::pair 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(); } \ No newline at end of file diff --git a/nasa-tables/mem_ctx/mem_ctx.cpp b/nasa-tables/mem_ctx/mem_ctx.cpp index 4ce5f55..a1c445d 100644 --- a/nasa-tables/mem_ctx/mem_ctx.cpp +++ b/nasa-tables/mem_ctx/mem_ctx.cpp @@ -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(reinterpret_cast(buffer) + size), reinterpret_cast(reinterpret_cast(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(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/nasa-tables/mem_ctx/mem_ctx.hpp b/nasa-tables/mem_ctx/mem_ctx.hpp index 3096684..b99228c 100644 --- a/nasa-tables/mem_ctx/mem_ctx.hpp +++ b/nasa-tables/mem_ctx/mem_ctx.hpp @@ -57,8 +57,7 @@ namespace nasa template 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 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 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& entry_idx); + pde operator[](const std::tuple& entry_idx); + pte operator[](const std::tuple& 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 diff --git a/nasa-tables/util/nt.hpp b/nasa-tables/util/nt.hpp index c0cbccc..1a39462 100644 --- a/nasa-tables/util/nt.hpp +++ b/nasa-tables/util/nt.hpp @@ -1,6 +1,8 @@ #pragma once #include #include +#include +#include #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.");