/* check which symbols the program looks up */ void * dlsym(void *handle, const char *symbol) { static void *(*orig_dlsym)(void *, const char *); void *orig_ptr, *ptr = NULL; if (orig_dlsym == NULL) orig_dlsym = _dl_sym(RTLD_NEXT, "dlsym", dlsym); if (!_env_ignored) { /* try to resolve the symbol to an internal one first to avoid issues * with dlerror(). */ ptr = _env_dump_resolve_local_symbol_by_name(symbol); /* resolve the symbol as expected by the client */ orig_ptr = orig_dlsym(handle, symbol); if (!orig_ptr) return orig_ptr; /* add the symbol to our DB */ _env_dump_replace_symbol(symbol, orig_ptr); if (ptr) return ptr; else return orig_ptr; } else return orig_dlsym(handle, symbol); }
void * _env_dump_resolve_symbol_by_name(const char *symbol) { void *ret = NULL, *tmp_ret = NULL; void *(*orig_dlsym)(void *handle, const char *symbol); int i; pthread_mutex_lock(&symbols_mp); /* first check in our internal DB */ for (i = 0; i < symbols_count; i++) { if (symbols[i].name && strcmp(symbols[i].name, symbol) == 0) { ret = symbols[i].ptr; break; } } pthread_mutex_unlock(&symbols_mp); if (ret) return ret; /* Then try to see if there is another version somewhere else */ orig_dlsym = _env_dump_resolve_symbol_by_id(SYMB_DLSYM); ret = orig_dlsym(RTLD_NEXT, symbol); if (ret == NULL) { /* Try to resolve the symbol from the local handles */ pthread_mutex_lock(&found_so_list_mp); for (i = 0; i < dlopen_local_handles_count; i++) { tmp_ret = orig_dlsym(dlopen_local_handles[i], symbol); if (tmp_ret) { if (ret == NULL || ret == tmp_ret) ret = tmp_ret; else { fprintf(env_file, "WARNING, found multiple candidates for " "the symbol '%s'\n", symbol); } } } pthread_mutex_unlock(&found_so_list_mp); } return ret; }
void * _env_dump_resolve_local_symbol_by_name(const char *symbol) { static void *(*orig_dlsym)(void *, const char *); static void *handle_env_dump; if (orig_dlsym == NULL) orig_dlsym = _dl_sym(RTLD_NEXT, "dlsym", dlsym); if (handle_env_dump == NULL ) { void *(*orig_dlopen)(const char *, int); char *fullpath = find_Linked_library("env_dump.so"); orig_dlopen = _dl_sym(RTLD_NEXT, "dlopen", dlsym); handle_env_dump = orig_dlopen(fullpath, RTLD_LAZY); free(fullpath); } return orig_dlsym(handle_env_dump, symbol); }
//void *dlsym(void *handle,const char *symbol) HOOK_DEF(void*, dlsym, void *handle, char *symbol) { LOGD("dlsym : %p %s.", handle, symbol); return orig_dlsym(handle, symbol); }