查看原文
其他

新手分享 | 再谈FS寄存器

Cestlavie呀 看雪学院 2019-05-26



关于FS寄存器与分析环境 



历史:在80386及之后的处理器 又增加了两个寄存器 FS 寄存器和 GS寄存器

环境:win7 32位(单核)  

工具:windbg 、OD



一、FS 寄存器到底指向哪里?



通OD 在3环下查看 FS 为3B


 

windbg 查看 0环下 FS 为30

               


1)0环下的FS

         

首先我们先看下 0环下的FS

         

通过intel 手册 看下 段选择子的结构

       

     

根据这个结构 我们对 30 进行拆分

index        TI         RPL
00110        0          00

可以看到 使用的 是GDT表 而GDT表的索引 是 6   

                


根据索引 找到 GDT 表中的内容   834093f3`4c003748


段描述符的结构在进行拆分 (在windbg可以使用 dg 命令 进行 查看   后来才看到)

             


最终找到 0环下 FS 指向的内容  那这个地址到底是什么呢?


我们先查看下 KPCR 结构的信息


    

看到之后 是不是很熟悉 ,这里正是 我们 0换下 FS 指向的内容 

   

这里这扯一下 关于 KPCR  


由于Windows需要支持多个CPU,

因此Windows内核中为此定义了一套以处理器控制区(Processor Control Region)

即KPCR为枢纽的数据结构, 使每个CPU都有个KPCR. 

其中KPCR这个结构中有一个域KPRCB(Kernel Processor Control Block)结构, 这个结构扩展了KPCR. 这两个结构用来保存与线程切换相关的全局信息. 


关于一些 重要的结构 都能在 KPCR 中找到

  

2)3环下的FS

           

0环下的 基本了解差不多了  那再看下 3环 下的 FS      3B

           

在OD 中 我们 看到   是指向  7FFDF000   ,那我们拿  3B  去拆分  

index         TI          RPL
111(7)        0           11‬(3)

                  

在找到 描述符 时 拆分  会发现 基地址  全是  0

        

这是为什么呢?因为微软在 winXP sp3 之后对TEB进行了随机化机制处理,所以是无法用选择子去找gdt表找描述符。

        

不过我们在3环下通过windbg查看结果是正确的。  

           

这里验证下3环fs指向TEB 

     



二、哪里改变了FS的值?


             

现在  我们知道了 FS 在3环和 0环指向的内容   ,不过 0环和3环的FS 值是不同的 在哪里改变的呢?

           

关于 3环进入0环


在老式的cpu 上 应用程序从3环进入0环是通过中断门 在IDT的0x2E位置

而当时程序的入口为_KiSystemService()

而在之后出现了新的进入0环的方法 sysenter 快速系统调用

与新的入口 KiFastCallEntry()

           

那就看一下 KiFastCallEntry 到底干了些什么?


nt!KiFastCallEntry:
83e470c0 b923000000      mov     ecx,23h
83e470c5 6a30            push    30h
83e470c7 0fa1            pop     fs      //在这对fs 进行了赋值
83e470c9 8ed9            mov     ds,cx
83e470cb 8ec1            mov     es,cx
83e470cd 648b0d40000000  mov     ecx,dword ptr fs:[40h]
83e470d4 8b6104          mov     esp,dword ptr [ecx+4]
83e470d7 6a23            push    23h
83e470d9 52              push    edx

       

可以看到在刚进入函数就对fs进行赋值,那再哪给还原回去了?  

      


在跟踪 KiServiceExit 函数时发现在这里对 fs 进行 了 还原 


PS:而在 win7 环境下KiSystemCallExit和KiSystemCallExit2 、KiSystemCallExitBranch 中找不到恢复R3 FS的代码了

      

这基本上就是 0环 与3环 FS值得相互转换了 

  

至此 FS 寄存器 已经分析的差不多了,在0环分析时看到KPCR结构,在想想其他结构,一下有一种明晰的感觉。



三、关于文章


本人新手,有错误的地方请各位指点。


关于FS 段寄存器的文章有很多 很多前辈也写过这个知识点也很老 ,也许有些人会觉得写着个是炒剩饭的感觉。 

我发这篇文章 只是 对基础知识 进一步的总结  同样也希望 对跟我一样的新手 有帮助 


看完这篇文章 再推荐 看下   前段时间的  <从TEB到PEB在到SEH>   毕竟也有点联系 


最后附上 之前 看的文章  保存下来的结构图 (如有问题 请联系 删除图片)

         






本文由看雪论坛 Cestlavie呀  原创

转载请注明来自看雪社区



往期热门阅读:



扫描二维码关注我们,更多干货等你来拿!



    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存