【问题标题】:Getting the actual executable path of current process context - Linux kernel获取当前进程上下文的实际可执行路径——Linux内核
【发布时间】:2015-02-21 18:44:31
【问题描述】:

我正在尝试通过我的内核驱动程序获取正在运行的进程的实际可执行路径。

我做了以下事情:

static struct kretprobe do_fork_probe = {
    .entry_handler = (kprobe_opcode_t *) process_entry_callback,
    .handler = (kprobe_opcode_t *) NULL,
    .maxactive = 1000,
    .data_size = 0
};

do_fork_probe.kp.addr =     (kprobe_opcode_t*)kallsyms_lookup_name("do_fork");

if ((ret = register_kretprobe(&do_fork_probe)) < 0)
    return -1; 

static int process_entry_callback(struct kretprobe_instance *ri, struct pt_regs *regs)
{

    printk("Executable path = %s\n", executable_path(current));
    return 0;
}

executable_path 函数:

char* executable_path(struct task_struct* process)
{
#define PATH_MAX 4096
char* p = NULL, *pathname;
struct mm_struct* mm = current->mm;
if (mm)
{
    down_read(&mm->mmap_sem);
    if (mm->exe_file) 
    {
        pathname = kmalloc(PATH_MAX, GFP_ATOMIC);
        if (pathname)
            p = d_path(&mm->exe_file->f_path, pathname, PATH_MAX);            
    }
    up_read(&mm->mmap_sem);
} 

return p;
}

问题是,如果我使用 bash 运行可执行文件,如下所示:

./execname

我得到以下输出:

Executable path = /bin/bash

虽然我真正想要的是 : execname(实际上是它的完整路径,但让我们从名称开始)

有什么建议吗?

【问题讨论】:

  • 你使用的是printk(),可能得不到p指向的完整路径,因为字符串中'/bin/bash'后面可能有'\n',printk在它看到了新行。只是猜测。

标签: c linux linux-kernel


【解决方案1】:

不清楚你想得到什么,所以这里是选项列表:

  • execname SystemTap 认为它。简单的process-&gt;comm 就足够了。这就是内核中定义comm字段的方式:

    char comm[TASK_COMM_LEN]; /* executable name excluding path
                                - access with [gs]et_task_comm (which lock
                                it with task_lock())
                                - initialized normally by setup_new_exec */
    

    但是如果bash 是一个符号链接,那么 comm 应该包含符号链接的名称,而不是真正的可执行文件名称。

  • argv[0] 在我的应用程序中看到的命令行参数数组的第一个元素(并且可能会被它更改)。内核中有get_cmdline()函数,但是好像没有导出。

  • 完整路径的基本名称。这种情况下不要调用d_path,直接取dentry的d_name字段即可:

    strlcpy(pathname, mm->exe_file->f_path->d_name, PATH_MAX);
    

但这听起来像是一个 XY 问题。您试图获取所有分叉进程的可执行名称?为什么不直接使用SystemTap

# stap -v -e 'probe scheduler.process_fork { println(execname()); }'

【讨论】:

  • 为什么不装订?因为 OP 可能想要获取 exec 信息并在内核空间内对其进行处理,而 stap 是用户空间。
  • @icdevppl: 实际上 SystemTap 生成内核模块
猜你喜欢
  • 2012-05-10
  • 1970-01-01
  • 1970-01-01
  • 2018-10-17
  • 2014-05-26
  • 2013-09-22
  • 1970-01-01
  • 1970-01-01
  • 2017-04-16
相关资源
最近更新 更多