You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hook readdir()时,如何从opendir()返回的DIR结构体恢复目录路径?

针对readdir()钩子拦截特定路径的实现方案

核心思路:追踪DIR结构体与路径的绑定关系

要实现只拦截特定路径的readdir()调用,关键是在**opendir()/fdopendir()**的调用阶段就记录下DIR结构体对应的路径,这样后续readdir()被hook时,直接通过DIR指针查找对应的路径即可判断是否需要拦截。

具体实现步骤

  1. Hook opendir系列函数

    • 拦截opendir(const char *name):调用原始opendir得到DIR后,把这个DIR指针和传入的路径name关联存储(比如用哈希表,key是DIR,value是路径字符串的深拷贝)。
    • 拦截fdopendir(int fd):先通过readlink("/proc/self/fd/<fd>")(Linux)或fcntl(fd, F_GETPATH)(BSD)获取fd对应的路径,再调用原始fdopendir得到DIR*,同样把DIR*和路径关联存储。
    • 注意:要做路径规范化处理,比如解析符号链接、去除末尾斜杠,避免同一路径的不同写法导致匹配失败。
  2. Hook readdir()函数

    • 当readdir(DIR *dirp)被调用时,先在哈希表中查找dirp对应的路径。
    • 如果路径匹配目标拦截路径,执行自定义逻辑(比如修改返回的dirent、记录访问日志);不匹配则直接调用原始readdir返回结果。
  3. Hook closedir()函数

    • 拦截closedir(DIR *dirp):调用原始closedir后,从哈希表中删除该DIR*对应的条目,释放路径字符串内存,避免内存泄漏和无效指针残留。

关键细节处理

  • 线程安全:多线程环境下,哈希表的读写操作要加锁(比如用pthread_mutex_t),防止并发冲突。
  • 内存管理:存储路径时必须深拷贝,不能直接使用原始参数指针(opendir的参数可能是临时缓冲区),closedir时要释放路径内存。
  • 特殊场景兼容:处理dup/dup2复制目录fd后调用fdopendir的情况,确保每个新DIR*都能关联到正确路径;部分系统的DIR结构体内置fd,可通过dirfd(dirp)获取fd后反向查路径作为 fallback。

依赖系统实现的替代方案

部分系统(如Linux)的DIR结构体内部包含文件描述符fd,可直接通过DIR*获取fd再反向查路径:

// Linux下从DIR*提取fd的近似实现(需参考系统头文件确认结构体布局)
#define dirfd(dirp) ((dirp)->fd)

之后用readlink("/proc/self/fd/<fd>")获取路径,这种方法无需hook opendir,但移植性差,且每次readdir都要查询路径,性能略低。


内容的提问来源于stack exchange,提问作者sawntoe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 17:45:03