33 #define _CRTDBG_MAP_ALLOC
42 #if _WIN32_WINNT < 0x0500
47 #ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
48 #define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 0x4
50 #ifndef GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT
51 #define GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT 0x2
56 #pragma intrinsic(_ReturnAddress)
59 #ifndef _ReturnAddress
60 #define _ReturnAddress() (__builtin_extract_return_addr(__builtin_return_address(0)))
64 #ifdef DLFCN_WIN32_SHARED
65 #define DLFCN_WIN32_EXPORTS
69 #if defined(_MSC_VER) && _MSC_VER >= 1300
71 #define DLFCN_NOINLINE __declspec(noinline)
72 #elif defined(__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
74 #define DLFCN_NOINLINE __attribute__((noinline))
76 #define DLFCN_NOINLINE
127 pobject->
next = nobject;
181 ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
184 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
205 char ptr_buf[2 + 2 *
sizeof(ptr) + 1];
212 for (
i = 0;
i < 2 *
sizeof(ptr);
i++) {
213 num = (char) ((((
ULONG_PTR) ptr) >> (8 *
sizeof(ptr) - 4 * (
i + 1))) & 0xF);
214 ptr_buf[2 +
i] = num + ((num < 0xA) ?
'0' : (
'A' - 0xA));
217 ptr_buf[2 + 2 *
sizeof(ptr)] = 0;
223 static BOOL(WINAPI * SetThreadErrorModePtr)(DWORD, DWORD*) =
NULL;
224 static BOOL failed =
FALSE;
228 if (!failed && SetThreadErrorModePtr ==
NULL) {
229 kernel32 = GetModuleHandleA(
"Kernel32.dll");
230 if (kernel32 !=
NULL)
231 SetThreadErrorModePtr = (BOOL(WINAPI*)(DWORD, DWORD*))(
232 LPVOID) GetProcAddress(kernel32,
"SetThreadErrorMode");
233 if (SetThreadErrorModePtr ==
NULL)
238 if (!SetThreadErrorModePtr(uMode, &oldMode))
243 return SetErrorMode(uMode);
248 static BOOL(WINAPI * GetModuleHandleExAPtr)(DWORD, LPCSTR, HMODULE*) =
NULL;
249 static BOOL failed =
FALSE;
252 MEMORY_BASIC_INFORMATION
info;
255 if (!failed && GetModuleHandleExAPtr ==
NULL) {
256 kernel32 = GetModuleHandleA(
"Kernel32.dll");
257 if (kernel32 !=
NULL)
258 GetModuleHandleExAPtr = (BOOL(WINAPI*)(DWORD, LPCSTR, HMODULE*))(
259 LPVOID) GetProcAddress(kernel32,
"GetModuleHandleExA");
260 if (GetModuleHandleExAPtr ==
NULL)
276 sLen = VirtualQuery(addr, &
info,
sizeof(
info));
277 if (sLen !=
sizeof(
info))
289 LPDWORD lpcbNeeded) {
290 static BOOL(WINAPI * EnumProcessModulesPtr)(HANDLE, HMODULE*, DWORD, LPDWORD) =
NULL;
291 static BOOL failed =
FALSE;
298 if (EnumProcessModulesPtr ==
NULL) {
301 psapi = GetModuleHandleA(
"Kernel32.dll");
303 EnumProcessModulesPtr = (BOOL(WINAPI*)(HANDLE, HMODULE*, DWORD, LPDWORD))(
304 LPVOID) GetProcAddress(psapi,
"K32EnumProcessModules");
308 if (EnumProcessModulesPtr ==
NULL) {
311 psapi = LoadLibraryA(
"Psapi.dll");
313 EnumProcessModulesPtr = (BOOL(WINAPI*)(HANDLE, HMODULE*, DWORD, LPDWORD))(
314 LPVOID) GetProcAddress(psapi,
"EnumProcessModules");
315 if (EnumProcessModulesPtr ==
NULL)
321 if (EnumProcessModulesPtr ==
NULL) {
327 return EnumProcessModulesPtr(hProcess, lphModule, cb, lpcbNeeded);
331 void*
dlopen(
const char* file,
int mode) {
357 DWORD dwProcModsBefore, dwProcModsAfter;
358 char lpFileName[MAX_PATH];
363 if (len >=
sizeof(lpFileName)) {
368 for (
i = 0;
i < len;
i++) {
370 lpFileName[
i] =
'\\';
372 lpFileName[
i] = file[
i];
374 lpFileName[len] =
'\0';
376 hCurrentProc = GetCurrentProcess();
379 dwProcModsBefore = 0;
386 hModule = LoadLibraryExA(lpFileName,
NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
403 if ((mode &
RTLD_LOCAL) && dwProcModsBefore != dwProcModsAfter) {
409 }
else if (!(mode &
RTLD_LOCAL) && dwProcModsBefore == dwProcModsAfter) {
478 if (hCaller ==
NULL) {
479 dwMessageId = ERROR_INVALID_PARAMETER;
485 symbol = GetProcAddress((HMODULE)
handle,
name);
502 hCurrentProc = GetCurrentProcess();
509 modules = malloc(dwSize);
512 dwSize == cbNeeded) {
513 for (
i = 0;
i < dwSize /
sizeof(HMODULE);
i++) {
516 if (hCaller == modules[
i])
522 symbol = GetProcAddress(modules[
i],
name);
523 if (symbol !=
NULL) {
531 dwMessageId = ERROR_NOT_ENOUGH_MEMORY;
538 if (symbol ==
NULL) {
540 dwMessageId = ERROR_PROC_NOT_FOUND;
544 return *(
void**) (&symbol);
567 IMAGE_DOS_HEADER* dosHeader;
568 IMAGE_NT_HEADERS* ntHeaders;
569 IMAGE_OPTIONAL_HEADER* optionalHeader;
571 dosHeader = (IMAGE_DOS_HEADER*) module;
573 if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE)
576 ntHeaders = (IMAGE_NT_HEADERS*) ((BYTE*) dosHeader + dosHeader->e_lfanew);
578 if (ntHeaders->Signature != IMAGE_NT_SIGNATURE)
581 optionalHeader = &ntHeaders->OptionalHeader;
583 if (optionalHeader->Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
586 if (index < 0 || index > IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR)
589 if (optionalHeader->DataDirectory[
index].Size == 0 ||
590 optionalHeader->DataDirectory[
index].VirtualAddress == 0)
594 *size = optionalHeader->DataDirectory[
index].Size;
596 *ptr = (
void*) ((BYTE*) module + optionalHeader->DataDirectory[
index].VirtualAddress);
603 IMAGE_EXPORT_DIRECTORY* ied,
605 void** func_address) {
607 void* candidateAddr =
NULL;
608 int candidateIndex = -1;
609 BYTE* base = (BYTE*) module;
610 DWORD* functionAddressesOffsets = (DWORD*) (base + ied->AddressOfFunctions);
611 DWORD* functionNamesOffsets = (DWORD*) (base + ied->AddressOfNames);
612 USHORT* functionNameOrdinalsIndexes = (USHORT*) (base + ied->AddressOfNameOrdinals);
614 for (
i = 0;
i < ied->NumberOfFunctions;
i++) {
615 if ((
void*) (base + functionAddressesOffsets[
i]) > addr ||
616 candidateAddr >= (
void*) (base + functionAddressesOffsets[
i]))
619 candidateAddr = (
void*) (base + functionAddressesOffsets[
i]);
623 if (candidateIndex == -1)
626 *func_address = candidateAddr;
628 for (
i = 0;
i < ied->NumberOfNames;
i++) {
629 if (functionNameOrdinalsIndexes[
i] == candidateIndex)
630 return (
const char*) (base + functionNamesOffsets[
i]);
637 MEMORY_BASIC_INFORMATION
info;
647 info.AllocationProtect == PAGE_NOACCESS)
661 return *(
short*) addr == 0x25ff ?
TRUE :
FALSE;
668 BYTE* thkp = (BYTE*) addr;
672 ULONG offset = *(ULONG*) (thkp + 2);
680 BYTE* ptr = (BYTE*) (thkp + 6 + (LONG) offset);
685 BYTE* ptr = (BYTE*) offset;
688 if (!
is_valid_address(ptr) || ptr < (BYTE*) iat || ptr > (BYTE*) iat + iat_size)
691 return *(
void**) ptr;
700 IMAGE_EXPORT_DIRECTORY* ied;
701 void* funcAddress =
NULL;
724 : funcAddress !=
NULL ? funcAddress
752 IMAGE_IMPORT_DESCRIPTOR* iid;
758 if (iid ==
NULL || iid->Characteristics == 0 || iid->FirstThunk == 0)
761 iat = (
void*) ((BYTE*)
hModule + iid->FirstThunk);
763 iatSize = iidSize - (DWORD) ((BYTE*) iat - (BYTE*) iid);
778 #ifdef DLFCN_WIN32_SHARED
779 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
static void save_err_ptr_str(const void *ptr, DWORD dwMessageId)
static char error_buffer[65535]
static void * get_address_from_import_address_table(void *iat, DWORD iat_size, const void *addr)
#define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
struct local_object local_object
static BOOL fill_info(const void *addr, Dl_info *info)
static UINT MySetErrorMode(UINT uMode)
static void save_err_str(const char *str, DWORD dwMessageId)
static local_object * local_search(HMODULE hModule)
DLFCN_EXPORT void * dlopen(const char *file, int mode)
static local_object first_object
DLFCN_EXPORT char * dlerror(void)
static const char * get_export_symbol_name(HMODULE module, IMAGE_EXPORT_DIRECTORY *ied, const void *addr, void **func_address)
DLFCN_EXPORT int dlclose(void *handle)
static char module_filename[2 *MAX_PATH]
DLFCN_EXPORT int dladdr(const void *addr, Dl_info *info)
static BOOL local_add(HMODULE hModule)
static BOOL error_occurred
static HMODULE MyGetModuleHandleFromAddress(const void *addr)
#define GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT
static BOOL is_import_thunk(const void *addr)
DLFCN_NOINLINE DLFCN_EXPORT void * dlsym(void *handle, const char *name)
static BOOL get_image_section(HMODULE module, int index, void **ptr, DWORD *size)
static BOOL MyEnumProcessModules(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded)
static void local_rem(HMODULE hModule)
static BOOL is_valid_address(const void *addr)
handle_interface< non_owning_identifier< storage > > handle
Non-owning handle to a Mechanism instance.
struct local_object * previous
struct local_object * next