summaryrefslogtreecommitdiff
path: root/loader/client/syscall.hpp
blob: 64121f2ca10799c5b57eb7c5087e7c7d83a531a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#pragma once

#include <windows.h>
#include <winternl.h>

#include <map>
#include "fnv.hpp"
#include "strings.hpp"

namespace syscall {
	// stub for calling the syscalls
	class c_syscall_stub {
		uint8_t m_stub[11] = {
			0x4c, 0x8b, 0xd1,				// mov r10, rcx
			0xb8, 0x00, 0x00, 0x00, 0x00,	// mov eax, 0h
			0x0f, 0x05,						// syscall
			0xc3							// retn
		};

	public:
		void set_index(uint32_t index) {
			unsigned long old;
			if (VirtualProtect(m_stub, sizeof m_stub, PAGE_EXECUTE_READWRITE, &old)) {
				// okay now this is epic
				*(uint32_t*)(&m_stub[4]) = index;
			}
		}

		__forceinline bool validate() {
			return *(uint32_t*)(&m_stub[4]) != 0;
		}

		uintptr_t operator()() {
			return (uintptr_t)m_stub;
		}
	};

	// syscaller
	using file_t = std::pair< uint8_t *, size_t >;

	class c_syscall_mgr {
		std::map< hash_t, c_syscall_stub > m_syscalls;

		file_t load_ntdll();
	public:
		bool start();

		template <typename T>
		T get(hash_t hash) {
			return (T)(m_syscalls[hash]());
		}
	};
}