void glinject_init_hooks() { if(g_glinject_hooks_initialized) return; // part 1: get dlsym and dlvsym eh_obj_t libdl; if(eh_find_obj(&libdl, "*/libdl.so*")) { fprintf(stderr, "[SSR-GLInject] Can't open libdl.so!\n"); exit(-181818181); } if(eh_find_sym(&libdl, "dlsym", (void **) &g_glinject_real_dlsym)) { fprintf(stderr, "[SSR-GLInject] Can't get dlsym address!\n"); eh_destroy_obj(&libdl); exit(-181818181); } if(eh_find_sym(&libdl, "dlvsym", (void **) &g_glinject_real_dlvsym)) { fprintf(stderr, "[SSR-GLInject] Can't get dlvsym address!\n"); eh_destroy_obj(&libdl); exit(-181818181); } eh_destroy_obj(&libdl); // part 2: get everything else g_glinject_real_glXCreateWindow = (GLXWindow (*)(Display*, GLXFBConfig, Window, const int*)) g_glinject_real_dlsym(RTLD_NEXT, "glXCreateWindow"); if(g_glinject_real_glXCreateWindow == NULL) { fprintf(stderr, "[SSR-GLInject] Can't get glXCreateWindow address!\n"); exit(-181818181); } g_glinject_real_glXSwapBuffers = (void (*)(Display*, GLXDrawable)) g_glinject_real_dlsym(RTLD_NEXT, "glXSwapBuffers"); if(g_glinject_real_glXSwapBuffers == NULL) { fprintf(stderr, "[SSR-GLInject] Can't get glXSwapBuffers address!\n"); exit(-181818181); } g_glinject_real_glXGetProcAddressARB = (GLXextFuncPtr (*)(const GLubyte*)) g_glinject_real_dlsym(RTLD_NEXT, "glXGetProcAddressARB"); if(g_glinject_real_glXGetProcAddressARB == NULL) { fprintf(stderr, "[SSR-GLInject] Can't get glXGetProcAddressARB address!\n"); exit(-181818181); } g_glinject_real_XNextEvent = (int (*)(Display*, XEvent*)) g_glinject_real_dlsym(RTLD_NEXT, "XNextEvent"); if(g_glinject_real_XNextEvent == NULL) { fprintf(stderr, "[SSR-GLInject] Can't get XNextEvent address!\n"); exit(-181818181); } g_glinject_hooks_initialized = 1; }
extern "C" void* dlsym(void* handle, const char* symbol) { glinject_init_hooks(); for(unsigned int i = 0; i < sizeof(hook_table) / sizeof(Hook); ++i) { if(strcmp(hook_table[i].name, symbol) == 0) { fprintf(stderr, "[SSR-GLInject] Hooked: dlsym(%s).\n", symbol); return hook_table[i].address; } } return g_glinject_real_dlsym(handle, symbol); }
extern "C" void* dlsym(void* handle, const char* symbol) { InitGLInject(); for(unsigned int i = 0; i < sizeof(hook_table) / sizeof(Hook); ++i) { if(strcmp(hook_table[i].name, symbol) == 0) { std::lock_guard<std::mutex> lock(g_glinject_mutex); GLINJECT_PRINT("Hooked: dlsym(" << symbol << ")."); return hook_table[i].address; } } return g_glinject_real_dlsym(handle, symbol); }
void InitGLInject() { std::lock_guard<std::mutex> lock(g_glinject_mutex); if(g_glinject != NULL) return; // part 1: get dlsym and dlvsym eh_obj_t libdl; if(eh_find_obj(&libdl, "*/libdl.so*")) { GLINJECT_PRINT("Error: Can't open libdl.so!"); exit(1); } if(eh_find_sym(&libdl, "dlsym", (void**) &g_glinject_real_dlsym)) { GLINJECT_PRINT("Error: Can't get dlsym address!"); eh_destroy_obj(&libdl); exit(1); } if(eh_find_sym(&libdl, "dlvsym", (void**) &g_glinject_real_dlvsym)) { GLINJECT_PRINT("Error: Can't get dlvsym address!"); eh_destroy_obj(&libdl); exit(1); } eh_destroy_obj(&libdl); // part 2: get everything else g_glinject_real_glXCreateWindow = (GLXWindow (*)(Display*, GLXFBConfig, Window, const int*)) g_glinject_real_dlsym(RTLD_NEXT, "glXCreateWindow"); if(g_glinject_real_glXCreateWindow == NULL) { GLINJECT_PRINT("Error: Can't get glXCreateWindow address!"); exit(1); } g_glinject_real_glXDestroyWindow = (void (*)(Display*, GLXWindow)) g_glinject_real_dlsym(RTLD_NEXT, "glXDestroyWindow"); if(g_glinject_real_glXDestroyWindow == NULL) { GLINJECT_PRINT("Error: Can't get glXDestroyWindow address!"); exit(1); } g_glinject_real_XDestroyWindow = (int (*)(Display*, Window)) g_glinject_real_dlsym(RTLD_NEXT, "XDestroyWindow"); if(g_glinject_real_XDestroyWindow == NULL) { GLINJECT_PRINT("Error: Can't get XDestroyWindow address!"); exit(1); } g_glinject_real_glXSwapBuffers = (void (*)(Display*, GLXDrawable)) g_glinject_real_dlsym(RTLD_NEXT, "glXSwapBuffers"); if(g_glinject_real_glXSwapBuffers == NULL) { GLINJECT_PRINT("Error: Can't get glXSwapBuffers address!"); exit(1); } g_glinject_real_glXGetProcAddressARB = (GLXextFuncPtr (*)(const GLubyte*)) g_glinject_real_dlsym(RTLD_NEXT, "glXGetProcAddressARB"); if(g_glinject_real_glXGetProcAddressARB == NULL) { GLINJECT_PRINT("Error: Can't get glXGetProcAddressARB address!"); exit(1); } g_glinject_real_XNextEvent = (int (*)(Display*, XEvent*)) g_glinject_real_dlsym(RTLD_NEXT, "XNextEvent"); if(g_glinject_real_XNextEvent == NULL) { GLINJECT_PRINT("Error: Can't get XNextEvent address!"); exit(1); } g_glinject = new GLInject(); atexit(FreeGLInject); }