1. 程式人生 > >FS暫存器指向當前活動執行緒的TEB結構(執行緒結構)

FS暫存器指向當前活動執行緒的TEB結構(執行緒結構)

偏移 說明
000 指向SEH鏈指標
004 執行緒堆疊頂部
008 執行緒堆疊底部
00C SubSystemTib
010 FiberData
014 ArbitraryUserPointer
018 FS段暫存器在記憶體中的映象地址
020 程序PID
024 執行緒ID
02C 指向執行緒區域性儲存指標
030 PEB結構地址(程序結構)
034 上個錯誤號




得到KERNEL32.DLL基址的方法
assume fs:nothing             ;開啟FS暫存器
mov eax,fs:[30h]            ;得到PEB結構地址
mov eax,[eax + 0ch]        ;得到PEB_LDR_DATA結構地址
mov esi,[eax + 1ch]        ;InInitializationOrderModuleList
lodsd                      ;得到KERNEL32.DLL所在LDR_MODULE結構的InInitializationOrderModuleList地址
mov edx,[eax + 8h]         ;得到BaseAddress,既Kernel32.dll基址

============================================================================================

執行緒執行在RING0(系統地址空間)和RING3(使用者地址空間)時,FS段暫存器分別指向不同記憶體段的。執行緒執行在RING0下,FS段值是0x3B(WindowsXP下值,在Windows2000下值為0x38);執行在RING3下時,FS段暫存器值是0x30。FS暫存器值的改變是在程式從Ring3進入Ring0後和從Ring0退回到Ring3前完成的,也就是說:都是在Ring0下給FS賦不同值的。

一.在RING3下執行時的FS

當執行緒執行在Ring3下時,FS指向的段是GDT中的0x30段。該段的長度為4K,基地址為當前執行緒的執行緒環境塊(TEB),所以該段也被稱為“TEB段”。因為Windows中執行緒是不停切換的,所以該段的基地址值將隨執行緒切換而改變的。

Windows2000中程序環境塊(PEB)的地址為0X7FFDF000,該程序的第一個執行緒的TEB地址為0X7FFDE000,第二個TEB的地址為0X7FFDD000…..但是在WindowsXP SP2 下這些結構的地址都是隨機對映的。所以程序的PEB的地址只能通過FS:[0x30]來獲取了。

Windows中每個執行緒都有一個ETHREAD結構,該結構的TEB成員(其實是KTHREAD中的成員,而KTHREAD又是ETHREAD的成員)是用來儲存執行緒的TEB地址的,當執行緒切換時,Windows就會用該值來更改GDT的0x30段描述符的基地址值。

下面就是WindowsXP SP2在RING3下FS段暫存器所指向的資料結構和地址。

_TIB

   +0x000 NtTib            : _NT_TIB

_NT_TIB

+0x000 ExceptionList: Ptr32 _EXCEPTION_REGISTRATION_RECORD

+0x004 StackBase        : Ptr32 Void

+0x008 StackLimit       : Ptr32 Void

+0x SubSystemTib     : Ptr32 Void

+0x010 FiberData        : Ptr32 Void

+0x010 Version          : Uint4B

+0x014 ArbitraryUserPointer : Ptr32 Void

   +0x018 Self            : Ptr32 _NT_TIB

二.在RING0下執行時的FS

當執行緒執行在Ring0下時, FS指向的段是GDT中的0x3B段。該段的長度也為4K,基地址為0xFFDFF000。該地址指向系統的處理器控制區域(KPCR)。這個區域中儲存這處理器相關的一些重要資料值,如GDT、IDT表的值等等。下面就是WindowsXP sp2中的KPCR資料結構:

_KPCR

   +0x000 NtTib            : _NT_TIB

_NT_TIB

+0x000 ExceptionList: Ptr32 _EXCEPTION_REGISTRATION_RECORD

+0x004 StackBase        : Ptr32 Void

+0x008 StackLimit       : Ptr32 Void

+0x SubSystemTib     : Ptr32 Void

+0x010 FiberData        : Ptr32 Void

+0x010 Version          : Uint4B

+0x014 ArbitraryUserPointer : Ptr32 Void

   +0x018 Self             : Ptr32 _NT_TIB

在WindowsXP中,許多作業系統的系統變數地址值儲存在以KPCR開始的資料結構中(可以參看下圖)。注意,這是在WindowsXP下,而在WIN2000下是沒有這中情況。有興趣的讀者可以看一下www.rootkit.com下的相關文章。

============================================================================================

以上為原文,因此以後在逆向中遇到fs,如果是ring0的fs則可以dt _kpcr來檢視相關偏移處的結構,若是ring3的,則dt _teb即可。