关于Hook unistd中open, read, write, close的一些技巧

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,...);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章