gpt4 book ai didi

c++ - fstat() 在预加载的 mmap() 系统调用中无法按预期工作

转载 作者:行者123 更新时间:2023-11-28 07:32:21 24 4
gpt4 key购买 nike

我正在尝试从 fstat() 获取设备的次要和主要编号。对 fstat() 的调用是在预加载的 mmap() 系统调用中完成的:

// preload.so
// compile with:
// gcc -ldl -Wall -shared -fPIC -o preload.so -D_GNU_SOURCE preload.c
#include <stdlib.h>
#include <stdarg.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <dlfcn.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>

#if __GNUC__ >= 4
#define PUBLIC __attribute__ ((visibility("default")))
#else
#define PUBLIC
#endif

PUBLIC void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) {
printf("preload\n");

struct stat sb;
if (fstat(fd, &sb) == -1)
printf("fstat() failed\n");
else
printf("%u %u\n", major(sb.st_rdev), minor(sb.st_rdev));

typedef void*(*mmap_t)(void *, size_t, int, int, int, off_t);
mmap_t o_mmap = dlsym(RTLD_NEXT, "mmap");
return (*o_mmap)(start, length, prot, flags, fd, offset);
}

然后上述库可以拦截来自任何给定程序的任何 mmap() 系统调用:

$ LD_PRELOAD=./preload.so ./my_prog

尽管 my_prog 在打开真实设备节点后尝试 mmap() 设备,但为什么我一直获取 0 和 0 作为主要和次要编号?

有没有办法从预加载的 mmap() 系统调用中获取主要和次要编号,除了传递给函数本身的参数之外没有任何其他信息?

最佳答案

mmap() 也会被许多其他代码调用,例如

  • 加载/映射共享库。
  • 获取匿名内存(例如 malloc() 可能调用 mmap 获取更多内存)

在第一种情况下,经 mmap() 处理的文件只是一个普通文件,其次要/主要为 0。在第二种情况下,传入的 fd 不是有效的 fd - 应用程序应该将 -1 作为 fd 传递,但它可能不会..

您可能会从运行时看到这些 mmap() 调用并间接从其他库调用您的应用程序执行的操作,而不仅仅是您的应用程序执行的设备的 mmap() 调用。

例如Linux/glibc,可能还有其他系统,我假设 mmap() 调用可以被编译为调用 mmap64(),这取决于所使用的编译器标志启用大文件支持。您可能需要拦截 mmap64() 以及 mmap()

不清楚你真正想做什么,但你可以

  • 检查fd不为-1
  • 检查标志是否不包含 MAP_ANONYMOUS
  • 然后执行 fstat。
  • 检查 S_ISCHR() 或 S_ISBLK() 的 struct stat.st_mode(参见 stat 手册页)以了解 mmap() 是否用于设备文件
  • 如果 sb.st_rdev 是您感兴趣的主要/次要号码,请采取行动。

关于c++ - fstat() 在预加载的 mmap() 系统调用中无法按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17411093/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com