在Linux 3.x上挂钩sys_execve()

我试图通过修改系统调用表来挂钩Linux 3.x内核上的sys_execve()函数。 问题是sys_execve()只应在执行失败时返回错误代码。 使用我正在使用的包装器函数(见下文),当在有效的可执行文件上调用sys_execve()时,它执行正常并且一切正常。 但是,当调用不存在的文件或导致错误情况的其他内容时,调用程序将崩溃:

 segfault at 3b ip 000000000000003b... 

使用strace来检查钩子sys_execve()的返回值,显示-1或ENOSYS而不是正确的错误代码,这让我感到困惑,因为我检查了我的包装器函数的程序集以及sys_execve()的Linux源代码。 有关为什么我的包装器没有正确传递错误代码的任何建议?

 asmlinkage long new_execve(const char* name, const char const** argv, const char const** envp, struct pt_regs* regs) { return orig_func(name, argv, envp, regs); } 

你不能通过修改系统调用表来挂钩execve ,就像在x86_64上从stub_execve调用sys_execve stub_execve 。 所以调用链是sys_call_table[NR_execve] -> stub_execve -> sys_execve -> do_execve …看看LXR上的stub_execve 。

在过去,在Linux内核中挂钩系统调用是一项更容易的任务,但是,在较新的内核中,程序集存根被添加到系统调用中。 为了解决这个问题,我动态修补了内核的内存。

你可以在这里查看我的完整解决方案来挂钩sys_execve: https : //github.com/kfiros/execmon