我正在尝试从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()
尝试{{1}}设备,为什么我仍然继续获取0和0作为主要和次要号码?
有没有办法从预加载的mmap()系统调用中获取主要和次要数字,除了传递给函数本身的参数之外没有任何其他信息?
答案 0 :(得分:1)
mmap()也会被很多其他代码调用,例如
在第一种情况下,mmap()'ed文件只是一个常规文件,并且次要/主要为0。 在第二种情况下,传入的fd不是有效的fd - 应用程序应该将-1作为fd传递,但它可能不会...
您可能会看到来自运行时的这些mmap()调用以及间接来自其他调用的mmap()调用 库调用你的应用程序,而不仅仅是你的应用程序所做的设备的mmap()调用。
例如Linux / glibc,也可能是其他系统,我假设可以编译mmap()
调用来调用mmap64()
,这取决于用于启用大文件支持的编译器标志。您可能需要截取mmap64()
以及mmap()
目前还不清楚你真正想做什么,但你可以
struct stat
。st_mode是否为S_ISCHR()或S_ISBLK()(参见stat手册页)以了解mmap()是否用于设备文件sb.st_rdev
是您感兴趣的主要/次要号码,请采取措施。