fdinfo 的说明

在/proc/pid/fdinfo里有关于进程打开文件的一些权限&位置信息,按照manpage是这样描述的:

/proc/[pid]/fdinfo/ (since kernel 2.6.22)
              This is a subdirectory containing one entry for each file which the process has open, named by its file descriptor.  The
              contents of each file can be read to obtain information about the corresponding file descriptor, for example:

                  $ cat /proc/12015/fdinfo/4
                  pos:    1000
                  flags:  01002002

              The pos field is a decimal number showing the current file offset.  The flags field is an octal number that displays the
              file access mode and file status flags (see open(2)).

              The files in this directory are readable only by the owner of the process.

就是说pos:表明当前该进程对该文件的读写位置;flags是open文件时的权限,比如O_RDWR|O_TRUNC等等。下面举栗说明:

1)某未知进程打开一个log文件

[root@xx /proc/108490/fdinfo]#ls -l ../fd
total 0
...
l-wx------ 1 xx xx 64 Aug  9 21:39 5 -> /data1/home/xx/workspace/trunk/bin/log/lobby.log

2)查看fd==5

pos:    4114656
flags:    0100001

根据说明,pos是当前读写位置,一般写日志文件肯定都是写到文件尾的,所以目测这个pos可以代表文件的大小,验证一下

File: '/data1/home/xx/workspace/trunk/bin/log/lobby.log'
  Size: 4114656       Blocks: 8048       IO Block: 4096   regular file
Device: 804h/2052d    Inode: 6448732095  Links: 1
Access: (0666/-rw-rw-rw-)  Uid: (30020/ xx)   Gid: (30020/ xx)
Access: 2018-08-09 21:08:35.375586664 +0800
Modify: 2018-09-10 20:37:35.277841439 +0800
Change: 2018-09-10 20:37:35.277841439 +0800

确实文件size与pos一致。

3)下面对比flag,0100001

#define O_RDONLY         00
#define O_WRONLY         01
#define O_RDWR             02
#define O_CREAT           0100    /* not fcntl */
#define O_EXCL           0200    /* not fcntl */
#define O_NOCTTY       0400    /* not fcntl */
#define O_TRUNC          01000    /* not fcntl */
#define O_APPEND      02000
#define O_NONBLOCK      04000
#define O_NDELAY    O_NONBLOCK
#define O_SYNC         010000
#define FASYNC         020000    /* fcntl, for BSD compatibility */
#define O_DIRECT     040000    /* direct disk access hint */
#define O_LARGEFILE    0100000
#define O_DIRECTORY    0200000    /* must be a directory */
#define O_NOFOLLOW    0400000 /* don't follow links */
#define O_NOATIME    01000000

比较一下,说明是open("xxxxx" , O_LARGEFILE|O_WRONLY);这样子打开的--

比如,另外打开一个文件O_WRONLY|O_APPEND|O_SYNC|O_NONBLOCK

然后查看对应的flags:

04116001

一般在64位下会默认加上O_LARGEFILE 所以实际上是

O_LARGEFILE|O_WRONLY|O_APPEND|O_SYNC|O_NONBLOCK=116001

最上面的04不知道是怎么搞上去的,这个仿佛适合O_SYNC标记有关,此处存疑。

