我想拦截应用程序对dlsym的调用,我已经尝试在.so中声明我正在预加载dlsym,并使用dlsym本身来获取它的真实地址,但是由于非常明显的原因不起作用。
有没有比采用进程’内存映射更容易,并使用libelf在加载的libdl.so中找到dlsym的真实位置?
作为评论者,我偶然发现了与hdante的答案相同的问题:调用__libc_dlsym()
直接崩溃了一个段错误。 在阅读了一些glibc源代码后,我提出了以下hack作为解决方法:
extern void *_dl_sym(void *, const char *, void *); extern void *dlsym(void *handle, const char *name) { /* my target binary is even asking for dlsym() via dlsym()... */ if (!strcmp(name,"dlsym")) return (void*)dlsym; return _dl_sym(handle, name, dlsym); }
注意这个“解决方案”的两件事:
到目前为止提出的解决方案有一些明显的缺点: _dl_sym()
dlsym()
在某些情况下与预期的dlsym()
行为完全不同。 例如,尝试解析不存在的符号会退出程序而不是仅返回NULL。 要解决这个问题,可以使用_dl_sym()
来获取指向原始dlsym()
的指针,并将其用于其他所有内容(例如在“标准” LD_PRELOAD
钩子approch中,而不需要连接dlsym
):
extern void *_dl_sym(void *, const char *, void *); extern void *dlsym(void *handle, const char *name) { static void * (*real_dlsym)(void *, const char *)=NULL; if (real_dlsym == NULL) real_dlsym=_dl_sym(RTLD_NEXT, "dlsym", dlsym); /* my target binary is even asking for dlsym() via dlsym()... */ if (!strcmp(name,"dlsym")) return (void*)dlsym; return real_dlsym(handle,name); }
从文字:
当需要在钩子中调用__libc_dlsym(句柄,符号)时,请注意自己调用dlsym()的函数。
extern void *__libc_dlsym (void *, const char *); void *dlsym(void *handle, const char *symbol) { printf("Ha Ha...dlsym() Hookedn"); void* result = __libc_dlsym(handle, symbol); /* now, this will call dlsym() library function */ return result; }
以上就是c/c++开发分享如何使用LD_PRELOAD拦截dlsym调用?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/545315.html