Dan*_*ish 2 c linux system-calls linux-kernel
我为execve系统调用编写了一个钩子,并在开始时将其编写为 print "hi",每次执行文件时。它工作正常,但是当我尝试打印filename传递给系统调用的内容时,这导致了崩溃,当然我不得不重新启动计算机。
这是我的代码:
static asmlinkage long our_execl(const char __user * filename,
const char __user * const __user * argv,
const char __user * const __user * envp) {
printk("%s\n",filename);
return original_execl(filename, argv, envp);
}
Run Code Online (Sandbox Code Playgroud)
这就是我注入新系统调用的方式:
static int lkm_example_init(void)
{
printk("new new new 2");
write_cr0(read_cr0()&(~ 0x10000));
sys_call_table = (void*)0xdd8c4240//the syscall address from the /proc/kallsyms ;
execl= sys_call_table[__NR_execve];
sys_call_table[__NR_execve]=our_execl;
write_cr0(read_cr0() | 0X10000);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这里最有可能发生的是 SMAP(超级用户模式访问保护)阻止内核访问原始用户空间指针,从而导致恐慌。
从用户空间访问字符串的正确方法是使用strncpy_from_user()first复制其内容。另外,请小心并确保正确终止字符串。
static asmlinkage long our_execl(const char __user * filename,
const char __user * const __user * argv,
const char __user * const __user * envp) {
char buf[256];
buf[255] = '\0';
long res = strncpy_from_user(buf, filename, 255);
if (res > 0)
printk("%s\n", buf);
return original_execl(filename, argv, envp);
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,由于我们专门讨论文件名,因此您可以使用getname()和putname()函数,它们使用struct filename.
static asmlinkage long our_execl(const char __user * filename,
const char __user * const __user * argv,
const char __user * const __user * envp) {
struct filename *fname = getname(filename);
if (!IS_ERR(fname)) {
printk("%s\n", fname->name);
putname(fname);
}
return original_execl(filename, argv, envp);
}
Run Code Online (Sandbox Code Playgroud)