【问题标题】:thread fs segment register switching between user and kernel land线程 fs 段寄存器在用户和内核空间之间切换
【发布时间】:2013-02-26 06:01:20
【问题描述】:

fs 段寄存器如何指向 TEB 和 KPCR。这些数据结构是否保存在线程用户和内核堆栈中?那么,当线程上下文从用户切换到内核时,包含 TEB 指针的 fs 段寄存器被保存到线程用户堆栈中,然后指向 KPCR 的内核 fs 段寄存器被加载回fs 段寄存器? fs 段寄存器是这样指向 TEB 和 KPCR 的吗?

【问题讨论】:

  • 你的实际编程问题是什么?这听起来像是无聊的好奇心。
  • 就是这样。我正在阅读一篇文章,其中指出 fs 段寄存器指向 KPCR 和 TEB

标签: windows multithreading kernel


【解决方案1】:

FS 寄存器在LDTGDT(本地/全局段描述符表)中有一个与之关联的段基地址。 FS 几乎是描述符表的索引,它选择表中定义的段之一。

当您通过FS(在指令中使用FS 段覆盖前缀)访问内存时,您访问的内存等于指令中的地址加上段基址的虚拟地址地址。

该段基地址必须与线程特定控制数据结构的位置一致。因此,当使用其特定的控制数据结构创建线程时,会将基设置为指向该数据。

对于同一进程中的不同线程,这些位置是不同的,因为它们都共享内存并且不应该跨入彼此的结构。上下文切换要么只是更新FS 以指向不同的段,要么更新描述符表中段的基地址,然后重新加载FS,以便CPU 观察到变化。

当线程从用户模式转换到内核模式时,FS 及其指向的内容不受内核 POV 的信任,我希望内核重新加载 FS 并使用指向内核端线程的值-特定的数据结构。在回来的路上,应该恢复用户模式FS。实际上,事情可能会稍微复杂一些,但这应该会给您一个想法。

在 64 位模式下,您甚至可以使用 SWAPGS 指令快速交换 GS 寄存器的内容,其作用类似于 32 位模式下的 FS

【讨论】:

  • 感谢 Alexey,所以我假设在环之间切换时这些值会被弹出并推送到线程用户和内核堆栈上。由于 KPCR 维护了诸如上一个、当前和下一个调度线程之类的详细信息,我认为这将有自己的永久段寄存器,不会更改。
【解决方案2】:

所以fs段寄存器肯定指向kpcr。查看windbg并发出“dt nt!_kpcr”后,kpcr中的第一个结构是NtTib或TEB中的第一个结构,所以当人们说fs指向KPCR和TEB时,fs实际上指向KPCR和TIB/TEB是KPCR 中的第一个数据结构。

【讨论】:

    猜你喜欢
    • 2011-12-16
    • 1970-01-01
    • 2012-03-02
    • 2019-12-16
    • 1970-01-01
    • 2012-02-03
    • 2018-06-08
    • 2016-10-12
    • 1970-01-01
    相关资源
    最近更新 更多