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{ };
}
}
}
|