aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dlfcn.c64
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
204static 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 */
200static BOOL MyEnumProcessModules( HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded ) 243static 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 ) )