diff options
| -rw-r--r-- | src/dlfcn.c | 64 |
1 files changed, 57 insertions, 7 deletions
diff --git a/src/dlfcn.c b/src/dlfcn.c index 4e4e10e..80bd119 100644 --- a/src/dlfcn.c +++ b/src/dlfcn.c | |||
| @@ -24,9 +24,6 @@ | |||
| 24 | * THE SOFTWARE. | 24 | * THE SOFTWARE. |
| 25 | */ | 25 | */ |
| 26 | 26 | ||
| 27 | #ifndef _WIN32_WINNT | ||
| 28 | #define _WIN32_WINNT 0x0501 | ||
| 29 | #endif | ||
| 30 | #ifdef _DEBUG | 27 | #ifdef _DEBUG |
| 31 | #define _CRTDBG_MAP_ALLOC | 28 | #define _CRTDBG_MAP_ALLOC |
| 32 | #include <stdlib.h> | 29 | #include <stdlib.h> |
| @@ -36,6 +33,14 @@ | |||
| 36 | #include <stdio.h> | 33 | #include <stdio.h> |
| 37 | #include <stdlib.h> | 34 | #include <stdlib.h> |
| 38 | 35 | ||
| 36 | /* Older SDK versions do not have these macros */ | ||
| 37 | #ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | ||
| 38 | #define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 0x4 | ||
| 39 | #endif | ||
| 40 | #ifndef GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | ||
| 41 | #define GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT 0x2 | ||
| 42 | #endif | ||
| 43 | |||
| 39 | #ifdef _MSC_VER | 44 | #ifdef _MSC_VER |
| 40 | /* https://docs.microsoft.com/en-us/cpp/intrinsics/returnaddress */ | 45 | /* https://docs.microsoft.com/en-us/cpp/intrinsics/returnaddress */ |
| 41 | #pragma intrinsic( _ReturnAddress ) | 46 | #pragma intrinsic( _ReturnAddress ) |
| @@ -196,6 +201,44 @@ static void save_err_ptr_str( const void *ptr, DWORD dwMessageId ) | |||
| 196 | save_err_str( ptr_buf, dwMessageId ); | 201 | save_err_str( ptr_buf, dwMessageId ); |
| 197 | } | 202 | } |
| 198 | 203 | ||
| 204 | static HMODULE MyGetModuleHandleFromAddress( void *addr ) | ||
| 205 | { | ||
| 206 | static BOOL (WINAPI *GetModuleHandleExAPtr)(DWORD, LPCSTR, HMODULE *) = NULL; | ||
| 207 | static BOOL failed = FALSE; | ||
| 208 | HMODULE kernel32; | ||
| 209 | HMODULE hModule; | ||
| 210 | MEMORY_BASIC_INFORMATION info; | ||
| 211 | SIZE_T sLen; | ||
| 212 | |||
| 213 | if( !failed && GetModuleHandleExAPtr == NULL ) | ||
| 214 | { | ||
| 215 | kernel32 = GetModuleHandleA( "Kernel32.dll" ); | ||
| 216 | if( kernel32 != NULL ) | ||
| 217 | GetModuleHandleExAPtr = (BOOL (WINAPI *)(DWORD, LPCSTR, HMODULE *)) GetProcAddress( kernel32, "GetModuleHandleExA" ); | ||
| 218 | if( GetModuleHandleExAPtr == NULL ) | ||
| 219 | failed = TRUE; | ||
| 220 | } | ||
| 221 | |||
| 222 | if( !failed ) | ||
| 223 | { | ||
| 224 | /* If GetModuleHandleExA is available use it with GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS */ | ||
| 225 | if( !GetModuleHandleExAPtr( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCSTR) addr, &hModule ) ) | ||
| 226 | return NULL; | ||
| 227 | } | ||
| 228 | else | ||
| 229 | { | ||
| 230 | /* To get HMODULE from address use undocumented hack from https://stackoverflow.com/a/2396380 | ||
| 231 | * The HMODULE of a DLL is the same value as the module's base address. | ||
| 232 | */ | ||
| 233 | sLen = VirtualQuery( addr, &info, sizeof( info ) ); | ||
| 234 | if( sLen != sizeof( info ) ) | ||
| 235 | return NULL; | ||
| 236 | hModule = (HMODULE) info.AllocationBase; | ||
| 237 | } | ||
| 238 | |||
| 239 | return hModule; | ||
| 240 | } | ||
| 241 | |||
| 199 | /* Load Psapi.dll at runtime, this avoids linking caveat */ | 242 | /* Load Psapi.dll at runtime, this avoids linking caveat */ |
| 200 | static BOOL MyEnumProcessModules( HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded ) | 243 | static BOOL MyEnumProcessModules( HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded ) |
| 201 | { | 244 | { |
| @@ -402,9 +445,12 @@ void *dlsym( void *handle, const char *name ) | |||
| 402 | * The next object is the one found upon the application of a load | 445 | * The next object is the one found upon the application of a load |
| 403 | * order symbol resolution algorithm. To get caller function of dlsym() | 446 | * order symbol resolution algorithm. To get caller function of dlsym() |
| 404 | * use _ReturnAddress() intrinsic. To get HMODULE of caller function | 447 | * use _ReturnAddress() intrinsic. To get HMODULE of caller function |
| 405 | * use standard GetModuleHandleExA() function. | 448 | * use MyGetModuleHandleFromAddress() which calls either standard |
| 449 | * GetModuleHandleExA() function or hack via VirtualQuery(). | ||
| 406 | */ | 450 | */ |
| 407 | if( !GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCSTR) _ReturnAddress( ), &hCaller ) ) | 451 | hCaller = MyGetModuleHandleFromAddress( _ReturnAddress( ) ); |
| 452 | |||
| 453 | if( hCaller == NULL ) | ||
| 408 | { | 454 | { |
| 409 | dwMessageId = ERROR_INVALID_PARAMETER; | 455 | dwMessageId = ERROR_INVALID_PARAMETER; |
| 410 | goto end; | 456 | goto end; |
| @@ -638,7 +684,9 @@ static BOOL fill_info( void *addr, Dl_info *info ) | |||
| 638 | void *funcAddress = NULL; | 684 | void *funcAddress = NULL; |
| 639 | 685 | ||
| 640 | /* Get module of the specified address */ | 686 | /* Get module of the specified address */ |
| 641 | if( !GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, addr, &hModule ) || hModule == NULL ) | 687 | hModule = MyGetModuleHandleFromAddress( addr ); |
| 688 | |||
| 689 | if( hModule == NULL ) | ||
| 642 | return FALSE; | 690 | return FALSE; |
| 643 | 691 | ||
| 644 | dwSize = GetModuleFileNameA( hModule, module_filename, sizeof( module_filename ) ); | 692 | dwSize = GetModuleFileNameA( hModule, module_filename, sizeof( module_filename ) ); |
| @@ -676,7 +724,9 @@ int dladdr( void *addr, Dl_info *info ) | |||
| 676 | HMODULE hModule; | 724 | HMODULE hModule; |
| 677 | 725 | ||
| 678 | /* Get module of the import thunk address */ | 726 | /* Get module of the import thunk address */ |
| 679 | if( !GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, addr, &hModule ) || hModule == NULL ) | 727 | hModule = MyGetModuleHandleFromAddress( addr ); |
| 728 | |||
| 729 | if( hModule == NULL ) | ||
| 680 | return 0; | 730 | return 0; |
| 681 | 731 | ||
| 682 | if( !get_image_section( hModule, IMAGE_DIRECTORY_ENTRY_IAT, &iat, &iatSize ) ) | 732 | if( !get_image_section( hModule, IMAGE_DIRECTORY_ENTRY_IAT, &iat, &iatSize ) ) |
