summaryrefslogtreecommitdiff
path: root/injector/winapi.h
blob: 6fceeb767d76e9c24281f70cad4b8c4aa09673f9 (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
#pragma once
#include <intrin.h>

#include "pe.h"
#include "util.h"

namespace winapi 
{
	auto get_peb( ) {
		return ( nt::_PEB* )( __readfsdword( 0x30 ) );
	}

	namespace k32 {
		__declspec( noinline ) static void* get_module_handle( const wchar_t* module_ ) {
			auto peb = get_peb( );
			auto ldr = peb->Ldr;
			
			auto root = &ldr->InMemoryOrderModuleList;

			for( auto mod = root->Flink; mod != root; mod = mod->Flink ) {
				nt::LDR_DATA_TABLE_ENTRY*	data_table;
				void*						module_base;
				wchar_t*					module_name;

				data_table = reinterpret_cast< decltype( data_table ) >( mod );
				module_base = reinterpret_cast< void* >( ( ( void** )( uintptr_t( data_table ) + 0x10 ) )[ 0 ] );

				module_name = ( wchar_t* )_alloca( ( data_table->FullDllName.Length + 1 ) * 2 );
				util::memcpy( module_name, data_table->FullDllName.Buffer, data_table->FullDllName.Length * 2 );
				module_name[ data_table->FullDllName.Length ] = L'0';

				if( util::wstrcmp( module_name, module_ ) ) {
					return module_base;
				}
			}

			return false;
		}

		__declspec( noinline ) uintptr_t get_proc_address( void* module_, const char* proc_name ) {
			nt::IMAGE_DOS_HEADER*		dos_header;
			nt::IMAGE_NT_HEADERS*		nt_headers;
			uintptr_t					export_address;
			nt::IMAGE_EXPORT_DIRECTORY*	export_dir;
			const char*					export_name;
			uintptr_t*					names;
			uintptr_t*					funcs;
			uint16_t*					ords;
			uint32_t					export_hash;

			dos_header = reinterpret_cast< decltype( dos_header ) >( uintptr_t( module_ ) );
			nt_headers = reinterpret_cast< decltype( nt_headers ) >( uintptr_t( module_ ) + dos_header->e_lfanew );

			//find addresses of functions from nt headers
			export_address = nt_headers->OptionalHeader.DataDirectory[ 0 ].VirtualAddress;
			export_dir = reinterpret_cast< decltype( export_dir ) >( uintptr_t( module_ ) + export_address );

			if( !export_dir->NumberOfFunctions )
				return uintptr_t{ };

			names = reinterpret_cast< uintptr_t* >( uintptr_t( module_ ) + export_dir->AddressOfNames );
			funcs = reinterpret_cast< uintptr_t* >( uintptr_t( module_ ) + export_dir->AddressOfFunctions );

			ords = reinterpret_cast< uint16_t* >( uintptr_t( module_ ) + export_dir->AddressOfNameOrdinals );

			if( names && funcs && ords ) {
				//iterate the exports
				for( size_t i{ }; i < export_dir->NumberOfNames; ++i ) {
					export_name = reinterpret_cast< const char* >( uintptr_t( module_ ) + names[ i ] );
					if( util::strcmp( export_name, proc_name ) ) {
						return uintptr_t( module_ ) + funcs[ ords[ i ] ];
					}
				}
			}

			while( 1 ) { }

			return uintptr_t{ };
		}
	}
}