【发布时间】:2015-11-29 05:57:43
【问题描述】:
我想在 do_execve 上设置一个 jprobe 钩子来捕获每个执行的程序。
我的代码在
[ 628.534037] registered: do_execve, ret: 0
[ 723.995797] execve: /usr/bin/vi
[ 726.807025] execve: /bin/dmesg
在 4.1 内核上,我的结果相同(所有内容都已注册)但没有“execve”:
[ 8621.430568] registered: do_execve, ret: 0
这是我的代码:
static struct jprobe jprobe_hooks[] = {
{
.entry = jdo_execve,
.kp = { .symbol_name = "do_execve" }
}};
static long jdo_execve(const char *filename, const char __user *const __user *argv, const char __user *const __user *envp, struct pt_regs *regs)
{
printk(KERN_INFO "execve: %s", filename );
}
//
// registration
//
int ret, x, reg_error;
reg_error = 0;
for (x = 0; x < sizeof(jprobe_hooks) / sizeof(jprobe_hooks[0]); x++)
{
ret = register_jprobe(&jprobe_hooks[x]);
if (ret < 0)
{
printk(KERN_INFO "register_jprobe failed, returned %d, item: %s\n", ret, jprobe_hooks[x].kp.symbol_name);
reg_error++;
}
else
{
printk(KERN_INFO "registered: %s, ret: %u\n", jprobe_hooks[x].kp.symbol_name, ret);
}
}
当我在 kallsyms 上执行 grep 时,我得到了 3.2:
grep do_execv /proc/kallsyms
ffffffff81100650 T do_execve
在 4.2 上:
grep do_execv /proc/kallsyms
ffffffff811d2950 T do_execve
ffffffff811d2980 T do_execveat
我什至尝试将函数(因为 do_execve 原型已更改)更改为:
static int jdo_execve(struct filename *fname, const char __user *const __user *__argv, const char __user *const __user *__envp)
{
int i = 0;
printk(KERN_INFO "execve: %s ", fname->name );
}
即使这样也无济于事。
我可以在 do_fork 或 sys_open 等其他函数上设置挂钩,但不能在 do_execve 上设置。为什么?有人有想法吗?为什么它不再工作了?
编辑:
我也在挂钩 do_execveat:
static int jdo_execveat(int fd, struct filename *fname, const char __user *const __user *__argv, const char __user *const __user *__envp, int flags)
【问题讨论】:
-
可能,新内核的
libc使用execveat系统调用而不是execve之一。您还需要挂钩do_execveat以执行 catch 程序。 -
我也喜欢 jdo_execveat :(
标签: linux linux-kernel execve kprobe jprobe