你的代码实现了一个简单的文件读写操作,并且使用 dlsym
函数挂钩了 read
和 write
函数以打印读取和写入的数据。但在你的 init_hook
函数中,设置 write_f
的时候却错误地调用了 dlsym(RTLD_NEXT, "read")
,而应该是调用 "write"
。这会导致你的程序在进行写操作时出错,因为没有正确保存原始的 write
函数指针。
以下是修正后的代码示例:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <ucontext.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
ucontext_t ctx[3];
ucontext_t main_ctx;
int count = 0;
// hook
typedef ssize_t (*read_t)(int fd, void *buf, size_t count);
read_t read_f = NULL;
typedef ssize_t (*write_t)(int fd, const void *buf, size_t count);
write_t write_f = NULL;
ssize_t read(int fd, void *buf, size_t count) {
ssize_t ret = read_f(fd, buf, count);
printf("read: %s\n", (char *)buf);
return ret;
}
ssize_t write(int fd, const void *buf, size_t count) {
printf("write: %s\n", (const char *)buf);
return write_f(fd, buf, count);
}
void init_hook(void) {
if (!read_f) {
read_f = dlsym(RTLD_NEXT, "read");
}
if (!write_f) {
// 修复这里,使用 "write"
write_f = dlsym(RTLD_NEXT, "write");
}
}
int main() {
init_hook();
int fd = open("a.txt", O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); // 加上 O_TRUNC 避免重复写入
if (fd < 0) {
perror("Error opening file");
return -1;
}
chmod("a.txt", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
char *str = "1234567890";
write(fd, str, strlen(str));
lseek(fd, 0, SEEK_SET); // 移动文件指针到开头,以便读取刚写入的数据
char buffer[128] = {0};
read(fd, buffer, sizeof(buffer)); // 使用 sizeof(buffer)
printf("buffer: %s\n", buffer);
close(fd); // 别忘了关闭文件描述符
return 0;
}
主要修改点:
- 修正函数指针:在
init_hook
中确保为write_f
正确赋值。 - 添加文件指针移动:在调用
read
之前,添加了一个lseek(fd, 0, SEEK_SET)
来将文件指针移回到开头。这是因为在执行完一次写操作后,文件指针会位于末尾,需要重置它才能从头部读取数据。 - 错误处理:增加了一些错误处理,例如打开文件失败时输出错误信息。
- 清理资源:确保程序结束前关闭打开的文件描述符。
这些更改可以帮助你正确记录读写操作并保证程序正常工作。
内容由零声教学AI助手提供,问题来源于学员提问