【问题标题】:Access scheduled instructions of process in kernel module访问内核模块中进程的调度指令
【发布时间】:2017-10-11 23:51:40
【问题描述】:

我想编写一个内核模块来检查正在运行的进程的预定指令。我已经看过Linux Kernel Process Management,它解释了如何迭代进程。

struct task_struct *task;
for_each_process(task) {
    /* this pointlessly prints the name and PID of each task */
    printk("%s[%d]\n", task->comm, task->pid);
}

但是,一旦我获得了task_struct,我该如何获得说明?我假设我需要先找到程序计数器,看看接下来要执行哪些指令。

我需要检查task_struct 的哪个成员才能按照说明结束?它们存储在哪种struct 类型中?

感谢您的帮助。我对内核编程没有那么丰富的经验。

【问题讨论】:

  • 嗯,用户堆栈指针应该指向下一条要执行的指令被压入的堆栈位置,(或者,至少在它旁边,取决于堆栈的工作方式)。跨度>
  • @ThingyWotsit,好的,听起来不错。有没有办法沿着堆栈“走”?这些说明是否类似于我可以遵循的链接列表?

标签: c linux linux-kernel kernel-module program-counter


【解决方案1】:

我猜这是您的last question 的后续。您是正确的,通过task_struct 您可以访问进程程序计数器(在 x86 上也称为指令指针)。我将回答 x86,因为您表示您有兴趣查找特定于该指令集的指令。

您应该查看文件arch/x86/include/asm/processor.h。它包含很多辅助宏和函数,因此您不必重新发明轮子。您最可能感兴趣的其中之一是task_pt_regs(task)。该宏将为您提供与给定任务相关的所有寄存器值。这些值包含在struct pt_regs 中。你可以在arch/x86/include/asm/ptrace.h 中看到这个结构的定义。您感兴趣的会员是unsigned long ip。

你现在有了一个内存地址,它指向进程要执行的下一条指令。不过,这需要转换为物理地址才能对您可用。这是另一个问题的主题。

一个简短的说明,用于回答您评论中的问题。指令不存储在像链表这样的数据结构中。它们只是一个接一个的序列,所有的操作数。你应该把它想象成一个可以被处理器解析的二进制文件。

【讨论】:

    猜你喜欢
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-18
    • 1970-01-01
    相关资源
    最近更新 更多