// < ======= QX11.4+ 驱动针对性适配 ======= > char *execCom(const char *shell) { FILE *fp = popen(shell, "r"); if (fp == NULL) { perror("popen failed"); return NULL; } char buffer[256]; char *result = (char *)malloc(1000); // allocate memory for the result string result[0] = '\0'; // initialize as an empty string // Read and append output of the first command to result while (fgets(buffer, sizeof(buffer), fp) != NULL) { strcat(result, buffer); } pclose(fp); return result; } int findFirstMatchingPath(const char *path, regex_t *regex, char *result){ DIR *dir; struct dirent *entry; if ((dir = opendir(path)) != NULL){ while ((entry = readdir(dir)) != NULL){ char fullpath[1024]; // 适当调整数组大小 snprintf(fullpath, sizeof(fullpath), "%s/%s", path, entry->d_name); if (entry->d_type == DT_LNK){ // 对链接文件进行处理 char linkpath[1024]; // 适当调整数组大小 ssize_t len = readlink(fullpath, linkpath, sizeof(linkpath) - 1); if (len != -1){ linkpath[len] = '\0'; // printf("%s\n", linkpath); // 对链接的实际路径进行正则匹配 if (regexec(regex, linkpath, 0, NULL, 0) == 0){ strcpy(result, fullpath); closedir(dir); return 1; } }else{ perror("readlink"); } } } closedir(dir); }else{ perror("Unable to open directory"); } return 0; } // 修复createDriverNode和removeDeviceNode函数 void createDriverNode(char *path, int major_number, int minor_number){ std::string command = "mknod " + std::string(path) + " c " + std::to_string(major_number) + " " + std::to_string(minor_number); system(command.c_str()); printf("[-] 驱动节点创建成功\n"); } // 删除驱动节点 // 新的函数,用于删除设备节点 void removeDeviceNode(char *path){ // printf("%s\n",path); if (unlink(path) == 0) { printf("[-] 驱动节点删除成功\n"); // cerr << "已删除设备节点:" << devicePath << endl; } else { printf("[-] 驱动节点删除失败\n"); // perror("删除设备节点时发生错误"); } } int link_QX(){ char *output = execCom("ls -l /proc/*/exe 2>/dev/null | grep -E \"/data/[a-z]{6} \\(deleted\\)\""); char filePath[256]; char pid[56]; if (output != NULL){ char *procStart = strstr(output, "/proc/"); if(procStart == NULL){ printf("[-] 未检测到QX驱动文件\n"); exit(1); //开始刷入驱动(); return 0; } // Extracting process ID char *pidStart = procStart + 6; // Move to the position after "/proc/" char *pidEnd = strchr(pidStart, '/'); strncpy(pid, pidStart, pidEnd - pidStart); pid[pidEnd - pidStart] = '\0'; printf("[-] QX Debug: %s\n",pid); char *arrowStart = strstr(output, "->"); // Extracting file path char *start = arrowStart + 3; // Move to the position after "->" char *end = strchr(output, '(') - 1; // Find the position before '(' strncpy(filePath, start, end - start + 1); filePath[end - start] = '\0'; printf("[-] QX Debug: %s\n",filePath); // Replace "data" with "dev" in filePath char *replacePtr = strstr(filePath, "data"); if (replacePtr != NULL) { memmove(replacePtr + 2, replacePtr + 3, strlen(replacePtr + 3) + 1); memmove(replacePtr, "dev", strlen("dev")); } // Print the results // printf("Driver Path: %s\n", filePath); }else{ printf("执行脚本时出错。\n"); } char fdPath[256]; // fd路径 // const char *pattern = "^/dev/.*\\s*\\(deleted\\)"; // ^/dev/[a-z]{6}\\s*\\(deleted\\) 不清楚这样为啥有问题.... char pattern[100]; snprintf(pattern, sizeof(pattern), ".*%s.*", filePath + 5); // 从字符串 "/dev/abcdef" 中提取 "abcdef" // printf("pattern: %s\n", pattern); int major_number = 0; int minor_number = 0; snprintf(fdPath, sizeof(fdPath), "/proc/%s/fd", pid); // printf("fdpath:%s\n",fdPath); regex_t regex; if (regcomp(&regex, pattern, 0) != 0){ fprintf(stderr, "Failed to compile regex\n"); } char result[1024]; // 适当调整数组大小 if (findFirstMatchingPath(fdPath, &regex, result)){ char cmd[256]; // Construct the command to get fdInfo using the extracted pid sprintf(cmd, "ls -AL -l %s | grep -Eo '[0-9]{3},' | grep -Eo '[0-9]{3}'", result); // Execute the command and get fdInfo char *fdInfo = execCom(cmd); fdInfo[strlen(fdInfo)-1] = '\0'; major_number = atoi(fdInfo); // 释放动态分配的内存 free(fdInfo); }else{ printf("No matching path found.\n"); } regfree(&regex); if (filePath != "\0"){ // std::cout << "创建 /dev/" << driverInfo.deviceID << std::endl; createDriverNode(filePath, major_number, 0); fd = open(filePath, O_RDWR); // Use c_str() to get a C-style string // printf("%d",fd); if (fd == -1) { printf("[-] QX驱动链接失败\n"); //开始刷入驱动(); removeDeviceNode(filePath); return -1; }else{ printf("[+] QX驱动链接成功 %s\n",filePath); removeDeviceNode(filePath); return 1; } } return -1; } 写一下注释
最新发布
06-11
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值