2013-03-11 105 views
2

我试图挂接x86_32上的Linux内核v3.5中的sys_execve syscall。我简单地改变sys_call_table的入口地址到我的钩子函数sys_execve挂钩在3.5内核

asmlinkage long (*real_execve)(const char __user*, const char __user* const __user*, 
       const char __user* const __user*); 
... 
asmlinkage long hook_execve(const char __user* filename, const char __user* const __user* argv, 
        const char __user* const __user* envp) 
{ 
    printk("Called execve hook\n"); 
    return real_execve(filename, argv, envp); 
} 
... 
real_execve = (void*)sys_call_table[ __NR_execve ]; 
sys_call_table[ __NR_execve ] = (unsigned long)hook_execve; 

我做一套页面权限修改sys_call_table的条目,并提到方案可以很好地用于其他系统调用(CHDIR,MKDIR等)。但在execve的钩我得到空指针:

Mar 11 14:18:08 mbz-debian kernel: [ 5590.596033] Called execve hook 
Mar 11 14:18:08 mbz-debian kernel: [ 5590.596408] BUG: unable to handle kernel NULL pointer dereference at (null) 
Mar 11 14:18:08 mbz-debian kernel: [ 5590.596486] IP: [< (null)>] (null) 
Mar 11 14:18:08 mbz-debian kernel: [ 5590.596526] *pdpt = 0000000032302001 *pde = 0000000000000000 
Mar 11 14:18:08 mbz-debian kernel: [ 5590.596584] Oops: 0010 [#1] SMP 

我打电话有三个参数,因为arch/x86/kernel/entry_32.S,包含PTREGSCALL3(execve) sys_execve。但是,我试着用四个参数调用它(添加struct pt_regs*),但我得到了同样的错误。也许这种execve方法完全错误?或者我错过了什么?

更新#1

我发现sys_call_table[ __NR_execve ]实际上包含的ptregs_execve(不sys_execve)地址。它被定义为arch/x86/kernel/entry_32.S如下:

#define PTREGSCALL3(name) \ 
ENTRY(ptregs_##name) ; \ 
CFI_STARTPROC; \ 
leal 4(%esp),%eax; \ 
pushl_cfi %eax; \ 
movl PT_EDX(%eax),%ecx; \ 
movl PT_ECX(%eax),%edx; \ 
movl PT_EBX(%eax),%eax; \ 
call sys_##name; \ 
addl $4,%esp; \ 
CFI_ADJUST_CFA_OFFSET -4; \ 
ret; \ 
CFI_ENDPROC; \ 
ENDPROC(ptregs_##name) 
... 
PTREGSCALL3(execve) 

所以为了修改sys_execve我需要而不改变其地址来替换它的代码?我读过类似here的东西,这是要走的路吗?

更新#2

事实上,我发现下面的调用序列:do_execve->do_execve_common->search_binary_handler->security_bprm_check,这是security_bprm_check围绕LSM(Linux安全模块)的操作的包装,其控制一个二进制的执行。之后,我已阅读并遵循this link,我得到了它的工作。它解决了我的问题,因为现在我可以看到要执行的进程的名称,但我仍然不确定它的正确性。也许别人会为这些东西增加一些清晰度。

+0

这篇文章解释了为什么你不能挂钩'经'sys_call_table'修改http://stackoverflow.com/questions/8372912/ sys_execve' hooking-sys-execve-on-linux-3-x/9672512#9672512 – 2013-05-06 10:37:00

+0

@IlyaMatveychikov所以我在3.18上通过sys_call_table在sys_execve上做了一个工作钩子,我做错了什么? – 2014-12-15 00:01:46

+0

@ kagali-san请在系统'sudo grep stub_execve/proc/kallsyms'上运行以下命令? – 2014-12-24 13:10:52

回答

1

过去,在Linux内核中挂接系统调用是一件容易的事,然而,在新内核中,程序集存根被添加到系统调用中。为了解决这个问题,我修补了内核的内存。

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