#pragma once #include #include #include #include #include #include #include "../vdm/vdm.hpp" namespace vdm { // change this to whatever you want :^) constexpr std::pair syscall_hook = { "NtShutdownSystem", "ntdll.dll" }; inline std::atomic is_page_found = false; inline std::atomic syscall_address = nullptr; inline std::uint16_t nt_page_offset; inline std::uint32_t nt_rva; inline std::uint8_t* ntoskrnl; class vdm_ctx { public: vdm_ctx(); template __forceinline std::invoke_result_t syscall(void* addr, Ts ... args) const { static const auto proc = GetProcAddress( LoadLibraryA(syscall_hook.second), syscall_hook.first ); static std::mutex syscall_mutex; syscall_mutex.lock(); // jmp [rip+0x0] std::uint8_t jmp_code[] = { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 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); // execute hook... vdm::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); syscall_mutex.unlock(); return result; } template __forceinline auto rkm(std::uintptr_t addr) -> T { static const auto ntoskrnl_memcpy = util::get_kmodule_export("ntoskrnl.exe", "memcpy"); T buffer; this->syscall( ntoskrnl_memcpy, &buffer, (void*)addr, sizeof T); return buffer; } template __forceinline void wkm(std::uintptr_t addr, const T& value) { static const auto ntoskrnl_memcpy = util::get_kmodule_export("ntoskrnl.exe", "memcpy"); this->syscall( ntoskrnl_memcpy, (void*)addr, &value, sizeof T); } __forceinline auto get_virtual(std::uintptr_t addr) -> std::uintptr_t { static const auto ntoskrnl_get_virtual = util::get_kmodule_export( "ntoskrnl.exe", "MmGetVirtualForPhysical"); return this->syscall( ntoskrnl_get_virtual, addr); } __forceinline auto get_peprocess(std::uint32_t pid) -> PEPROCESS { static const auto ps_lookup_peproc = util::get_kmodule_export( "ntoskrnl.exe", "PsLookupProcessByProcessId"); PEPROCESS peproc = nullptr; this->syscall( ps_lookup_peproc, (HANDLE)pid, &peproc ); return peproc; } private: void locate_syscall(std::uintptr_t begin, std::uintptr_t end) const; bool valid_syscall(void* syscall_addr) const; }; }