3

我想知道如果从内核(在本例中为 Linux)您在进程上下文(系统调用、页面错误等)中使用 PTRACE_SINGLESTEP 调用 ptrace_request 会发生什么。它会单步执行用户空间指令还是内核空间指令。我意识到 ptrace 只能执行单步用户指令,这就是为什么我对这会产生的行为感到好奇的原因。

只是为了提供更多信息,我试图从页面错误处理程序中执行此操作(单步错误的指令但更改 PTE 以便指令通过)。我想知道这是否可能,或者它是否需要另一种方法来做到这一点,例如重新安排进程运行等....

出现这种情况是因为进程的 task_struct(如果被抢占)仍将指向内核空间处理程序 IIRC,因此使用 ptrace 单步执行是否会绕过此并执行正确的用户空间指令,或者根本不执行?

4

2 回答 2

1

我不完全理解您的意思,PTRACE_SINGLESTEP 总是在用户上下文中从内核调用:当您执行系统调用 ptrace(PTRACE_SINGLESTEP) 时,您最终将在内核上下文中执行该函数,该函数的行为通常和使您正在跟踪的进程执行一条指令,无论您是否从页面错误处理程序调用它。当它像往常一样位于内核域时,您将无法单步执行它。

我建议您查看 arch/x86/kernel/ptrace.c 以了解单个步骤的实际工作原理。单步指令实际上是由内核模拟的,IIRC 对此没有硬件支持。

于 2011-11-07T23:56:26.310 回答
0

要了解您的问题的答案,您需要了解英特尔硬件。

首先我们从最简单的指令开始(因为 SINGLE_STEP 是让 Intel CPU 进入单步模式,执行一个指令后返回中断处理程序):

movl (eax), ebx

按照 Intel 的格式,这意味着取 eax 中的值,将其视为内存指针,访问内存,获取 4 字节值并将其复制到 ebx。

这条 ONE 汇编指令 - 在内核与用户上下文中执行时将具有不同的行为/含义。

如果在内核中,内核的页表将用于访问内存,并将数据复制到 ebx。在一个用户进程中,用户的页表将被使用(通过MMU硬件顺便)从内存中读取数据并复制到ebx。eax 中的值相同,但 CR3 寄存器中的值不同(意味着不同的进程上下文),将触发读取内存的不同部分。所以在内核中跟踪用户空间程序,实在是太可笑了。因为您必须在执行用户指令之前和之后进行上下文切换(涉及整套寄存器存储和恢复操作) - 有效地意味着 4 个操作。

如您所见,我没有像您提到的那样引用任何内核函数 API。总体概念理解是第一位的。

于 2012-01-31T11:14:11.693 回答