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