2010-03-11 22:16:41 -08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif /* HAVE_CONFIG_H */
|
|
|
|
|
2008-02-27 13:01:30 -08:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
2010-03-11 22:16:41 -08:00
|
|
|
#if defined(__MINGW32CE__) || defined(_MSC_VER)
|
2008-03-05 01:19:38 -08:00
|
|
|
# include <limits.h>
|
2010-03-11 22:16:41 -08:00
|
|
|
#endif /* __MINGW32CE__ || _MSC_VER */
|
2008-03-05 01:19:38 -08:00
|
|
|
|
2008-04-26 09:27:46 -07:00
|
|
|
#include "../Evil.h"
|
|
|
|
|
|
|
|
#include "dlfcn.h"
|
|
|
|
|
2008-02-27 13:01:30 -08:00
|
|
|
|
|
|
|
static char *dl_err = NULL;
|
|
|
|
static int dl_err_viewed = 0;
|
|
|
|
|
|
|
|
static void
|
|
|
|
get_last_error(char *desc)
|
|
|
|
{
|
2008-06-08 14:39:49 -07:00
|
|
|
char *str;
|
2009-08-27 01:19:06 -07:00
|
|
|
size_t l1;
|
|
|
|
size_t l2;
|
2008-02-27 13:01:30 -08:00
|
|
|
|
2008-06-08 14:39:49 -07:00
|
|
|
str = evil_last_error_get();
|
2008-02-27 13:01:30 -08:00
|
|
|
|
|
|
|
l1 = strlen(desc);
|
2008-06-08 14:39:49 -07:00
|
|
|
l2 = strlen(str);
|
2008-02-27 13:01:30 -08:00
|
|
|
|
|
|
|
if (dl_err)
|
|
|
|
free(dl_err);
|
|
|
|
|
|
|
|
dl_err = (char *)malloc(sizeof(char) * (l1 + l2 + 1));
|
|
|
|
if (!dl_err)
|
|
|
|
dl_err = strdup("not enough resource");
|
|
|
|
else
|
|
|
|
{
|
|
|
|
memcpy(dl_err, desc, l1);
|
2008-06-08 14:39:49 -07:00
|
|
|
memcpy(dl_err + l1, str, l2);
|
2008-02-27 13:01:30 -08:00
|
|
|
dl_err[l1 + l2] = '\0';
|
|
|
|
}
|
2008-06-08 14:39:49 -07:00
|
|
|
free(str);
|
2008-02-27 13:01:30 -08:00
|
|
|
dl_err_viewed = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void *
|
|
|
|
dlopen(const char* path, int mode __UNUSED__)
|
|
|
|
{
|
|
|
|
HMODULE module = NULL;
|
|
|
|
|
|
|
|
if (!path)
|
|
|
|
{
|
|
|
|
module = GetModuleHandle(NULL);
|
|
|
|
if (!module)
|
|
|
|
get_last_error("GetModuleHandle returned: ");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-08-27 01:19:06 -07:00
|
|
|
char *new_path;
|
|
|
|
size_t l;
|
|
|
|
unsigned int i;
|
2008-02-27 13:01:30 -08:00
|
|
|
|
|
|
|
/* according to MSDN, we must change the slash to backslash */
|
|
|
|
l = strlen(path);
|
|
|
|
new_path = (char *)malloc(sizeof(char) * (l + 1));
|
|
|
|
if (!new_path)
|
|
|
|
{
|
|
|
|
if (dl_err)
|
|
|
|
free(dl_err);
|
|
|
|
dl_err = strdup("not enough resource");
|
|
|
|
dl_err_viewed = 0;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
for (i = 0; i <= l; i++)
|
|
|
|
{
|
|
|
|
if (path[i] == '/')
|
|
|
|
new_path[i] = '\\';
|
|
|
|
else
|
|
|
|
new_path[i] = path[i];
|
|
|
|
}
|
2008-06-08 14:39:49 -07:00
|
|
|
#ifdef UNICODE
|
2008-02-27 13:01:30 -08:00
|
|
|
{
|
|
|
|
wchar_t *wpath;
|
|
|
|
|
2008-04-26 09:27:46 -07:00
|
|
|
wpath = evil_char_to_wchar(new_path);
|
2008-03-13 10:46:53 -07:00
|
|
|
module = LoadLibrary(wpath);
|
2008-02-27 13:01:30 -08:00
|
|
|
free(wpath);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
module = LoadLibraryEx(new_path, NULL,
|
|
|
|
LOAD_WITH_ALTERED_SEARCH_PATH);
|
2008-06-08 14:39:49 -07:00
|
|
|
#endif /* ! UNICODE */
|
2008-02-27 13:01:30 -08:00
|
|
|
if (!module)
|
|
|
|
get_last_error("LoadLibraryEx returned: ");
|
|
|
|
|
|
|
|
free(new_path);
|
|
|
|
}
|
|
|
|
|
|
|
|
return module;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
dlclose(void* handle)
|
|
|
|
{
|
|
|
|
if (FreeLibrary(handle))
|
|
|
|
return 0;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
get_last_error("FreeLibrary returned: ");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void *
|
|
|
|
dlsym(void *handle, const char *symbol)
|
|
|
|
{
|
|
|
|
FARPROC fp;
|
|
|
|
|
2008-06-08 14:39:49 -07:00
|
|
|
#ifdef UNICODE
|
2008-02-27 13:01:30 -08:00
|
|
|
{
|
|
|
|
wchar_t *wsymbol;
|
|
|
|
|
2008-04-26 09:27:46 -07:00
|
|
|
wsymbol = evil_char_to_wchar(symbol);
|
2008-02-27 13:01:30 -08:00
|
|
|
fp = GetProcAddress(handle, wsymbol);
|
|
|
|
free(wsymbol);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
fp = GetProcAddress(handle, symbol);
|
2008-06-08 14:39:49 -07:00
|
|
|
#endif /* ! UNICODE */
|
2008-02-27 13:01:30 -08:00
|
|
|
if (!fp)
|
|
|
|
get_last_error("GetProcAddress returned: ");
|
|
|
|
|
|
|
|
return fp;
|
|
|
|
}
|
|
|
|
|
2008-04-28 07:34:55 -07:00
|
|
|
int
|
2008-11-01 02:50:01 -07:00
|
|
|
dladdr (const void *addr __UNUSED__, Dl_info *info)
|
2008-04-28 07:34:55 -07:00
|
|
|
{
|
2009-08-27 01:19:06 -07:00
|
|
|
TCHAR tpath[PATH_MAX];
|
2009-09-26 14:36:01 -07:00
|
|
|
MEMORY_BASIC_INFORMATION mbi;
|
2009-08-27 01:19:06 -07:00
|
|
|
char *path;
|
|
|
|
char *tmp;
|
|
|
|
size_t length;
|
|
|
|
int ret = 0;
|
2008-04-28 07:34:55 -07:00
|
|
|
|
2010-01-19 05:46:45 -08:00
|
|
|
if (!info)
|
|
|
|
return 0;
|
2008-04-28 07:34:55 -07:00
|
|
|
|
2010-01-19 05:46:45 -08:00
|
|
|
#ifdef _WIN32_WINNT
|
|
|
|
length = VirtualQuery(addr, &mbi, sizeof(mbi));
|
|
|
|
if (!length)
|
|
|
|
return 0;
|
2009-09-26 14:36:01 -07:00
|
|
|
|
2010-01-19 05:46:45 -08:00
|
|
|
if (mbi.State != MEM_COMMIT)
|
|
|
|
return 0;
|
2009-09-26 14:36:01 -07:00
|
|
|
|
2010-01-19 05:46:45 -08:00
|
|
|
if (!mbi.AllocationBase)
|
|
|
|
return 0;
|
2009-09-26 14:36:01 -07:00
|
|
|
|
2010-01-19 05:46:45 -08:00
|
|
|
ret = GetModuleFileName((HMODULE)mbi.AllocationBase, (LPTSTR)&tpath, PATH_MAX);
|
|
|
|
if (!ret)
|
|
|
|
return 0;
|
|
|
|
#else
|
|
|
|
ret = GetModuleFileName(NULL, (LPTSTR)&tpath, PATH_MAX);
|
2008-04-28 07:34:55 -07:00
|
|
|
if (!ret)
|
|
|
|
return 0;
|
2010-01-19 05:46:45 -08:00
|
|
|
#endif
|
2008-04-28 07:34:55 -07:00
|
|
|
|
2008-06-08 14:39:49 -07:00
|
|
|
#ifdef UNICODE
|
2008-04-28 07:34:55 -07:00
|
|
|
path = evil_wchar_to_char(tpath);
|
|
|
|
#else
|
|
|
|
path = tpath;
|
2008-06-08 14:39:49 -07:00
|
|
|
#endif /* ! UNICODE */
|
2008-04-28 07:34:55 -07:00
|
|
|
|
|
|
|
length = strlen (path);
|
|
|
|
if (length >= PATH_MAX)
|
|
|
|
{
|
|
|
|
length = PATH_MAX - 1;
|
|
|
|
path[PATH_MAX - 1] = '\0';
|
|
|
|
}
|
|
|
|
|
2008-05-09 16:16:42 -07:00
|
|
|
/* replace '\' by '/' */
|
|
|
|
tmp = path;
|
|
|
|
while (*tmp)
|
|
|
|
{
|
|
|
|
if (*tmp == '\\') *tmp = '/';
|
|
|
|
tmp++;
|
|
|
|
}
|
|
|
|
|
2008-04-28 07:34:55 -07:00
|
|
|
memcpy (info->dli_fname, path, length + 1);
|
|
|
|
info->dli_fbase = NULL;
|
|
|
|
info->dli_sname = NULL;
|
|
|
|
info->dli_saddr = NULL;
|
|
|
|
|
2008-06-08 14:39:49 -07:00
|
|
|
#ifdef UNICODE
|
2008-04-28 07:34:55 -07:00
|
|
|
free (path);
|
2008-06-08 14:39:49 -07:00
|
|
|
#endif /* ! UNICODE */
|
2008-04-28 07:34:55 -07:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2008-02-27 13:01:30 -08:00
|
|
|
char *
|
|
|
|
dlerror (void)
|
|
|
|
{
|
|
|
|
if (!dl_err_viewed)
|
|
|
|
{
|
|
|
|
dl_err_viewed = 1;
|
|
|
|
return dl_err;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (dl_err)
|
|
|
|
free(dl_err);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|