New function, DSO_pathbyaddr, to find pathname for loaded shared object
by an address within it. Tested on Linux, Solaris, IRIX, Tru64, Darwin, HP-UX, Win32, few BSD flavors...
This commit is contained in:
parent
b2d91a6913
commit
7ed876533a
@ -170,6 +170,9 @@ typedef struct dso_meth_st
|
|||||||
/* [De]Initialisation handlers. */
|
/* [De]Initialisation handlers. */
|
||||||
int (*init)(DSO *dso);
|
int (*init)(DSO *dso);
|
||||||
int (*finish)(DSO *dso);
|
int (*finish)(DSO *dso);
|
||||||
|
|
||||||
|
/* Return pathname of the module containing location */
|
||||||
|
int (*pathbyaddr)(void *addr,char *path,int sz);
|
||||||
} DSO_METHOD;
|
} DSO_METHOD;
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
@ -296,6 +299,17 @@ DSO_METHOD *DSO_METHOD_win32(void);
|
|||||||
/* If VMS is defined, use shared images. If not, return NULL. */
|
/* If VMS is defined, use shared images. If not, return NULL. */
|
||||||
DSO_METHOD *DSO_METHOD_vms(void);
|
DSO_METHOD *DSO_METHOD_vms(void);
|
||||||
|
|
||||||
|
/* This function writes null-terminated pathname of DSO module
|
||||||
|
* containing 'addr' into 'sz' large caller-provided 'path' and
|
||||||
|
* returns the number of characters [including trailing zero]
|
||||||
|
* written to it. If 'sz' is 0 or negative, 'path' is ignored and
|
||||||
|
* required amount of charachers [including trailing zero] to
|
||||||
|
* accomodate pathname is returned. If 'addr' is NULL, then
|
||||||
|
* pathname of cryptolib itself is returned. Negative or zero
|
||||||
|
* return value denotes error.
|
||||||
|
*/
|
||||||
|
int DSO_pathbyaddr(void *addr,char *path,int sz);
|
||||||
|
|
||||||
/* BEGIN ERROR CODES */
|
/* BEGIN ERROR CODES */
|
||||||
/* The following lines are auto generated by the script mkerr.pl. Any changes
|
/* The following lines are auto generated by the script mkerr.pl. Any changes
|
||||||
* made after this point may be overwritten when the script is next run.
|
* made after this point may be overwritten when the script is next run.
|
||||||
@ -342,6 +356,7 @@ void ERR_load_DSO_strings(void);
|
|||||||
#define DSO_F_WIN32_NAME_CONVERTER 125
|
#define DSO_F_WIN32_NAME_CONVERTER 125
|
||||||
#define DSO_F_WIN32_SPLITTER 136
|
#define DSO_F_WIN32_SPLITTER 136
|
||||||
#define DSO_F_WIN32_UNLOAD 121
|
#define DSO_F_WIN32_UNLOAD 121
|
||||||
|
#define DSO_F_PATHBYADDR 137
|
||||||
|
|
||||||
/* Reason codes. */
|
/* Reason codes. */
|
||||||
#define DSO_R_CTRL_FAILED 100
|
#define DSO_R_CTRL_FAILED 100
|
||||||
|
@ -85,6 +85,7 @@ static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg);
|
|||||||
#endif
|
#endif
|
||||||
static char *dl_name_converter(DSO *dso, const char *filename);
|
static char *dl_name_converter(DSO *dso, const char *filename);
|
||||||
static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2);
|
static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2);
|
||||||
|
static int dl_pathbyaddr(void *addr,char *path,int sz);
|
||||||
|
|
||||||
static DSO_METHOD dso_meth_dl = {
|
static DSO_METHOD dso_meth_dl = {
|
||||||
"OpenSSL 'dl' shared library method",
|
"OpenSSL 'dl' shared library method",
|
||||||
@ -101,7 +102,8 @@ static DSO_METHOD dso_meth_dl = {
|
|||||||
dl_name_converter,
|
dl_name_converter,
|
||||||
dl_merger,
|
dl_merger,
|
||||||
NULL, /* init */
|
NULL, /* init */
|
||||||
NULL /* finish */
|
NULL, /* finish */
|
||||||
|
dl_pathbyaddr
|
||||||
};
|
};
|
||||||
|
|
||||||
DSO_METHOD *DSO_METHOD_dl(void)
|
DSO_METHOD *DSO_METHOD_dl(void)
|
||||||
@ -349,4 +351,27 @@ static char *dl_name_converter(DSO *dso, const char *filename)
|
|||||||
return(translated);
|
return(translated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dl_pathbyaddr(void *addr,char *path,int sz)
|
||||||
|
{
|
||||||
|
struct shl_descriptor inf;
|
||||||
|
int i,len;
|
||||||
|
|
||||||
|
if (addr == NULL) addr = dl_pathbyaddr;
|
||||||
|
|
||||||
|
for (i=-1;shl_get_r(i,&inf)==0;i++)
|
||||||
|
{
|
||||||
|
if (((size_t)addr >= inf.tstart && (size_t)addr < inf.tend) ||
|
||||||
|
((size_t)addr >= inf.dstart && (size_t)addr < inf.dend))
|
||||||
|
{
|
||||||
|
len = (int)strlen(inf.filename);
|
||||||
|
if (sz <= 0) return len+1;
|
||||||
|
if (len >= sz) len=sz-1;
|
||||||
|
memcpy(path,inf.filename,len);
|
||||||
|
path[len++] = 0;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
#endif /* DSO_DL */
|
#endif /* DSO_DL */
|
||||||
|
@ -68,6 +68,12 @@ DSO_METHOD *DSO_METHOD_dlfcn(void)
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
#ifdef HAVE_DLFCN_H
|
#ifdef HAVE_DLFCN_H
|
||||||
|
|
||||||
|
#ifdef __linux
|
||||||
|
# ifndef _GNU_SOURCE
|
||||||
|
# define _GNU_SOURCE /* make sure dladdr is declared */
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -87,6 +93,7 @@ static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg);
|
|||||||
static char *dlfcn_name_converter(DSO *dso, const char *filename);
|
static char *dlfcn_name_converter(DSO *dso, const char *filename);
|
||||||
static char *dlfcn_merger(DSO *dso, const char *filespec1,
|
static char *dlfcn_merger(DSO *dso, const char *filespec1,
|
||||||
const char *filespec2);
|
const char *filespec2);
|
||||||
|
static int dlfcn_pathbyaddr(void *addr,char *path,int sz);
|
||||||
|
|
||||||
static DSO_METHOD dso_meth_dlfcn = {
|
static DSO_METHOD dso_meth_dlfcn = {
|
||||||
"OpenSSL 'dlfcn' shared library method",
|
"OpenSSL 'dlfcn' shared library method",
|
||||||
@ -103,7 +110,8 @@ static DSO_METHOD dso_meth_dlfcn = {
|
|||||||
dlfcn_name_converter,
|
dlfcn_name_converter,
|
||||||
dlfcn_merger,
|
dlfcn_merger,
|
||||||
NULL, /* init */
|
NULL, /* init */
|
||||||
NULL /* finish */
|
NULL, /* finish */
|
||||||
|
dlfcn_pathbyaddr
|
||||||
};
|
};
|
||||||
|
|
||||||
DSO_METHOD *DSO_METHOD_dlfcn(void)
|
DSO_METHOD *DSO_METHOD_dlfcn(void)
|
||||||
@ -366,4 +374,63 @@ static char *dlfcn_name_converter(DSO *dso, const char *filename)
|
|||||||
return(translated);
|
return(translated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __sgi
|
||||||
|
#if 0
|
||||||
|
This is a quote from IRIX manual for dladdr(3c):
|
||||||
|
|
||||||
|
<dlfcn.h> does not contain a prototype for dladdr or definition of
|
||||||
|
Dl_info. The #include <dlfcn.h> in the SYNOPSIS line is traditional,
|
||||||
|
but contains no dladdr prototype and no IRIX library contains an
|
||||||
|
implementation. Write your own declaration based on the code below.
|
||||||
|
|
||||||
|
The following code is dependent on internal interfaces that are not
|
||||||
|
part of the IRIX compatibility guarantee; however, there is no future
|
||||||
|
intention to change this interface, so on a practical level, the code
|
||||||
|
below is safe to use on IRIX.
|
||||||
|
#endif
|
||||||
|
#include <rld_interface.h>
|
||||||
|
#ifndef _RLD_INTERFACE_DLFCN_H_DLADDR
|
||||||
|
#define _RLD_INTERFACE_DLFCN_H_DLADDR
|
||||||
|
typedef struct Dl_info {
|
||||||
|
const char * dli_fname;
|
||||||
|
void * dli_fbase;
|
||||||
|
const char * dli_sname;
|
||||||
|
void * dli_saddr;
|
||||||
|
int dli_version;
|
||||||
|
int dli_reserved1;
|
||||||
|
long dli_reserved[4];
|
||||||
|
} Dl_info;
|
||||||
|
#else
|
||||||
|
typedef struct Dl_info Dl_info;
|
||||||
|
#endif
|
||||||
|
#define _RLD_DLADDR 14
|
||||||
|
|
||||||
|
static int dladdr(void *address, Dl_info *dl)
|
||||||
|
{
|
||||||
|
void *v;
|
||||||
|
v = _rld_new_interface(_RLD_DLADDR,address,dl);
|
||||||
|
return (int)v;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int dlfcn_pathbyaddr(void *addr,char *path,int sz)
|
||||||
|
{
|
||||||
|
Dl_info dli;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (addr == NULL) addr = dlfcn_pathbyaddr;
|
||||||
|
|
||||||
|
if (dladdr(addr,&dli))
|
||||||
|
{
|
||||||
|
len = (int)strlen(dli.dli_fname);
|
||||||
|
if (sz <= 0) return len+1;
|
||||||
|
if (len >= sz) len=sz-1;
|
||||||
|
memcpy(path,dli.dli_fname,len);
|
||||||
|
path[len++]=0;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
ERR_add_error_data(4, "dlfcn_pathbyaddr(): ", dlerror());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
#endif /* DSO_DLFCN */
|
#endif /* DSO_DLFCN */
|
||||||
|
@ -107,6 +107,7 @@ static ERR_STRING_DATA DSO_str_functs[]=
|
|||||||
{ERR_FUNC(DSO_F_WIN32_NAME_CONVERTER), "WIN32_NAME_CONVERTER"},
|
{ERR_FUNC(DSO_F_WIN32_NAME_CONVERTER), "WIN32_NAME_CONVERTER"},
|
||||||
{ERR_FUNC(DSO_F_WIN32_SPLITTER), "WIN32_SPLITTER"},
|
{ERR_FUNC(DSO_F_WIN32_SPLITTER), "WIN32_SPLITTER"},
|
||||||
{ERR_FUNC(DSO_F_WIN32_UNLOAD), "WIN32_UNLOAD"},
|
{ERR_FUNC(DSO_F_WIN32_UNLOAD), "WIN32_UNLOAD"},
|
||||||
|
{ERR_FUNC(DSO_F_PATHBYADDR), "DSO_pathbyaddr"},
|
||||||
{0,NULL}
|
{0,NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -464,3 +464,15 @@ const char *DSO_get_loaded_filename(DSO *dso)
|
|||||||
}
|
}
|
||||||
return(dso->loaded_filename);
|
return(dso->loaded_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DSO_pathbyaddr(void *addr,char *path,int sz)
|
||||||
|
{
|
||||||
|
DSO_METHOD *meth = default_DSO_meth;
|
||||||
|
if (meth == NULL) meth = DSO_METHOD_openssl();
|
||||||
|
if (meth->pathbyaddr == NULL)
|
||||||
|
{
|
||||||
|
DSOerr(DSO_F_PATHBYADDR,DSO_R_UNSUPPORTED);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
return (*meth->pathbyaddr)(addr,path,sz);
|
||||||
|
}
|
||||||
|
@ -85,6 +85,7 @@ static long win32_ctrl(DSO *dso, int cmd, long larg, void *parg);
|
|||||||
static char *win32_name_converter(DSO *dso, const char *filename);
|
static char *win32_name_converter(DSO *dso, const char *filename);
|
||||||
static char *win32_merger(DSO *dso, const char *filespec1,
|
static char *win32_merger(DSO *dso, const char *filespec1,
|
||||||
const char *filespec2);
|
const char *filespec2);
|
||||||
|
static int win32_pathbyaddr(void *addr,char *path,int sz);
|
||||||
|
|
||||||
static const char *openssl_strnchr(const char *string, int c, size_t len);
|
static const char *openssl_strnchr(const char *string, int c, size_t len);
|
||||||
|
|
||||||
@ -103,7 +104,8 @@ static DSO_METHOD dso_meth_win32 = {
|
|||||||
win32_name_converter,
|
win32_name_converter,
|
||||||
win32_merger,
|
win32_merger,
|
||||||
NULL, /* init */
|
NULL, /* init */
|
||||||
NULL /* finish */
|
NULL, /* finish */
|
||||||
|
win32_pathbyaddr
|
||||||
};
|
};
|
||||||
|
|
||||||
DSO_METHOD *DSO_METHOD_win32(void)
|
DSO_METHOD *DSO_METHOD_win32(void)
|
||||||
@ -127,7 +129,7 @@ static int win32_load(DSO *dso)
|
|||||||
DSOerr(DSO_F_WIN32_LOAD,DSO_R_NO_FILENAME);
|
DSOerr(DSO_F_WIN32_LOAD,DSO_R_NO_FILENAME);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
h = LoadLibrary(filename);
|
h = LoadLibraryA(filename);
|
||||||
if(h == NULL)
|
if(h == NULL)
|
||||||
{
|
{
|
||||||
DSOerr(DSO_F_WIN32_LOAD,DSO_R_LOAD_FAILED);
|
DSOerr(DSO_F_WIN32_LOAD,DSO_R_LOAD_FAILED);
|
||||||
@ -593,5 +595,122 @@ static const char *openssl_strnchr(const char *string, int c, size_t len)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <tlhelp32.h>
|
||||||
|
#ifdef _WIN32_WCE
|
||||||
|
# if _WIN32_WCE < 300
|
||||||
|
static FARPROC GetProcAddressA(HMODULE hModule,LPCSTR lpProcName)
|
||||||
|
{
|
||||||
|
WCHAR lpProcNameW[64];
|
||||||
|
int i;
|
||||||
|
|
||||||
#endif /* OPENSSL_SYS_WIN32 */
|
for (i=0;lpProcName[i] && i<64;i++)
|
||||||
|
lpProcNameW[i] = (WCHAR)lpProcName[i];
|
||||||
|
if (i==64) return NULL;
|
||||||
|
lpProcNameW[i] = 0;
|
||||||
|
|
||||||
|
return GetProcAddressW(hModule,lpProcNameW);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
# undef GetProcAddress
|
||||||
|
# define GetProcAddress GetProcAddressA
|
||||||
|
# define DLLNAME "TOOLHELP.DLL"
|
||||||
|
#else
|
||||||
|
# ifdef MODULEENTRY32
|
||||||
|
# undef MODULEENTRY32 /* unmask the ASCII version! */
|
||||||
|
# endif
|
||||||
|
# define DLLNAME "KERNEL32.DLL"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef HANDLE (WINAPI *CREATETOOLHELP32SNAPSHOT)(DWORD, DWORD);
|
||||||
|
typedef BOOL (WINAPI *CLOSETOOLHELP32SNAPSHOT)(HANDLE);
|
||||||
|
typedef BOOL (WINAPI *MODULE32)(HANDLE, MODULEENTRY32 *);
|
||||||
|
|
||||||
|
static int win32_pathbyaddr(void *addr,char *path,int sz)
|
||||||
|
{
|
||||||
|
HMODULE dll;
|
||||||
|
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
|
||||||
|
MODULEENTRY32 me32;
|
||||||
|
CREATETOOLHELP32SNAPSHOT create_snap;
|
||||||
|
CLOSETOOLHELP32SNAPSHOT close_snap;
|
||||||
|
MODULE32 module_first, module_next;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (addr == NULL) addr = win32_pathbyaddr;
|
||||||
|
|
||||||
|
dll = LoadLibrary(TEXT(DLLNAME));
|
||||||
|
if (dll == NULL)
|
||||||
|
{
|
||||||
|
DSOerr(DSO_F_PATHBYADDR,DSO_R_UNSUPPORTED);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
create_snap = (CREATETOOLHELP32SNAPSHOT)
|
||||||
|
GetProcAddress(dll,"CreateToolhelp32Snapshot");
|
||||||
|
if (create_snap == NULL)
|
||||||
|
{
|
||||||
|
DSOerr(DSO_F_PATHBYADDR,DSO_R_UNSUPPORTED);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* We take the rest for granted... */
|
||||||
|
#ifdef _WIN32_WCE
|
||||||
|
close_snap = (CLOSETOOLHELP32SNAPSHOT)
|
||||||
|
GetProcAddress(dll,"CloseToolhelp32Snapshot");
|
||||||
|
#else
|
||||||
|
close_snap = (CLOSETOOLHELP32SNAPSHOT)CloseHandle;
|
||||||
|
#endif
|
||||||
|
module_first = (MODULE32)GetProcAddress(dll,"Module32First");
|
||||||
|
module_next = (MODULE32)GetProcAddress(dll,"Module32Next");
|
||||||
|
|
||||||
|
hModuleSnap = (*create_snap)(TH32CS_SNAPMODULE,0);
|
||||||
|
if( hModuleSnap == INVALID_HANDLE_VALUE )
|
||||||
|
{
|
||||||
|
FreeLibrary(dll);
|
||||||
|
DSOerr(DSO_F_PATHBYADDR,DSO_R_UNSUPPORTED);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
me32.dwSize = sizeof(me32);
|
||||||
|
|
||||||
|
if(!(*module_first)(hModuleSnap,&me32))
|
||||||
|
{
|
||||||
|
(*close_snap)(hModuleSnap);
|
||||||
|
FreeLibrary(dll);
|
||||||
|
DSOerr(DSO_F_PATHBYADDR,DSO_R_FAILURE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
if ((BYTE *)addr >= me32.modBaseAddr &&
|
||||||
|
(BYTE *)addr < me32.modBaseAddr+me32.modBaseSize)
|
||||||
|
{
|
||||||
|
(*close_snap)(hModuleSnap);
|
||||||
|
FreeLibrary(dll);
|
||||||
|
#ifdef _WIN32_WCE
|
||||||
|
# if _WIN32_WCE >= 101
|
||||||
|
return WideCharToMultiByte(CP_ACP,0,me32.szExePath,-1,
|
||||||
|
path,sz,NULL,NULL);
|
||||||
|
# else
|
||||||
|
len = (int)wcslen(me32.szExePath);
|
||||||
|
if (sz <= 0) return len+1;
|
||||||
|
if (len >= sz) len=sz-1;
|
||||||
|
for(i=0;i<len;i++)
|
||||||
|
path[i] = (char)me32.szExePath[i];
|
||||||
|
path[len++] = 0;
|
||||||
|
return len;
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
len = (int)strlen(me32.szExePath);
|
||||||
|
if (sz <= 0) return len+1;
|
||||||
|
if (len >= sz) len=sz-1;
|
||||||
|
memcpy(path,me32.szExePath,len);
|
||||||
|
path[len++] = 0;
|
||||||
|
return len;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} while((*module_next)(hModuleSnap, &me32));
|
||||||
|
|
||||||
|
(*close_snap)(hModuleSnap);
|
||||||
|
FreeLibrary(dll);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* DSO_WIN32 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user