Windows核心编程_FS段寄存器
程序员文章站
2022-06-08 19:13:43
...
Windows核心编程_FS段寄存器
FS段寄存器Windows用来存储一些进程信息的,FS段的首地址是存储这些进程信息的首地址:在内核态FS指向GDT表的:0x30地址, 在用户态FS=0x3B
也就是说当切换到用户态时,操作系统会把进程下正在执行的线程的某些信息写入到0X3B为起始地址的空间里,内核态时候也一样,操作系统也会写入一些关于内核程序的相关信息到0x3B里!
由于进程的不同进程信息也不同,所以当控制权到不同的进程下时操作系统会向0x3B空间下写入不同的数据!
下面为FS寄存器下偏移的相关信息:
00 指向SEH链表指针
04 线程堆栈顶部(地址最小)
08 线程堆栈底部(地址最大)
0c SubSystemTib
10 FiberData
14 ArbitraryUserPointer
18 FS 段寄存器在内存中的镜像
20 进程PID
24 线程ID
2c 指向线程局部存储的指针
30 PEB结构地址(进程结构/不是PCB进程控制块)
34 上一个错误(LastError)
这里来演示一下用_asm内联汇编来获取FS寄存器指向的地址空间里的内容
获取进程PID:
DWORD _PID;
_asm{
mov eax, dword ptr fs:[20h]
mov [_PID],eax
}
printf("%d", _PID);
getchar();
运行结果:
不信的话,我们使用WindowsAPI:
GetCurrentProcessId来获取自身进程PID试试:
DWORD _PID;
_asm{
mov eax, dword ptr fs:[20h]
mov [_PID],eax
}
printf("%d,%d", _PID, GetCurrentProcessId());
getchar();
运行结果
但是还有一个问题,多核CPU是一个CPU下有多个单核CPU,这些CPU通过内部总线来交互数据的,并且是并行的,当每个线程切换时,windows会将某个线程的信息写入到此寄存器下,但是并行的,每个CPU都会有一个自己的fs段寄存器!