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即可。