当前位置:   article > 正文

内核驱动获取所有进程的cmdline_内核获取其他进程信息

内核获取其他进程信息

内核驱动获取所有进程的cmdline

一、用户态获取进程的cmdline

# 查看/proc/pid/cmdline文件即可
$cat /proc/pid/cmdline
  • 1
  • 2

二、内核态获取进程cmdline

for_each_process

用于遍历Linux所有进程

#define for_each_process(p) \
        for (p = &init_task ; (p = next_task(p)) != &init_task ; )
  • 1
  • 2
get_cmdline
root@curtis-Aspire-E5-471G:/home/curtis/# cat /proc/kallsyms | grep get_cmdline
ffffffffb5c7c1e0 T get_cmdline
ffffffffb65a669c t get_cmdline.cold
  • 1
  • 2
  • 3
函数原型
/**
 * get_cmdline() - copy the cmdline value to a buffer.
 * @task:     the task whose cmdline value to copy.
 * @buffer:   the buffer to copy to.
 * @buflen:   the length of the buffer. Larger cmdline values are truncated
 *            to this length.
 *
 * Return: the size of the cmdline field copied. Note that the copy does
 * not guarantee an ending NULL byte.
 */
int get_cmdline(struct task_struct *task, char *buffer, int buflen)
{
        int res = 0;
        unsigned int len;
        struct mm_struct *mm = get_task_mm(task);
        unsigned long arg_start, arg_end, env_start, env_end;
        if (!mm)
                goto out;
        if (!mm->arg_end)
                goto out_mm;    /* Shh! No looking before we're done */

        spin_lock(&mm->arg_lock);
        arg_start = mm->arg_start;
        arg_end = mm->arg_end;
        env_start = mm->env_start;
        env_end = mm->env_end;
        spin_unlock(&mm->arg_lock);

        len = arg_end - arg_start;

        if (len > buflen)
                len = buflen;

        res = access_process_vm(task, arg_start, buffer, len, FOLL_FORCE);

        /*
         * If the nul at the end of args has been overwritten, then
         * assume application is using setproctitle(3).
         */
        if (res > 0 && buffer[res-1] != '\0' && len < buflen) {
                len = strnlen(buffer, res);
                if (len < res) {
                        res = len;
                } else {
                        len = env_end - env_start;
                        if (len > buflen - res)
                                len = buflen - res;
                        res += access_process_vm(task, env_start,
                                                 buffer+res, len,
                                                 FOLL_FORCE);
                        res = strnlen(buffer, res);
                }
        }
out_mm:
        mmput(mm);
out:
        return res;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

这个函数虽然不是内核导出函数,可以参考文章:Linux内核未导出符号使用方法_Configure-Handle的博客-CSDN博客

三、驱动实现源码
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/kallsyms.h>

#define PARM_LENTH 256

static int (*get_cmdline_fn)(struct task_struct *task, char *buffer, int buflen);
//static unsigned long (*kallsyms_lookup_name_fn)(const char *name);

/* 将获取的buffer中的 ‘\0’替换成空格 */
static void deal_raw_cmdline(char *buffer, unsigned int length)
{
        int i = 0;
        for (i = 0; i < length; i ++) {
                if (buffer[i] == '\0') {
                        buffer[i] = ' ';
                }
        }
}

static int __init query_process_param_init(void)
{
        int ret = 0;
        struct task_struct *tsk = NULL;
        char buffer[PARM_LENTH] = {0};

#if 0
        /* 使用命令cat /proc/kallsyms | grep kallsyms_lookup_name 获取内核函数地址 */
        kallsyms_lookup_name_fn = (unsigned long (*)(const char *))0xffffffffab563dd0;

        /* 这里无法用kallsyms_lookup_name获取函数get_cmdline的地址 */
        get_cmdline_fn = (int (*)(struct task_struct *, char *, int))
                        kallsyms_lookup_name_fn("get_cmdline");
        if (get_cmdline_fn == NULL) {
                printk("Get func get_cmdline address failed\n");
        }
#endif
        /* 采用直接赋值的方法获取函数地址 */
        get_cmdline_fn = (int (*)(struct task_struct *, char *, int))0xffffffffab67c230;

        rcu_read_lock();
        for_each_process(tsk) {
                printk("pid -> %d comm -> %s\n", tsk->pid, tsk->comm);
                if (tsk->mm == NULL) {
                        continue;
                }

                memset(buffer, 0, sizeof(buffer));
                ret = get_cmdline_fn(tsk, buffer, sizeof(buffer));
                if (ret < 0) {
                        continue;
                }
                deal_raw_cmdline(buffer, sizeof(buffer));

                printk("param : %s\n", buffer);
        }
        rcu_read_unlock();

        return 0;
}

static void __exit query_process_param_exit(void)
{
        printk("Query process param exit!\n");
}

module_init(query_process_param_init);
module_exit(query_process_param_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("curtis");
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73

为什么使用kallsyms_lookup_name()找到函数get_cmdline()地址?

[ 1415.524181] pid -> 1344 comm -> ibus-extension-
[ 1415.524186] /usr/libexec/ibus-extension-gtk3                                                                                                                       
[ 1415.524189] pid -> 1346 comm -> ibus-x11
[ 1415.524195] /usr/libexec/ibus-x11 --kill-daemon                                                                                                                    
[ 1415.524198] pid -> 1350 comm -> ibus-portal
[ 1415.524203] /usr/libexec/ibus-portal                                                                                                                               
[ 1415.524206] pid -> 1361 comm -> at-spi2-registr
[ 1415.524212] /usr/libexec/at-spi2-registryd --use-gnome-session 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/183420
推荐阅读
相关标签
  

闽ICP备14008679号