内核模块打印进程线程PID信息

challenge: 编写一个KO,传入一个PID模块参数,打印进程得父PID, 以及所有线程PID

        好久没有碰内核驱动,突然要写一个KO文件,并实现PID的打印功能,还是内心慌得一批。话不多说,直接开撸~

        首先题目是要实现一个KO文件,那么首先要做的就是先具备一个linux调试环境(我这边测试在VM-ware虚拟机上面), 源码部分先上链接https://gitee.com/badbadguys

        内核驱动模块初始化离不开module_init,module_exit这两个宏,关于module_init/exit这两个宏的解释这里不再多说。

        为了能够在应用程序中,动态的传入PID参数,这里内核模块注册为一个字符驱动,关于字符驱动的学习,bilibili也是一个不错的学习途径linux的字符驱动 

        按照传统字符驱动的框架,搭建好我们的内核驱动模块,现在要对传入参数进行处理,也就是我们打印PID的核心代码。

static int print_pid_operation(int input_pid)

{

    struct pid *current_pid = find_get_pid(input_pid);

    struct task_struct *current_task = pid_task(current_pid, PIDTYPE_PID);//获取进程任务描述符

    struct pid* parent = get_task_pid(current_task->parent, PIDTYPE_PID);//获取进程pid描述符

    pr_info("parent pid: %d\n", pid_nr(parent));

    struct task_struct *t = current_task;

    while((t=next_thread(t)) != current_task) {

        struct pid* pid = get_task_pid(t, PIDTYPE_PID);//获取线程pid描述符

        pr_info("thread pid: %d\n", pid_nr(pid));

    }

    return 0;

}

        其中比较关键的几个内核函数:

        input_pid是从应用程序侧获取到的PID参数;

        find_get_pid函数用来根据PID值,获取struct *pid结构体;

        pid_task获取已知pid,获取对应的task结构体;

        next_thread获取进程的线程task结构体;

        pid_nr返回入参为struct pid*,对应的pid值;


最后进行测试环节:

1. 编译内核模块,并安装内核模块(insmod, rmmod)。

2. 编译client测试程序:gcc test.c生成可执行文件a.out

3. ps -ef寻找一个系统正在运行的程序,这里以chrome为例,chrome的进程号为34063

4. sudo ./a.out 34063

5. 使用dmesg输出内核模块打印信息,并使用ps -T -p 34063对比线程打印信息是否一致

上图:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。