關於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> 畢竟也有點聯絡
最後附上 之前 看的文章 儲存下來的結構圖 (如有問題 請聯絡 刪除圖片)