关于Hook unistd中open, read, write, close的一些技巧
程序员文章站
2022-05-30 14:05:32
...
open , read, write, close, flock, fileno, lseek, lseek64, 这些都是使用一个int的文件描述符的,对于我们hook的时候,一般来说,我们是想在open这里,我们去打开一个自己的文件,可能这个并不是一个真实的文件,如这个我们需要维护一个类的指针,我们必须用一个整数去关联这个这个指针,因为返回值,我们只能是整型,fd这个东西是一个整数,它有自己的规则,又是系统维护的,我们必须返回一个整数和系统不冲突或重复的,我们才能在后面的read, write这里判断出这个整数是我们的自己的东西,还是系统的东西。
一开始我是自己自增的去维护这个整数,把所以的无论是自己的,还是系统都是再进行重新映射。但是,实际情况中发现的,还有一些fd并不能全部hook住,有一些函数也不好hook, 如fcntl和ioctl这里,是有可参数的,我们要转发这些函数,必须要使用汇编来操作,这个就相当麻烦了。
经过一天的思考,我搞了一个比较完美的办法,就是id全部使用系统的来生成,我们都打开一下当前路径"."去申请一个fd, 这样我们就不怕hook漏掉了失去控制了。
测试代码:
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main(int argc, char** argv)
{
int userPermissions = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
int i=0;
int n = 100;
int * fds = malloc(sizeof(n)*n);
for(i=0;i<n;i++)
{
//打开当前目录,这个肯定是所有系统都有可读权限的。
fds[i] = open(".",O_RDONLY|O_DIRECTORY,userPermissions);
}
for(i=0;i<n;i++)
{
printf("%d \n", fds[i]);
close(fds[i]);
}
return 0;
}
实际代码示意:
int open_hook(const char *pathname, int flags, mode_t mode)
{
int fd= -1;
void * xfd=NULL;
if(flags==O_RDONLY && (xfd = open_our_file(pathname))!=NULL)
{
fd =createMappedFileDesc(xfd);
}
else
{
fd = open(pathname,flags, mode);
}
return fd;
}
int read_hook(int fd, ....)
{
void * xfd=NULL;
if((xfd = GetMappedfd(fd) ) !=NULL)
{
return our_read_func(xfd,...);
}
return read(fd,...);
}