LD_PRELOAD和clone()
我正在使用一个脚本运行一个带有LD_PRELOAD的程序和一个由我创建的库拦截一些调用,它运行良好但是在某些时候进程调用clone()并且我失去了拦截下一步的能力(程序运行)再没有我的图书馆),有什么方法可以克服这个问题吗?
打电话是 clone(child_stack,CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID,parent_tidptr,tls,child_tidptr) 查看克隆的参数我发现有能力跟踪子进程,但没有任何与预加载有关的内容. 我还要提一下,我试图拦截特定文件描述符上的所有调用和进程克隆文件描述符,所以我甚至不确定是否有可能做我想要的而没有一些标记来克隆(问题是我不明白所有这些). 更新: #define _LARGEFILE64_SOURCE #define _GNU_SOURCE #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <dlfcn.h> #include <stdio.h> #include <stdarg.h> #define dprintf(...) if(__debug__) { char tmp[256]; int cnt = sprintf(tmp,__VA_ARGS__); _write_f_(2,tmp,cnt); _write_f_(__outfile__,cnt); } typedef int (*_open_f_t_)(const char *path,int flags,...); typedef int (*_open64_f_t_)(const char *path,...); typedef FILE *(*_fopen_f_t_)(const char *path,const char *mode); typedef int (*_close_f_t_)(int fd); typedef ssize_t (*_read_f_t_)(int fd,void *buf,size_t count); typedef ssize_t (*_write_f_t_)(int fd,const void *buf,size_t count); typedef off_t (*_lseek_f_t_)(int fd,off_t offset,int whence); static _open_f_t_ _open_f_ = NULL; static _open64_f_t_ _open64_f_ = NULL; static _fopen_f_t_ _fopen_f_ = NULL; static _close_f_t_ _close_f_ = NULL; static _read_f_t_ _read_f_ = NULL; static _write_f_t_ _write_f_ = NULL; static _lseek_f_t_ _lseek_f_ = NULL; static int __outfile__ = NULL; static int __debug__ = 0; void __init__ () { _open_f_ = (_open_f_t_)dlsym(RTLD_NEXT,"open"); _open64_f_ = (_open64_f_t_)dlsym(RTLD_NEXT,"open64"); _fopen_f_ = (_fopen_f_t_)dlsym(RTLD_NEXT,"fopen"); _close_f_ = (_close_f_t_)dlsym(RTLD_NEXT,"close"); _read_f_ = (_read_f_t_)dlsym(RTLD_NEXT,"read"); _write_f_ = (_write_f_t_)dlsym(RTLD_NEXT,"write"); _lseek_f_ = (_lseek_f_t_)dlsym(RTLD_NEXT,"lseek"); unlink("/tmp/qemu-dm-preload.log"); __outfile__ = _open_f_("/tmp/out-0",O_WRONLY | O_CREAT | O_APPEND); __debug__ = 1; } void __fini__ () { __debug__ = 0; fsync(__outfile__); _close_f_(__outfile__); } int open(const char *path,...) { //replace this int result; if (flags & O_CREAT) { va_list arg; int mode = 0; va_start (arg,flags); mode = va_arg (arg,int); va_end (arg); result = _open_f_(path,flags,mode); dprintf("open(%s,%d,%d) => %dn",path,mode,result); } else { result = _open_f_(path,flags); dprintf("open(%s,result); } return result; } int open64(const char *path,int); va_end (arg); result = _open64_f_(path,result); } else { result = _open64_f_(path,result); } return result; } FILE * fopen(const char *path,const char *mode) { FILE *result = _fopen_f_(path,mode); dprintf("fopen(%s,%s) => %pn",result); return result; } int close(int fd) { //replace this int result = _close_f_(fd); dprintf("close(%d) => %dn",fd,result); return result; } ssize_t read(int fd,size_t count) { // replace this ssize_t result = _read_f_(fd,buf,count); dprintf("read(%d,%p,%lu) => %ldn",count,result); return result; } ssize_t write(int fd,size_t count) { // replace this ssize_t result = _write_f_(fd,count); dprintf("write(%d,result); return result; } off_t lseek(int fd,int whence) { // replace this off_t result = _lseek_f_(fd,offset,whence); dprintf("lseek(%d,%ld,%d) => %ldn",whence,result); return result; } 使用gcc -ggdb -shared -fPIC -Wl编译,-init,__ init__ -Wl,-fini,__ fini__ -o fileaccesshooks.so -ldl fileaccesshooks.c 包装脚本内容: #!/bin/bash export LD_PRELOAD=/home/xception/work/fileaccesshooks.so exec /usr/lib/xen/bin/qemu-dm-orig "$@" 正如在下面的评论中所观察到的,环境对于任务和过程实际上是相同的(LD_PRELOAD对于/ proc / 8408 / task / 8526 / environ和/ proc / 8408 / environ都是相同的)但是在调用克隆之后不再记录数据 open(/root/testfile.raw,2) => 11 read(11,0x7fffb7259d00,512) => 512 read(11,0x7fba6e341200,512) => 512 这就是我得到的,但相对而言,相同的可执行文件上运行的strace -f的输出包含更多的读取和搜索 解决方法
从CLONE_VM的克隆参数和类似的,看起来这个克隆调用只是创建一个新的线程而不是一个新的进程.我不希望结果线程重新加载任何库,因此我不希望你的预加载库需要在新线程中再次行动 – 你现有的函数实现应该’正常工作’;所有跳转到库中的指令应该在旧线程中保持同样有效.
因此,我怀疑这不是你的问题,克隆是一个红鲱鱼. 我唯一的理论是: >某个地方也有一名执行官 关于qemu的最后一点 – 现代qemu使用协同程序来处理许多IO事物.它使用各种后端,具体取决于主机系统上的可用内容 – 如果你运气不好,它会为每个后端创建一个线程,这可能会产生非常非常大量的线程.在这里阅读 – http://lists.gnu.org/archive/html/qemu-devel/2011-07/msg02894.html – 有一些方法可以让qemu配置东西报告它正在使用的协程后端.但是,我怀疑Xen qemu-dm可能太老而无法获得这些协同程序的东西?我不知道. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |