我是一名正在研究Linux进程的学生,我需要了解更多关于它们的知识才能继续我的实验。在网上阅读几本书和一些东西时,我遇到了
task_struct
,我不确定我是否完全理解,并且希望确认/纠正我现有的想法。
据我所知,
task_struct
是充当进程描述符的C结构,保存内核可能需要了解的有关进程的所有信息。在进程内核堆栈的末尾有另一个结构体thread_info
,它有一个指向进程的指针task_struct
。
另一个问题:如何访问进程的
task_struct
?有没有计算找到它thread_info
的位置?内核中有宏/函数吗?
是的,
task_struct
结构包含有关进程的所有信息。您可以使用 current
宏获取指向描述当前进程的结构的指针,如下所示:
struct task_struct *p = current;
如果您想获取描述给定
pid
的流程的结构,您可以使用 find_task_by_vpid
函数,如下所示:
read_lock(&tasklist_lock);
p = find_task_by_vpid(pid);
if (p) get_task_struct(p);
read_unlock(&tasklist_lock);
if (p == NULL) {
// Task not found.
}
// Later, once you're finished with the task, execute:
put_task_struct(p);
最后,如果你想迭代所有进程,你可以使用
for_each_process
,如下所示:
read_lock(&tasklist_lock);
for_each_process(p) {
// p is a pointer to a task_struct instance.
}
read_unlock(&tasklist_lock);
如果您希望对任务列表进行独占访问,以便能够更改结构中的一个或多个字段,则必须使用
write_lock_irqsave
而不是 read_lock
。
让我尝试回答第二个问题。
在每个进程内核堆栈的顶部都有一个结构体thread_info。
要获取thread_info的地址/指针,不同的架构有不同的解决方案,但在x86上它看起来像这样:
要获取指向 thread_info 的指针,只需屏蔽堆栈指针值的 13 位:
movl $0xFFFFE000, %eax
andl %esp, %eax
现在我们有了指针,并且该结构体具有指向 task_struct 结构体的指针。
为了得到它,有一个 current 宏,看起来像这样:
#define current (current_thread_info()->task)
它给你指针(地址)task_struct
这是一个内核模块的示例,它使用
task_struct
来确定在模块插入时是否存在某个特定名称的进程:
/*
* File Name : test.c
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm_types.h>
#include <linux/sched/signal.h>
rwlock_t tasklist_lock;
static int __init Init(void){
struct task_struct *p = current;
read_lock(&tasklist_lock);
for_each_process(p){
if(!strncmp((const char *)p->comm, "Slay999", 16)){
printk(KERN_INFO "Found target program\n");
break;
}
}
read_unlock(&tasklist_lock);
return 0;
}
static void __exit Exit(void){
printk(KERN_INFO "Module removed.\n");
}
MODULE_DESCRIPTION("Experements in privlege escalation.");
MODULE_AUTHOR("a name");
MODULE_LICENSE("GPL");
MODULE_VERSION("0.0");
module_init(Init);
module_exit(Exit);
通过获取指向有效
task_struct
地址的指针,我们可以获得有关进程的信息,然后将其用于统计目的和重新配置目的。
例如,您可以使用以下 bash 命令查看
task_struct
的完整定义(可通过 apt-get install pahole
获得):
pahole -C task_struct
一些简短的旁注;
current
我相信包含活动内核进程的数据。task_struct.comm
,显示为p->comm
,包含正在运行的程序的名称。pid
的变量,其中包含进程 ID,还存在一个直接使用 task_struct
获取指向 pid_t
的指针的函数。task_struct
结构中的变量,您可以获得诸如struct mm_struct *active_mm
之类的东西,据我了解,它可以为您提供正在运行的进程的当前内存地址。这是该模块附带的 make 文件:
obj-m += test.o
all:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean