void *apkenv_get_hooked_symbol_dlfcn(void *handle, const char *sym) { struct _hook *result; struct _hook target; target.name = sym; if (is_builtin_lib_handle(handle)) { enum builtin_library_id builtin_lib_id = (const char **)handle - builtin_libs; #ifdef APKENV_GLES if (builtin_lib_id == BUILTIN_LIB_GLESV1) { result = bsearch(&target, hooks_gles1, HOOKS_GLES1_COUNT, HOOK_SIZE, hook_cmp); if (result != NULL) return result->func; return NULL; } #endif #ifdef APKENV_GLES2 if (builtin_lib_id == BUILTIN_LIB_GLESV2) { result = bsearch(&target, hooks_gles2, HOOKS_GLES2_COUNT, HOOK_SIZE, hook_cmp); if (result != NULL) return result->func; return NULL; } #endif } return apkenv_get_hooked_symbol(sym, 1); }
int android_dlclose(void *handle) { if (is_builtin_lib_handle(handle)) return 0; pthread_mutex_lock(&dl_lock); (void)unload_library((soinfo*)handle); pthread_mutex_unlock(&dl_lock); return 0; }
void *android_dlsym(void *handle, const char *symbol) { soinfo *found; Elf32_Sym *sym; unsigned bind; pthread_mutex_lock(&dl_lock); if(unlikely(handle == 0)) { set_dlerror(DL_ERR_INVALID_LIBRARY_HANDLE); goto err; } if(unlikely(symbol == 0)) { set_dlerror(DL_ERR_BAD_SYMBOL_NAME); goto err; } void *sym_addr; if(0 != (sym_addr = get_hooked_symbol_dlfcn(handle, symbol))) { LINKER_DEBUG_PRINTF("symbol %s hooked to %x\n",symbol,sym_addr); pthread_mutex_unlock(&dl_lock); return sym_addr; } if (is_builtin_lib_handle(handle)) { /* must be hooked.. */ set_dlerror(DL_ERR_SYMBOL_NOT_FOUND); goto err; } if(handle == RTLD_DEFAULT) { sym = lookup(symbol, &found, NULL); } else if(handle == RTLD_NEXT) { void *ret_addr = __builtin_return_address(0); soinfo *si = find_containing_library(ret_addr); sym = NULL; if(si && si->next) { sym = lookup(symbol, &found, si->next); } } else { found = (soinfo*)handle; sym = lookup_in_library(found, symbol); } if(likely(sym != 0)) { bind = ELF32_ST_BIND(sym->st_info); if(likely((bind == STB_GLOBAL) && (sym->st_shndx != 0))) { unsigned ret = sym->st_value + found->base; pthread_mutex_unlock(&dl_lock); return create_wrapper((char*)symbol, (void*)ret, WRAPPER_DYNHOOK); } set_dlerror(DL_ERR_SYMBOL_NOT_GLOBAL); } else set_dlerror(DL_ERR_SYMBOL_NOT_FOUND); err: LINKER_DEBUG_PRINTF("symbol %s has not been hooked\n",symbol); pthread_mutex_unlock(&dl_lock); return 0; }