rootkit的c-getdents()系统调用实现



我计划为我的rootkit挂接我自己版本的getdents((。代码在这里:

asmlinkage int new_getdents(unsigned int fd, struct linux_dirent *dirp, unsigned int count)
{
int nread;
int bpos;
struct linux_dirent *d;
int (*orig_func)(unsigned int fd, struct linux_dirent *dirp, unsigned int count);
t_syscall_hook *open_hook;
open_hook = find_syscall_hook(__NR_getdents);
orig_func = (void*) open_hook->orig_func;
nread = (*orig_func)(fd, dirp, count);
d = dirp;
for (bpos = 0; bpos < nread;) {
d = (struct linux_dirent *) ((char*)dirp + bpos);
printk(KERN_INFO "%sn", d->d_name);
bpos += d->d_reclen;
}
return nread;
}

我不理解这行中的类型转换:d = (struct linux_dirent *) ((char*)dirp + bpos);

ddirp都为linux_dient结构保留内存地址。d_reclen包含条目的长度。如果我们以3、5、7的形式接收d_reclen,则条目将出现在dirp、dirp+3/size(linux_dient(、(dirp+3-size(linux_Dient(+5/size(linux _dient((。。。

所以这条线应该是这样的:d = (struct linux_dirent *) ((dirp + bpos)/size(linux_dirent));

为什么我们要转换为(char*(?

typedef struct {
unsigned long   d_ino;
unsigned long   d_off;
unsigned short  d_reclen;
char            d_name[1];
} linux_dirent;

所以这行应该是这样的:d=(struct linux_dirent*(((dirp+bpos(/size(linux_dirent((;

No-dirp / sizeof(linux_dirent)没有什么意义,dirp0的偏移与结构的大小无关。将内存地址除以结构的大小。。。只是一些不相关的地址。

您的意思是,只将与内存位置的偏移量分开,然后将结果指针添加到指针中。嗯,沿着:

(char*)dirp + ((char*)(dirp + bpos) - (char*)dirp)/sizeof(linux_dirent)
^^^^^^^^^^^                                       = (char*)dirp + bpos * sizeof(linux_dirent)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                        = bpos * sizoef(linux_dirent)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  = bpos
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  = (char*)dirp + bpos

但是。。。您可以按1字节的步长递增dirp指针,而不是按sizeof(linux_dirent)的步长递增。这就是char*的演员们正在做的事情。CCD_ 13总是CCD_。以下值正确:

dirp + bpos == (char*)dirp + bpos * sizeof(linux_dirent)

为什么要转换为(char*(?

我们正在转换为char *,以更改+运算符将增加的字节数。简称:

int *a = 20;
a + 5 == 20 + 5 * sizeof(int)
(char*)a + 5 == 20 + 5 * sizeof(char)   // sizeof(char) = 1, so:
(char*)a + 5 == 25

指针算法是一个很好的研究课题。

最新更新