我想覆盖netstat-Tunap的读取函数,当我为netstat-Tunap运行strace时,我感兴趣的覆盖部分就是这里的这一部分,



openat(AT_FDCWD, "/proc/net/tcp", O_RDONLY) = 3
read(3, "  sl  local_address rem_address "..., 4096) = 300
write(1, "tcp        0      0 192.168.32.1"..., 101tcp        0      0 192.168.32.128:59904    192.168.32.129:9001     ESTABLISHED 17186/python ) = 101
read(3, "", 4096)                       = 0
close(3)

我想要的是在这里查看这行缓冲区的内容

read(3, "  sl  local_address rem_address "..., 4096) = 300

但是我LD_PREALOADING的读取库只给我打印文件描述符为5的读取缓冲区,文件描述符为5的读取是这样的

read(5, "unconfined\n", 4095)           = 11

我如何修复它,让它也打印文件描述符为3的缓冲区?

这是我在图书馆使用的程序,

#define _GNU_SOURCE
#include <stdio.h>
#include <dlfcn.h>
#include <unistd.h>

static ssize_t (*read_original)(int fd, void *buf, size_t count) = NULL;

ssize_t read(int fd, void *buf, size_t count) {
    ssize_t result;

    // Initialize the original read function if it hasn't been already
    if (!read_original) {
        read_original = dlsym(RTLD_NEXT, "read");
        if (!read_original) {
            fprintf(stderr, "Error: Unable to load the original read function\n");
            return -1;
        }
    }

    // Call the original read function
    result = read_original(fd, buf, count);

    // Print the buffer's contents for non-zero reads
    if (result > 0 && (fd == 3 || fd == 4 || fd == 5)) {
        printf("Read from fd %d, %zd bytes: ", fd, result);
        for (ssize_t i = 0; i < result; ++i) {
            printf("%02x ", ((unsigned char *)buf)[i]);
        }
        printf("\n");
    }

    return result;
}

我创建的库如下所示

gcc -shared -fPIC -o hider.so hide_read4.c -ldl

我就是这样经营的

LD_PRELOAD=/path/to/lib/hider.so netstat -tunap

这是我运行此命令时的输出

Read from fd 5, 11 bytes: 75 6e 63 6f 6e 66 69 6e 65 64 0a 
Read from fd 5, 11 bytes: 75 6e 63 6f 6e 66 69 6e 65 64 0a 
Read from fd 5, 11 bytes: 75 6e 63 6f 6e 66 69 6e 65 64 0a 
(Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.)
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 ip1:59904    ip2:9001     ESTABLISHED 17186/python        
udp        0      0 ip1:68       ip3:67       ESTABLISHED -

推荐答案

在本例中,netstat使用fgets()来读取/proc/net/tcp中的行.使用ltrace netstat -tunap工具,strace输出中的这些调用:

openat(AT_FDCWD, "/proc/net/tcp", O_RDONLY) = 3
read(3, "  sl  local_address rem_address "..., 4096) = 300
write(1, "tcp        0      0 192.168.32.1"..., 101tcp        0      0 192.168.32.128:59904    192.168.32.129:9001     ESTABLISHED 17186/python ) = 101
read(3, "", 4096)                       = 0
close(3)

映射到以下库调用:

fopen64("/proc/net/tcp", "r")                                                               = 0x564c3a8172a0
setvbuf(0x564c3a8172a0, 0x564c3a81a8a0, 0, 4096)                                            = 0
fgets("  sl  local_address rem_address "..., 8192, 0x564c3a8172a0)                          = 0x7fff68214ac0
feof(0x564c3a8172a0)                                                                        = 0
  .
  .
  .
fgets("  28: 9801A8C0:A6D4 6310FB8E:01B"..., 8192, 0x564c3a8172a0)                          = 0
feof(0x564c3a8172a0)                                                                        = 1
fclose(0x564c3a8172a0)                                                                      = 0

C++相关问答推荐

C中的__attributor__((aligned(4),packed))与 struct 的用法

丑陋的三重间接:可扩展的缓冲区管理 struct

MISRA C:2012 11.3违规强制转换(FLOAT*)到(uint32_t*)

如何将已分配的数组(运行时已知的大小)放入 struct 中?

为什么在Linux(特别是Ubuntu 20.04LTS)上,POSIX共享内存对象在重启后仍然存在,然后突然变成了根用户?

为什么删除CAP_DAC_OVERRIDE后创建文件失败?

Ruby C Api处理异常

为什么该函数不将参数值保存到数据 struct 中?

平均程序编译,但结果不好

如何在C中只对字符串(包含数字、单词等)中的数字进行重复操作?

GTK函数调用将完全不相关的char* 值搞乱

处理来自浏览器的HTTP请求

如何使用唯一数字对整型进行分区

错误...的多个定义(&Q)首先在这里定义&

我正在try 将QSORT算法实现为C++中的泛型函数

生产者消费者计数器意外输出的C代码

如何在C宏定义中包含双引号?

在printf()中用%.*S格式填充长度为0的字符串是否会调用任何UB?如果是,是哪一个?

Linux/C:带有子进程的进程在添加waitid后都挂起

Linux memcpy 限制关键字语法