static void dlsym_doit (void *a) { struct dlsym_args *args = (struct dlsym_args *) a; args->sym = _dl_sym (args->handle, args->name, args->who); }
unsigned long do_rel(struct _dl_handle * tmp_dl, unsigned long off) { Elf_Rel *tmp = ((void*)tmp_dl->plt_rel)+off; int sym=ELF_R_SYM(tmp->r_info); register unsigned long sym_val; #ifdef DEBUG pf(__func__": "); ph((unsigned long)tmp_dl); pf(" "); ph(off); pf(" on "); ph((long)tmp_dl->plt_rel); pf("\n"); pf(__func__": @ "); ph((long)tmp->r_offset); pf(" with type "); ph(ELF_R_TYPE(tmp->r_info)); pf(" and sym "); ph(sym); pf(" symval "); ph(tmp_dl->dyn_sym_tab[sym].st_value); pf("\n"); #endif /* modify GOT for REAL symbol */ //sym_val=((unsigned long)(tmp_dl->mem_base+tmp_dl->dyn_sym_tab[sym].st_value)); sym_val=(unsigned long)_dl_sym(tmp_dl,sym); *((unsigned long*)(tmp_dl->mem_base+tmp->r_offset))=sym_val; #ifdef DEBUG pf(__func__": sym "); ph(sym_val); pf("\n"); #endif /* JUMP (arg sysdep...) */ if (sym_val) return sym_val; /* can't find symbol -> die now */ return (unsigned long)exit_now; }
extern void * dlsym(void * handle, const char * symbol){ if(!real_dlsym){ real_dlsym = _dl_sym(RTLD_NEXT, "dlsym", dlsym); } void *ret = NULL; if(symbol && string_testEqual(symbol, "dlsym")) return dlsym; if(!(ret = real_dlsym(handle, symbol))) return ret; printf("hooked dlsym, %s\n", symbol); if(string_testEqualN(symbol, "glXGetProcAddress", 17)){ // printf("--- HOOK GLXGETPROCADDRESS\n"); glXGetProcAddress_orig = real_dlsym(handle, "glXGetProcAddress"); return glXGetProcAddress; } else if(string_testEqualN(symbol, "glutGetProcAddress", 18)){ // printf("--- HOOK GLXGETPROCADDRESS\n"); glutGetProcAddress_orig = real_dlsym(handle, "glutGetProcAddress"); return glutGetProcAddress; } else if(string_testEqualN(symbol, "glXSwapBuffers", 14)){ glXSwapBuffers_orig = real_dlsym(handle, "glXSwapBuffers"); // printf("replaced %s\n", symbol); return (__GLXextFuncPtr)glXSwapBuffers; } else if(string_testEqualN(symbol, "glXChooseFBConfig", 17)){ glXChooseFBConfig_orig = real_dlsym(handle, "glXChooseFBConfig"); // printf("replaced %s\n", symbol); return (__GLXextFuncPtr)glXChooseFBConfig; } else if(string_testEqualN(symbol, "glfwCreateWindow", 16)){ glfwCreateWindow_orig = real_dlsym(handle, "glfwCreateWindow"); // printf("replaced %s\n", symbol); return glfwCreateWindow; } return ret; }
/* 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_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 * _env_dump_resolve_symbol_by_id(enum symbol_key_t symbol) { void *ret = NULL; pthread_mutex_lock(&symbols_mp); if (symbol < SYMB_END && symbols_len > symbol && symbols[symbol].name) ret = symbols[symbol].ptr; pthread_mutex_unlock(&symbols_mp); /* Then try to see if there is another version somewhere else */ if (ret == NULL) { ret = _dl_sym(RTLD_NEXT, symbol_key_str[symbol], _env_dump_resolve_symbol_by_name); _env_dump_replace_symbol(symbol_key_str[symbol], ret); } return ret; }
/* Wrapper function called in place of dlsym(), since we intercept dlsym(). * We use this ONLY to get the original dlsym() itself, all other symbol * resolutions are done via that original function, then. */ static void *GH_dlsym_internal(void *handle, const char *name) { void *ptr; /* ARGH: we are bypassing glibc's locking for dlsym(), so we * must do this on our own */ pthread_mutex_lock(&GH_mutex); /* Third argument is the address of the caller, (glibc uses stack * unwinding internally to get this), we just use the address of our * wrapper function itself, which is wrong when this is called on * behalf of the real application doing a dlsycm, but we do not * care... */ ptr=_dl_sym(handle, name, (void (*)())GH_dlsym_internal); pthread_mutex_unlock(&GH_mutex); return ptr; }
void * __libc_dlsym (void *map, const char *name) { return _dl_sym (map, name, NULL); }