summaryrefslogtreecommitdiff
path: root/legacy/loader/iface.hpp
blob: 49a4dc5abb72659057897502f43acadab3d27644 (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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#pragma once
#include <vector>
#include <TlHelp32.h>
#include "winapi.hpp"
#include "util.hpp"

namespace iface
{
	class container {
	private:
		struct reg {
			char	  m_key;
			uintptr_t m_ptr;
			uintptr_t m_module;
			char	  m_module_name[ 64 ];
			char	  m_name[ 64 ];
		};
		
		std::vector< reg > m_regs;
	public:
		void emplace_reg( uintptr_t ptr, uintptr_t module_, const char* name, const char* module_name, char name_key ) {
			reg new_reg{ };
			new_reg.m_ptr = ptr;
			new_reg.m_module = module_;

			memcpy( new_reg.m_name, name, 64 );
			memcpy( new_reg.m_module_name, module_name, 64 );

			new_reg.m_key = name_key;

			m_regs.emplace_back( new_reg );
		}

		auto& get_regs( ) {
			return m_regs;
		}
	};

	struct iface_reg_t {
		void*		m_create_fn;
		const char* m_name;
		uintptr_t	m_next;

		inline auto follow( HANDLE process ) {
			iface_reg_t buf;
			ReadProcessMemory( process, ( void* )( m_next ), &buf, sizeof( buf ), nullptr );
			return buf;
		}
	};

	class manager {
		HANDLE&		m_process;
		container	m_container;

		inline auto is_createinterface_export( uintptr_t export_ ) {
			uint8_t buf[ 12 ];

			ReadProcessMemory( m_process, ( void* )( export_ ), buf, sizeof( buf ), nullptr );

			return( buf[ 0 ] == 0x55
				&& buf[ 4 ] == 0xe9
				&& buf[ 9 ] == 0xcc
				&& buf[ 10 ] == 0xcc );
		}

		inline auto is_createinterface_fn( uintptr_t fn_ ) {
			uint8_t buf[ 12 ];

			ReadProcessMemory( m_process, ( void* )( fn_ ), buf, sizeof( buf ), nullptr );

			return( buf[ 0 ] == 0x55
				&& buf[ 4 ] == 0x8b
				&& buf[ 10 ] == 0x57 );
		}

		inline auto follow_createinterface_export( uintptr_t export_ ) {
			uintptr_t jmp = export_ + 0x4;

			uintptr_t rel;
			ReadProcessMemory( m_process, ( void* )( jmp + 0x1 ), &rel, sizeof( rel ), nullptr );

			return jmp + rel + 0x5;
		}

		inline auto find_list_ptr( uintptr_t createinterface ) {
			uintptr_t
				first = createinterface + 0x6,
				second,
				third;

			ReadProcessMemory( m_process, ( void* )( first ), &second, sizeof( second ), nullptr );
			ReadProcessMemory( m_process, ( void* )( second ), &third, sizeof( third ), nullptr );

			return third;
		}

		inline auto get_list( uintptr_t ptr ) {
			iface_reg_t reg;
			ReadProcessMemory( m_process, ( void* )( ptr ), &reg, sizeof( reg ), nullptr );

			return reg;
		}

	public:
		manager( HANDLE& process ) : m_process( process ) { };

		inline void dump_from_module( HMODULE mod, const char* module_name ) {
			auto read_str = [ this ]( char* buf, size_t size, uintptr_t addr ) {
				for( size_t i{ }; i < size; ++i ) {
					char _c;
					ReadProcessMemory( m_process, ( void* )( addr + i ), &_c, 1, 0 );
					buf[ i ] = _c;
					if( !_c ) break;
				}

				buf[ size - 1 ] = 0;
			};

			auto enc_str = [ ]( char* buf, size_t size, char key ) {
				for( size_t i{ }; i < size; ++i ) {
					buf[ i ] ^= key;
				}
			};
			
			auto create_interface = winapi::get_procaddr_ex( m_process, mod, xors( "CreateInterface" ) );
			if( !create_interface || !is_createinterface_export( create_interface ) )
				return;

			auto fn = follow_createinterface_export( create_interface );
			if( !is_createinterface_fn( fn ) )
				return;

			auto list_ptr = find_list_ptr( fn );
			auto list = get_list( list_ptr );

			char name_buf[ 64 ];
			char module_buf[ 64 ];

			do {
				read_str( name_buf, 64, ( uintptr_t )( list.m_name ) );
				strcpy( module_buf, module_name );

				srand( list_ptr );
				auto key = rand( ) & 0xff;

				enc_str( name_buf, 64, key );
				enc_str( module_buf, 64, key );

				uintptr_t iface_ptr = 0;
				ReadProcessMemory( m_process, ( void* )( ( uintptr_t )list.m_create_fn + 1 ), 
					&iface_ptr, sizeof( uintptr_t ), nullptr ); 

				m_container.emplace_reg( iface_ptr, uintptr_t( mod ), name_buf, module_name, key );

				list_ptr = list.m_next;
				list	 = get_list( list_ptr );
			} while( list_ptr && name_buf[ 0 ] && list_ptr != list.m_next );
		}

		void dump_all_modules( int pid ) {
			HANDLE			t32_snapshot;
			MODULEENTRY32	entry;

			t32_snapshot = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, pid );
			entry.dwSize = sizeof( MODULEENTRY32 );

			for( Module32First( t32_snapshot, &entry );
				!!Module32Next( t32_snapshot, &entry ); ) {

				//why valve troll me
				if( strstr( entry.szModule, xors( "valve_avi" ) ) )
					continue;

				dump_from_module( ( HMODULE )( entry.modBaseAddr ), entry.szModule );
			}
		}

		auto count( ) {
			return m_container.get_regs( ).size( );
		}

		auto& get( ) {
			return m_container;
		}

		uintptr_t write_to_process( ) {
			size_t count_ = count( );
			size_t size = count_ * 137 + sizeof( size_t );

			auto allocation = VirtualAllocEx( m_process, 0, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE );
			WriteProcessMemory( m_process, allocation, &count_, sizeof( count_ ), nullptr );
			WriteProcessMemory( m_process, ( void* )( uintptr_t( allocation ) + 0x4 ), 
				get( ).get_regs( ).data( ), size, nullptr );

			return ( uintptr_t )( allocation );
		}
	};
}