非法内存读取或跳转后恢复IP寄存器

Recover IP register after ilegal memory read or jump

指令指针寄存器如何从错误读取或错误跳转中恢复? 内核调用 init 代码,该代码将调用 main() 程序。如果 main() 程序发生堆栈溢出或其他任何情况,并且 RIP/EIP/IP 填满了垃圾,那么 OS 如何恢复 CPU 寄存器?

CPU只有一个指令指针对吧?因此,在我看来,从溢出中恢复似乎是不可能的。

是的,如果 IP 被破坏并导致错误,则只有错误值是已知的。不清楚 "recovering from overflow" 是什么意思。当然,OS 的故障处理程序有一个明确定义的地址,cpu 会去那里,因此从那时起 IP 将得到明确定义。 OS 可能决定终止进程,或者如果程序安装了 signal/exception 处理程序,OS 将确保它被调用。然后,此处理程序可以使用适当的值加载 IP。

当您在用户模式下丢弃 IP 时,最终会发生硬件故障,可能是页面错误、非法操作码或类似的问题。然后处理器切换到 supervisor/kernel 模式并通过将指令指针设置为明确定义的值来启动 运行 故障处理程序。

内核代码将检查异常发生的地址and/or异常的类型。一旦发现是由于其中任何一种原因,内核通常会终止出现故障的用户模式进程。

如果 IP 加载了无法执行的地址,它会触发 EXCEPTION。 CPU 通常识别许多不同类型的异常,它们由不同的数字标识。

当异常发生时,会导致CPU切换到内核模式。这反过来会导致 CPU 使用定义的处理程序地址加载 IP,以处理特定类型的异常并加载内核模式堆栈。

有两种类型的异常:故障陷阱。故障后IP中原有指令可以重新启动。陷阱是致命错误。此时发生的情况取决于异常的类型。

如果是页面错误,处理程序将尝试将页面加载到内存中。

对于大多数其他异常,处理程序将尝试为特定类型的异常找到用户模式处理程序。参见太监中的signal函数