在R0和R3时,FS段寄存器分别指向GDT中的不同段:在R3下,FS段寄存器的值是0x3B,在R0下,FS段寄存器的值是0x30.分别用OD和Windbg在R3和R0下查看寄存器(XP3),下图:
FS寄存器的改变是从R3进入R0后和从R0退回到R3前完成的,也就是说:都是在R0下给FS赋不同值的.(FS在R0和R3中是不同的值,在KiFastCallEntry / KiSystemService中FS值由0x3B变成0x30在 KiSystemCallExit / KiSystemCallExitBranch / KiSystemCallExit2 中再将R3的FS恢复)
一.R3与R0之间的互相转换
nt!KiSystemService:
808696a1 6a00 push 0
808696a3 55 push ebp
808696a4 53 push ebx
808696a5 56 push esi
808696a6 57 push edi
808696a7 0fa0 push fs //旧的R3 下的FS 保存入栈
808696a9 bb30000000 mov ebx,30h
808696ae 668ee3 mov fs,bx //FS=0X30 FS 值变成了0X30
808696b1 64ff3500000000 push dword ptr fs:[0]
808696b8 64c70500000000ffffffff mov dword ptr fs:[0],0FFFFFFFFh
808696c3 648b3524010000 mov esi,dword ptr fs:[124h] //ESI=_ETHEAD
808696ca ffb640010000 push dword ptr [esi+140h] //PreviousMode
808696d0 83ec48 sub esp,48h
808696d3 8b5c246c mov ebx,dword ptr [esp+6Ch]
KiSystemCallExit部分代码
80869945 8d6550 lea esp,[ebp+50h]
80869948 0fa1 pop fs // 恢复 FS 值
8086994a 8d6554 lea esp,[ebp+54h]
8086994d 5f pop edi
8086994e 5e pop esi
8086994f 5b pop ebx
80869950 5d