summaryrefslogtreecommitdiff
path: root/loader/server/manual_map.hpp
blob: 74313530a829026ca3a762456a5fd9a9caa6e31f (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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#pragma once

// TODO: get stripped down version of what we need and shove it in here
#include <windows.h>

#include <cstdint>
#include <cstdio>
#include <fstream>
#include <iterator>
#include <vector>

// here's the game plan:
// - client runs, waits for game to start and whatnot
// - we wait for serverbrowser.dll to load (if source game, we should have an option in the game struct to wait for module)
// - client walks peb of process, dumps exports and packs them into { fnv, addy }, sends to server
// - server sends module size, client allocates and replies back with module address
// - server resolves imports through { fnv, addy } that were networked to us
// - server fixes reloc
// - we send back addy, then section data to client
// - server packs shellcode with data from client, sends to client
// - client runs shellcode, we're injected
namespace inject {
	// used as generic wrapper for pe, tells client how much to allocate, etc.
	class c_pe_file {
	protected:
		std::vector< uint8_t > m_file;
	public:
		c_pe_file() = default;
		c_pe_file(const char *file);
		bool valid();
		uint8_t *data();
		size_t size() const;
	};

	// used for fixing imports
	struct process_export_t {
		uint32_t m_hash;
		uint32_t m_address;
	};

	// used for writing memory in client
	struct memory_page_t {
		uint32_t m_address;
		uint32_t m_protection;
	};

	// container for sections
	using byte_array_t = std::vector<uint8_t>;
	using memory_section_t = std::pair<memory_page_t, byte_array_t>;

	// used as server wrapper for the manual mapper
	class c_mapper {
	protected:
		std::vector<process_export_t> m_exports;
		std::vector<memory_section_t> m_sections;

		c_pe_file m_pe;

	private:
		bool process_reloc(uint32_t remote_address);
		bool process_imports(uint32_t remote_address);

	public:
		c_mapper() = default;
		c_mapper(c_pe_file &pe_file);

		// returns size of module to allocate on client
		size_t initialise(std::vector<process_export_t> &exports);

		// handles reloc and fixing imports
		bool process_pe_file(uint32_t remote_address);

		// returns all sections
		std::vector<memory_section_t> get_pe_sections();
	};
}