diff options
Diffstat (limited to 'loader/winapi.hpp')
| -rw-r--r-- | loader/winapi.hpp | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/loader/winapi.hpp b/loader/winapi.hpp new file mode 100644 index 0000000..72fdbfe --- /dev/null +++ b/loader/winapi.hpp @@ -0,0 +1,64 @@ +#pragma once
+#include <Windows.h>
+#include "util.hpp"
+
+namespace winapi
+{
+ static uintptr_t get_procaddr_ex( HANDLE process, HMODULE mod, const char* proc ) {
+ IMAGE_DOS_HEADER dos_hdr;
+ IMAGE_NT_HEADERS nt_hdrs;
+ IMAGE_EXPORT_DIRECTORY export_dir;
+ uintptr_t export_addr;
+ char export_name[ 64 ];
+ uintptr_t* names;
+ uintptr_t* funcs;
+ uint16_t* ords;
+ uintptr_t ret{ };
+
+ ReadProcessMemory( process, mod, &dos_hdr, sizeof( dos_hdr ), 0 );
+ ReadProcessMemory( process, ( void* )( uintptr_t( mod ) + dos_hdr.e_lfanew ),
+ &nt_hdrs, sizeof( nt_hdrs ), nullptr );
+
+ export_addr = nt_hdrs.OptionalHeader.DataDirectory[ 0 ].VirtualAddress;
+ ReadProcessMemory( process, ( void* )( uintptr_t( mod ) + export_addr ),
+ &export_dir, sizeof( export_dir ), nullptr );
+
+ if( !export_dir.NumberOfFunctions )
+ return uintptr_t{ };
+
+ funcs = ( uintptr_t* )( malloc( sizeof( uintptr_t ) * export_dir.AddressOfFunctions ) );
+ names = ( uintptr_t* )( malloc( sizeof( uintptr_t ) * export_dir.NumberOfNames ) );
+ ords = ( uint16_t* ) ( malloc( sizeof( uint16_t ) * export_dir.NumberOfNames ) );
+
+ ReadProcessMemory( process, ( void* )( uintptr_t( mod ) + export_dir.AddressOfFunctions ),
+ funcs, sizeof( uintptr_t ) * export_dir.NumberOfFunctions, nullptr );
+ ReadProcessMemory( process, ( void* )( uintptr_t( mod ) + export_dir.AddressOfNames ),
+ names, sizeof( uintptr_t ) * export_dir.NumberOfNames, nullptr );
+ ReadProcessMemory( process, ( void* )( uintptr_t( mod ) + export_dir.AddressOfNameOrdinals ),
+ ords, sizeof( uint16_t ) * export_dir.NumberOfNames, nullptr );
+
+ auto read_str = [ &process ]( char* buf, size_t size, uintptr_t addr ) {
+ for( size_t i{ }; i < size; ++i ) {
+ char _c;
+ ReadProcessMemory( process, ( void* )( addr + i ), &_c, 1, 0 );
+ buf[ i ] = _c;
+ if( !_c ) break;
+ }
+
+ buf[ size - 1 ] = 0;
+ };
+
+ for( size_t i{ }; i < export_dir.NumberOfNames; ++i ) {
+ read_str( export_name, 64, uintptr_t( mod ) + names[ i ] );
+
+ if( !strcmp( export_name, proc ) )
+ ret = uintptr_t( mod ) + funcs[ ords[ i ] ];
+ }
+
+ ::free( funcs );
+ ::free( names );
+ ::free( ords );
+
+ return ret;
+ }
+}
\ No newline at end of file |
