Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Linux x86-64系统调用挂钩,路径名混乱_C_Linux_Linux Kernel_System Calls_Kernel Module - Fatal编程技术网

C Linux x86-64系统调用挂钩,路径名混乱

C Linux x86-64系统调用挂钩,路径名混乱,c,linux,linux-kernel,system-calls,kernel-module,C,Linux,Linux Kernel,System Calls,Kernel Module,我一直在x86_64 Linux系统上试验Linux系统调用挂钩,遵循在/proc/kallsyms中找到的修补sys\u call\u表方法表的标准过程 然而,在我的trampoline中,特别是对于解析文件路径(如openat)的系统调用,makedir我似乎正在检索非人类可读的文件路径,这是由于printk(path),其中path是传递给被拦截的系统调用的确切形式参数 有人能解释为什么我不能从系统调用中截取人类可读的路径名吗?e、 g./usr/home/file.txt 问题绕道:

我一直在x86_64 Linux系统上试验Linux系统调用挂钩,遵循在
/proc/kallsyms
中找到的修补
sys\u call\u表
方法表的标准过程

然而,在我的trampoline中,特别是对于解析文件路径(如openat)的系统调用,makedir我似乎正在检索非人类可读的文件路径,这是由于
printk(path)
,其中path是传递给被拦截的系统调用的确切形式参数

有人能解释为什么我不能从系统调用中截取人类可读的路径名吗?e、 g.
/usr/home/file.txt

问题绕道:

asmlinkage int sys_access_trampoline(const char __user *path, int mode)
{
    char buffer[STR_MAX];
    strncpy_from_user(buffer, path, strnlen_user(path, PATH_MAX+1));
    printk(buffer);  // prints \xe1\xaa\xff\xff\ etc...
    STUB_ORIGIN();
    return sys_access(path, mode);
}

正如Tsyvarev提到的,对于较新的内核版本(>4.17),传递系统调用参数的方式已经改变,并且要求拦截蹦床具有以下特征:

asmlinkage __type__ sys_foobar(const struct pt_regs * regs).
然后通过各自的寄存器访问各个参数,即(x86_64)

因此,要获取access系统调用的路径字符串,可以使用
regs->di

asmlinkage int sys_access_trampoline(const struct pt_regs * regs)
{
    char buffer[STR_MAX];
    strncpy_from_user(buffer, regs->di, strnlen_user(path, PATH_MAX+1));
    printk(buffer);  
    STUB_ORIGIN();
    return sys_access(path, mode);
}
我现在收到正确的ASCII路径名


谢谢大家的帮助

正如Tsyvarev所提到的,对于较新的内核版本(>4.17),系统调用参数的传递方式已经改变,并且要求拦截蹦床具有以下特征:

asmlinkage __type__ sys_foobar(const struct pt_regs * regs).
然后通过各自的寄存器访问各个参数,即(x86_64)

因此,要获取access系统调用的路径字符串,可以使用
regs->di

asmlinkage int sys_access_trampoline(const struct pt_regs * regs)
{
    char buffer[STR_MAX];
    strncpy_from_user(buffer, regs->di, strnlen_user(path, PATH_MAX+1));
    printk(buffer);  
    STUB_ORIGIN();
    return sys_access(path, mode);
}
我现在收到正确的ASCII路径名


谢谢大家的帮助

很可能是您的copy_from_user调用出错。感谢您的回复,我当前的实现:strncpy_from_user(buffer,path,strnlen_user(path,path_MAX+1))似乎正确复制了内存,但是字符串的性质是:\xab\xe1\xaa\xff\xff\xff\xff…请在问题中编辑足够的代码以显示问题。很抱歉,为蹦床动作添加了代码,
strncpy\u from\u user
的第三个参数必须始终是dest的大小,不是源。很可能从用户调用复制\u时出错。感谢您的回复,我当前的实现:strncpy\u from\u user(buffer,path,strnlen\u user(path,path\u MAX+1))似乎正确复制了内存,但是字符串的性质是:\xab\xe1\xaa\xff\xff\xff\xff…请在问题中编辑足够的代码以显示问题。很抱歉,为蹦床动作添加了代码,即
strncpy\u from\u user
的第三个参数必须始终是dest的大小,而不是源的大小。