首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >jprobe do_execve不适用于内核4.1

jprobe do_execve不适用于内核4.1
EN

Stack Overflow用户
提问于 2015-09-03 19:56:28
回答 1查看 584关注 0票数 1

我想在do_execve上设置一个jprobe钩子来捕获每个执行的程序。

我的代码在debian 3.2linux内核( <= )上工作。这是我在linux内核3.2上的输出:

代码语言:javascript
运行
复制
[  628.534037] registered: do_execve, ret: 0
[  723.995797] execve: /usr/bin/vi
[  726.807025] execve: /bin/dmesg

在4.1内核上也有同样的结果(所有东西都注册了),但是没有"execve":

代码语言:javascript
运行
复制
[ 8621.430568] registered: do_execve, ret: 0

这是我的代码:

代码语言:javascript
运行
复制
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:

代码语言:javascript
运行
复制
 grep do_execv /proc/kallsyms
 ffffffff81100650 T do_execve

在4.2上:

代码语言:javascript
运行
复制
grep do_execv /proc/kallsyms
ffffffff811d2950 T do_execve
ffffffff811d2980 T do_execveat

我甚至尝试将函数更改为以下代码(因为do_execve原型已更改):

代码语言:javascript
运行
复制
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:

代码语言:javascript
运行
复制
 static int jdo_execveat(int fd, struct filename *fname, const char __user *const __user *__argv, const char __user *const __user *__envp, int flags)
EN

回答 1

Stack Overflow用户

发布于 2015-09-07 18:09:20

有几个问题可能会阻止您使用jprobe消息:

  1. 您不会以换行符结束打印消息printk(KERN_INFO "execve: %s", filename );,因此不会刷新日志缓冲区。
  2. API已更改。现在do_execve有了filename参数,因为jprobe代码很愚蠢:没有模块条目,jprobe例程必须以jprobe_return()调用结束,依此类推。查看位于"samples/kprobes"

的内核源代码树中的示例

试着修复它--也许它会有所帮助。

不管怎么说,我自己试过了-- here是代码--确实,看起来很奇怪。当我加载这个模块时,它注册了2个jprobes -一个用于do_execve,另一个用于do_execveat。但是当我执行程序时,我看不到任何消息。,但我看到的是这样的周期性消息:

代码语言:javascript
运行
复制
jprobe: execve: /usr/lib/systemd/systemd-cgroups-agent

这意味着jprobe本身可以工作,但并不是对每个execve调用都有效。

因此,我编写了a simple C program来调用execve,以确保它真的被调用了,但除了systemd-cgroups-agent之外,我仍然什么都没有发生。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32374952

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档