Log in

View Full Version : Creepy behaviour in syscall dispatcher hook


omega_red
November 4th, 2008, 05:15
OK, this got me really wondering what is going on. I'm testing a global syscall dispatcher hook (inline hook at the beginning of KiFastCallEntry). Environment: vista32, 1 cpu, vmware. The following code crashes sometimes, not on all passes, but on some. It basically gets KPCR->KPRCB->KTHREAD->TEB. Interrupts are off.

Code:
0008:8316d021 648b1d20000000 mov ebx,dword ptr fs:[20h] ; KPRCB
0008:8316d028 8b5b04 mov ebx,dword ptr [ebx+4] ds:0023:000003dc=???????? ; KTHREAD
0008:8316d02b 8b9b84000000 mov ebx,dword ptr [ebx+84h] ; TEB


As you can see, it crashes with access violation due to invalid dereference. EBX is 0x3d8 at the moment of AV (8316d028). BUT take a look at this...

Code:
kd> dg @fs
P Si Gr Pr Lo
Sel Base Limit Type l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
0030 818ec700 000020b8 Data RW 0 Bg By P Nl 00000492

kd> ? poi(poi(818ec700+20)+4)
Evaluate expression: -1976137888 = 8a368760

kd> ? poi(poi(poi(818ec700+20)+4)+84)
Evaluate expression: 2147151872 = 7ffaf000


Wtf? Windbg can access the memory and it's a valid TEB. So EBX should be 8a368760, right? What's going on here? Vmware playing some tricks on me or am I just stupid and overlooked something simple?

PS. Is there any windbg expression that returns the selector base? "dg @fs" displays it, but it can't be used inside of commands (or can it somehow?).

blabberer
November 5th, 2008, 11:21
Quote:

PS. Is there any windbg expression that returns the selector base? "dg @fs" displays it, but it can't be used inside of commands (or can it somehow?).



you mean some thing like this
Code:

kd> r cs; r ds;r ss;r gs;r fs;r es
cs=00000008
ds=00000023
ss=00000010
gs=00000000
fs=00000030
es=00000023
kd> .foreach /pS 1a /ps a (place { dg @fs}) {? poi(poi( place +20)+4); ? poi(poi(poi( place +20)+4)+84)}
Evaluate expression: -2141875424 = 80559320
Evaluate expression: 65536 = 00010000
kd> .foreach /pS 1a /ps a (place { dg @fs}) {? poi(poi( place +20)+4); ? poi(poi(poi( place +20)+4)+84); dg @fs}
Evaluate expression: -2141875424 = 80559320
Evaluate expression: 65536 = 00010000
P Si Gr Pr Lo
Sel Base Limit Type l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
0030 ffdff000 00001fff Data RW Ac 0 Bg Pg P Nl 00000c93
kd> .foreach /pS 1a /ps a (place { dg 0x30}) {? poi(poi( place +20)+4); ? poi(poi(poi( place +20)+4)+84); dg @fs}
Evaluate expression: -2141875424 = 80559320
Evaluate expression: 65536 = 00010000
P Si Gr Pr Lo
Sel Base Limit Type l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
0030 ffdff000 00001fff Data RW Ac 0 Bg Pg P Nl 00000c93


4 is ok for kthread
but that 84 is teb you are sure ?

teb is at 0x20

i think it must one entry in _kwait_block

Code:

kd> dt nt!_kprcb CurrentThread CurrentThread. poi(fs:[20])
+0x004 CurrentThread : 0x80559320 _KTHREAD
+0x000 Header : _DISPATCHER_HEADER
+0x010 MutantListHead : _LIST_ENTRY [ 0x80559330 - 0x80559330 ]
+0x018 InitialStack : 0x80550b80
+0x01c StackLimit : 0x8054db80
+0x020 Teb : (null)
+0x024 TlsArray : (null)
+0x028 KernelStack : 0x805508cc
+0x02c DebugActive : 0 ''
+0x02d State : 0x2 ''
+0x02e Alerted : [2] ""
+0x030 Iopl : 0 ''
+0x031 NpxState : 0xa ''
+0x032 Saturation : 0 ''
+0x033 Priority : 16 ''
+0x034 ApcState : _KAPC_STATE
+0x04c ContextSwitches : 0x8d3e
+0x050 IdleSwapBlock : 0 ''
+0x051 Spare0 : [3] ""
+0x054 WaitStatus : 0
+0x058 WaitIrql : 0x2 ''
+0x059 WaitMode : 0 ''
+0x05a WaitNext : 0 ''
+0x05b WaitReason : 0 ''
+0x05c WaitBlockList : 0x80559390 _KWAIT_BLOCK
+0x060 WaitListEntry : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x060 SwapListEntry : _SINGLE_LIST_ENTRY
+0x068 WaitTime : 0x5947c
+0x06c BasePriority : 0 ''
+0x06d DecrementCount : 0 ''
+0x06e PriorityDecrement : 0 ''
+0x06f Quantum : 30 ''
+0x070 WaitBlock : [4] _KWAIT_BLOCK
+0x0d0 LegoData : (null)
+0x0d4 KernelApcDisable : 0



Code:

kd> dd fs:[20] l1;dd poi(fs:[20]) l1;dd (poi(fs:[20])+4) l1;dd poi(poi(fs:[20])+4) l1;dd (poi(poi(fs:[20])+4)+84) l1;dd poi(poi(poi(fs:[20])+4)+84) l1
0030:00000020 ffdff120
ffdff120 00010001
ffdff124 80559320
80559320 00700006
805593a4 00010000
00010000 04e4000d



there is something very different in what i see from your analysis
fs:[20] always holds Cid for me not kpcrb


Code:

kd> g
Breakpoint 0 hit
calc!WinMain+0x246:
001b:01002197 ff158c110001 call dword ptr [calc!_imp__TranslateMessage (0100118c)]
kd> !pcr
KPCR for Processor 0 at ffdff000:
Major 1 Minor 1
NtTib.ExceptionList: f75bb6d8
NtTib.StackBase: f75bbdf0
NtTib.StackLimit: f75b7000
NtTib.SubSystemTib: 00000000
NtTib.Version: 00000000
NtTib.UserPointer: 00000000
NtTib.SelfTib: 7ffdf000

SelfPcr: ffdff000
Prcb: ffdff120
Irql: 00000000
IRR: 00000000
IDR: ffff20d0
InterruptMode: 00000000
IDT: 8003f400
GDT: 8003f000
TSS: 80042000

CurrentThread: ffb27030
NextThread: 00000000
IdleThread: 80559320

DpcQueue:
kd> dd fs:[0]
003b:00000000 0007ff10 00080000 0007c000 00000000
003b:00000010 00001e00 00000000 7ffdf000 00000000
003b:00000020 000001bc 00000668 00000000 00000000
003b:00000030 7ffd4000 00000005 00000000 00000000
003b:00000040 e19375f8 00000000 00000000 00000000
003b:00000050 00000000 00000000 00000000 00000000
003b:00000060 00000000 00000000 00000000 00000000
003b:00000070 00000000 00000000 00000000 00000000
kd> !process 0 0 calc.exe
PROCESS 81247550 SessionId: 0 Cid: 01bc Peb: 7ffd4000 ParentCid: 04c8
DirBase: 0662f000 ObjectTable: e18131d0 HandleCount: 198.
Image: calc.exe

kd> dt nt!_kthread teb ffb27030
+0x020 Teb : 0x7ffdf000
kd> dt nt!_peb Processparameter ProcessParameters. poi(fs:[30])
+0x010 ProcessParameters :
Cannot find specified field members.
kd> dt nt!_peb Processparameters ProcessParameters. poi(fs:[30])
+0x010 ProcessParameters : 0x00020000 _RTL_USER_PROCESS_PARAMETERS
+0x000 MaximumLength : 0x1000
+0x004 Length : 0x674
+0x008 Flags : 0x22001
+0x00c DebugFlags : 0
+0x010 ConsoleHandle : (null)
+0x014 ConsoleFlags : 0
+0x018 StandardInput : (null)
+0x01c StandardOutput : 0x00010001
+0x020 StandardError : (null)
+0x024 CurrentDirectory : _CURDIR
+0x030 DllPath : _UNICODE_STRING "C:\WINDOWS\system32;C:\WINDOWS\system32;C:\WINDOWS\system;C:\WINDOWS;.;C:\WINDOWS\system32;C:\WINDOW S;C:\WINDOWS\System32\Wbem"
+0x038 ImagePathName : _UNICODE_STRING "C:\WINDOWS\system32\calc.exe"
+0x040 CommandLine : _UNICODE_STRING ""C:\WINDOWS\system32\calc.exe" "
+0x048 Environment : 0x00010000
+0x04c StartingX : 0
+0x050 StartingY : 0
+0x054 CountX : 0
+0x058 CountY : 0
+0x05c CountCharsX : 0
+0x060 CountCharsY : 0
+0x064 FillAttribute : 0
+0x068 WindowFlags : 0x401
+0x06c ShowWindowFlags : 1
+0x070 WindowTitle : _UNICODE_STRING "C:\WINDOWS\system32\calc.exe"
+0x078 DesktopInfo : _UNICODE_STRING "WinSta0\Default"
+0x080 ShellInfo : _UNICODE_STRING ""
+0x088 RuntimeData : _UNICODE_STRING ""
+0x090 CurrentDirectores : [32] _RTL_DRIVE_LETTER_CURDIR



Code:

kd> dg @fs;dd poi(7ffdf000+20) l1;dd 7ffdf000;dt nt!_teb ClientId ClientId. 7ffdf000
P Si Gr Pr Lo
Sel Base Limit Type l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
003B 7ffdf000 00000fff Data RW Ac 3 Bg By P Nl 000004f3
000001bc ????????
7ffdf000 0007ff10 00080000 0007c000 00000000
7ffdf010 00001e00 00000000 7ffdf000 00000000
7ffdf020 000001bc 00000668 00000000 00000000
7ffdf030 7ffd4000 00000005 00000000 00000000
7ffdf040 e19375f8 00000000 00000000 00000000
7ffdf050 00000000 00000000 00000000 00000000
7ffdf060 00000000 00000000 00000000 00000000
7ffdf070 00000000 00000000 00000000 00000000
+0x020 ClientId : _CLIENT_ID
+0x000 UniqueProcess : 0x000001bc
+0x004 UniqueThread : 0x00000668

Kayaker
November 5th, 2008, 17:46
Quote:
[Originally Posted by blabberer;77618]
there is something very different in what i see from your analysis
fs:[20] always holds Cid for me not kpcrb


That's what this says too
http://en.wikipedia.org/wiki/Win32_Thread_Information_Block

omega_red
November 6th, 2008, 05:55
Teb is 0x20 only up to XP. On Vista it is 0x84 (all 32bit ofc)
Code:
kd> dt nt!_kprcb CurrentThread CurrentThread. poi(fs:[20])
nt!_KPRCB
+0x004 CurrentThread : 0x8bcd63a8 _KTHREAD
+0x000 Header : _DISPATCHER_HEADER
+0x010 CycleTime : 0xfbf3cb8
+0x018 HighCycleTime : 0
+0x020 QuantumTarget : 0x137e989c
+0x028 InitialStack : 0x90cdc000
+0x02c StackLimit : 0x90cd9000
+0x030 KernelStack : 0x90cdb648
+0x034 ThreadLock : 0
+0x038 ApcState : _KAPC_STATE
+0x038 ApcStateFill : [23] "???"
+0x04f Priority : 8 ''
+0x050 NextProcessor : 0
+0x052 DeferredProcessor : 0
+0x054 ApcQueueLock : 0
+0x058 ContextSwitches : 0x64
+0x05c State : 0x2 ''
+0x05d NpxState : 0xa ''
+0x05e WaitIrql : 0 ''
+0x05f WaitMode : 0 ''
+0x060 WaitStatus : 0
+0x064 WaitBlockList : 0x8bcd6460 _KWAIT_BLOCK
+0x064 GateObject : 0x8bcd6460 _KGATE
+0x068 KernelStackResident : 0y1
+0x068 ReadyTransition : 0y0
+0x068 ProcessReadyQueue : 0y0
+0x068 WaitNext : 0y0
+0x068 SystemAffinityActive : 0y0
+0x068 Alertable : 0y0
+0x068 GdiFlushActive : 0y0
+0x068 Reserved : 0y0000000000000000000000000 (0)
+0x068 MiscFlags : 1
+0x06c WaitReason : 0x12 ''
+0x06d SwapBusy : 0 ''
+0x06e Alerted : [2] ""
+0x070 WaitListEntry : _LIST_ENTRY [ 0x8bd2e4b8 - 0x818ee2c0 ]
+0x070 SwapListEntry : _SINGLE_LIST_ENTRY
+0x078 Queue : (null)
+0x07c WaitTime : 0xe8d
+0x080 KernelApcDisable : -3
+0x082 SpecialApcDisable : 0
+0x080 CombinedApcDisable : 0xfffd
+0x084 Teb : 0x7ffdc000
+0x088 Timer : _KTIMER

omega_red
November 6th, 2008, 06:32
Additional info from my OS:
Code:
kd> vertarget
Windows Vista Kernel Version 6000 MP (1 procs) Free x86 compatible
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 6000.16584.x86fre.vista_gdr.071023-1545
Kernel base = 0x81800000 PsLoadedModuleList = 0x81908ad0
Debug session time: Thu Nov 6 12:21:21.218 2008 (GMT+1)
System Uptime: 0 days 0:02:31.364

kd> dd fs:[20] l1;dd poi(fs:[20]) l1;dd (poi(fs:[20])+4) l1;dd poi(poi(fs:[20])+4) l1;dd (poi(poi(fs:[20])+4)+84) l1;dd poi(poi(poi(fs:[20])+4)+84) l1
0030:00000020 818ec820
818ec820 00010001
818ec824 82ffd3b0
82ffd3b0 00780006
82ffd434 7ffdf000
7ffdf000 0012fc0c

kd> dd fs:[0]
0030:00000000 851d182c 00000000 00000000 80139000
0030:00000010 0003625e 00000001 7ffdf000 818ec700
0030:00000020 818ec820 0000001f 00000000 00000000
0030:00000030 ffffffff 818ebc20 8231f400 8231f000
0030:00000040 80139000 00010001 00000001 00000c91
0030:00000050 08000000 00000000 00000000 00000000
0030:00000060 00000000 00000000 00000000 00000000
0030:00000070 00000000 00000000 00000000 00000000


Well, according to wrk sources, FS is supposed to be base for KPCR for MP systems. Maybe you tested in on uniprocessor xp?

ntos\inc\i386.h:
Code:
// Location of primary PCR (used only for UP kernel & hal code)
//

// addressed from 0xffdf0000 - 0xffdfffff are reserved for the system
// (ie, not for use by the hal)

#define KI_BEGIN_KERNEL_RESERVED 0xffdf0000
#define KIP0PCRADDRESS 0xffdff000 // ntddk wdm ntosp

// begin_ntddk begin_ntosp

#define KI_USER_SHARED_DATA 0xffdf0000
#define SharedUserData ((KUSER_SHARED_DATA * const) KI_USER_SHARED_DATA)

(...snip...)

#if NT_UP
#define _PCR ds:[KIP0PCRADDRESS]
#else
#define _PCR fs:[0] // ntddk ntosp
#endif


And since all Vista kernels are MP, my code should be ok...

blabberer
November 6th, 2008, 08:35
Quote:

Teb is 0x20 only up to XP. On Vista it is 0x84 (all 32bit ofc)


yeah thats why i asked are you sure :P

Code:

kd> dd fs:[0]
0030:00000000 851d182c 00000000 00000000 80139000
0030:00000010 0003625e 00000001 7ffdf000 818ec700
0030:00000020 818ec820 0000001f 00000000 00000000


are you in context ?

i would prefer to see it on a breakpoint when you are really in context

like i posted

if you break here on say lkd or on DebugBreak with ctrl+break or ctrl+c in windbg or kd
the data for idle thread always seems to be radically different from what is seen at break on context

Code:

Microsoft (R) Windows Debugger Version 6.9.0003.113 X86
Copyright (c) Microsoft Corporation. All rights reserved.

Opened \\.\pipe\debugPipe
Waiting to reconnect...
Connected to Windows XP 2600 x86 compatible target, ptr64 FALSE
Kernel Debugger connection established.
Symbol search path is: SRV*F:\SYMBOLS*HTTP://MSDL.MICROSOFT.COM/DOWNLOAD/SYMBOLS
Executable search path is:
Windows XP Kernel Version 2600 UP Free x86 compatible
Built by: 2600.xpsp_sp2_rtm.040803-2158
Kernel base = 0x804d7000 PsLoadedModuleList = 0x8055ab20
System Uptime: not available
Break instruction exception - code 80000003 (first chance)
*******************************************************************************
* *
* You are seeing this message because you pressed either *
* CTRL+C (if you run kd.exe) or, *
* CTRL+BREAK (if you run WinDBG), *
* on your debugger machine's keyboard. *
* *
* THIS IS NOT A BUG OR A SYSTEM CRASH *
* *
* If you did not intend to break into the debugger, press the "g" key, then *
* press the "Enter" key now. This message might immediately reappear. If it *
* does, press "g" and "Enter" again. *
* *
*******************************************************************************
nt!RtlpBreakWithStatusInstruction:
804e3b25 cc int 3
kd> dd fs:0
0030:00000000 80550150 80550970 8054db80 00000000
0030:00000010 00000000 00000000 00000000 ffdff000
0030:00000020 ffdff120 0000001c 00000000 00000000
0030:00000030 ffff20d0 8054c738 8003f400 8003f000
0030:00000040 80042000 00010001 00000001 00000064
0030:00000050 00000000 00000000 00000000 00000000
0030:00000060 00000000 00000000 00000000 00000000
0030:00000070 00000000 00000000 00000000 00000000


see the same place at break on context

Code:

kd> .process /p /r /i /P 81189230
You need to continue execution (press 'g' <enter> for the context
to be switched. When the debugger breaks in again, you will be in
the new process context.
kd> g
Break instruction exception - code 80000003 (first chance)
nt!RtlpBreakWithStatusInstruction:
804e3b25 cc int 3
kd> u 1002197
01002197 ff158c110001 call dword ptr ds:[100118Ch]
0100219d 8d45cc lea eax,[ebp-34h]
010021a0 50 push eax
010021a1 ff1588110001 call dword ptr ds:[1001188h]
010021a7 53 push ebx
010021a8 53 push ebx
010021a9 8d45cc lea eax,[ebp-34h]
010021ac 53 push ebx
kd> bp 1002197
kd> bl
0 e 01002197 0001 (0001)
Match process data 81189230
1 e 01002197 0001 (0001)

kd> g
Breakpoint 0 hit
Breakpoint 1 hit
001b:01002197 ff158c110001 call dword ptr ds:[100118Ch]
kd> dd fs:0
003b:00000000 0007ff10 00080000 0007d000 00000000
003b:00000010 00001e00 00000000 7ffdf000 00000000
003b:00000020 000006b4 000006b8 00000000 00000000
003b:00000030 7ffd6000 00000005 00000000 00000000
003b:00000040 e1960008 00000000 00000000 00000000
003b:00000050 00000000 00000000 00000000 00000000
003b:00000060 00000000 00000000 00000000 00000000
003b:00000070 00000000 00000000 00000000 00000000
kd> u @eip l1
01002197 ff158c110001 call dword ptr ds:[100118Ch]
kd> .reload /f


Code:

kd> u @eip l1;dd fs:0;!process 0 0 calc.exe
calc!WinMain+0x246:
01002197 ff158c110001 call dword ptr [calc!_imp__TranslateMessage (0100118c)]
003b:00000000 0007ff10 00080000 0007d000 00000000
003b:00000010 00001e00 00000000 7ffdf000 00000000
003b:00000020 000006b4 000006b8 00000000 00000000
003b:00000030 7ffd6000 00000005 00000000 00000000
003b:00000040 e1960008 00000000 00000000 00000000
003b:00000050 00000000 00000000 00000000 00000000
003b:00000060 00000000 00000000 00000000 00000000
003b:00000070 00000000 00000000 00000000 00000000
PROCESS 81189230 SessionId: 0 Cid: 06b4 Peb: 7ffd6000 ParentCid: 04bc
DirBase: 083d3000 ObjectTable: e1867278 HandleCount: 27.
Image: calc.exe

omega_red
November 6th, 2008, 10:17
Previous line: fs:1c is PCR-self linear pointer.

Code:
83185020 648b1d1c000000 mov ebx,dword ptr fs:[1Ch]


Code:
kd> g
Breakpoint 1 hit
83185027 8b5b20 mov ebx,dword ptr [ebx+20h]

kd> !thread
THREAD 83147030 Cid 0de4.0de8 Teb: 7ffdf000 Win32Thread: ffb4fbc0 RUNNING on processor 0
Not impersonating
DeviceMap 926d6048
Owning Process 8316fd90 Image: SysLog.exe
Wait Start TickCount 14736 Ticks: 12 (0:00:00:00.187)
Context Switch Count 45
UserTime 00:00:00.000
KernelTime 00:00:00.062
Win32 Start Address SysLog!ILT+2025(_mainCRTStartup) (0x004157ee)
Stack Init 93bc8000 Current 93bc7580 Base 93bc8000 Limit 93bc5000 Call 0
Priority 8 BasePriority 8 PriorityDecrement 0 IoPriority 2 PagePriority 5
ChildEBP RetAddr Args to Child
851d1fd8 00000000 00000000 0012fc1c 851d1ffc 0x83185027

kd> r
eax=00000102 ebx=00000000 ecx=00000023 edx=0012fba4 esi=83185000 edi=00000058
eip=83185027 esp=851d1fdc ebp=0012fc1c iopl=0 nv up di ng nz na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000086
83185027 8b5b20 mov ebx,dword ptr [ebx+20h] ds:0023:00000020=????????

kd> dg @fs
P Si Gr Pr Lo
Sel Base Limit Type l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
0030 818ec700 000020b8 Data RW 0 Bg By P Nl 00000492

kd> dd fs:[0]
0030:00000000 851d182c 00000000 00000000 80139000
0030:00000010 000471ab 00000001 7ffdf000 818ec700
0030:00000020 818ec820 0000001f 00000000 00000000
0030:00000030 ffffffff 818ebc20 8231f400 8231f000
0030:00000040 80139000 00010001 00000001 00000c91
0030:00000050 08000000 00000000 00000000 00000000
0030:00000060 00000000 00000000 00000000 00000000
0030:00000070 00000000 00000000 00000000 00000000

EBX is 0 at this point, but it should be 818ec700.

blabberer
November 6th, 2008, 10:46
this both return differnt values when you have broken ?

can you single step through the previous line ?



Code:


kd> dd fs:0;.echo " "; dg @fs; .echo " ";.foreach /pS 1a /ps a (place { dg @fs}) { dd place }
003b:00000000 0007ff10 00080000 0007d000 00000000
003b:00000010 00001e00 00000000 7ffdf000 00000000
003b:00000020 000006b4 000006b8 00000000 00000000
003b:00000030 7ffd6000 00000005 00000000 00000000
003b:00000040 e1960008 00000000 00000000 00000000
003b:00000050 00000000 00000000 00000000 00000000
003b:00000060 00000000 00000000 00000000 00000000
003b:00000070 00000000 00000000 00000000 00000000

P Si Gr Pr Lo
Sel Base Limit Type l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
003B 7ffdf000 00000fff Data RW Ac 3 Bg By P Nl 000004f3

7ffdf000 0007ff10 00080000 0007d000 00000000
7ffdf010 00001e00 00000000 7ffdf000 00000000
7ffdf020 000006b4 000006b8 00000000 00000000
7ffdf030 7ffd6000 00000005 00000000 00000000
7ffdf040 e1960008 00000000 00000000 00000000
7ffdf050 00000000 00000000 00000000 00000000
7ffdf060 00000000 00000000 00000000 00000000
7ffdf070 00000000 00000000 00000000 00000000

omega_red
November 17th, 2008, 09:22
Right, I think I (partially) solved the problem. I had a week's break, but now at least I know why the code crashed and I corrected it.

It's quite simple: on syscall entry, FS values can be variable. Normally it's 0x30 for kernel selector (KPCR), but sometimes it's also 0x3b, which is user-mode selector for TEB etc.

Code:
kd> dg 30
P Si Gr Pr Lo
Sel Base Limit Type l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
0030 8190b800 00002128 Data RW 0 Bg By P Nl 00000492
kd> dg 3b
P Si Gr Pr Lo
Sel Base Limit Type l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
003B 7ffdf000 00000fff Data RW 3 Bg By P Nl 000004f2

kd> dd 30:0
0030:00000000 8069d82c 00000000 00000000 8013b000
0030:00000010 00032454 00000001 7ffdf000 8190b800
0030:00000020 8190b920 0000001f 00000000 00000000
0030:00000030 ffffffff 8190ac68 8245e400 8245e000
0030:00000040 8013b000 00010001 00000001 00000c91
0030:00000050 08000000 00000000 00000000 00000000
0030:00000060 00000000 00000000 00000000 00000000
0030:00000070 00000000 00000000 00000000 00000000
kd> dd 3b:0
003b:00000000 0012fbf4 00130000 0012d000 00000000
003b:00000010 00001e00 00000000 7ffdf000 00000000
003b:00000020 00000eb0 00000eb4 00000000 7ffdf02c
003b:00000030 7ffd8000 00000000 00000000 00000000
003b:00000040 ffb30e90 00000000 00000000 00000000
003b:00000050 00000000 00000000 00000000 00000000
003b:00000060 00000000 00000000 00000000 00000000
003b:00000070 00000000 00000000 00000000 00000000


You can see the difference in IOPL field. So if FS happened to be 3b, my code of course crashed.

BUT, I still don't know why the debugger apparently showed WRONG FS value: when I broke on conditional BP at the faulting line, WinDBG always showed that FS=30, not 3b. I only glanced the difference on crash dump analysis when I examined exception trap frame, it certainly had FS=3b. Can anyone explain such behaviour?

deroko
November 17th, 2008, 09:58
imho, if you posted whole hook code from very 1st instruction error would be noticed immediately, as when you go r0 you should always set fs to 0x30 to point to KPCR. As sysenter/int 2e won't do it for you. I thought you have setup fs to 0x30 at the beginning, and really didn't have good explanation for your scenario, and was waiting to see what possibily could go wrong

omega_red
November 17th, 2008, 10:02
Yeah, I didn't set FS before, it was set only after my stub by normal dispatcher code. It's just the weird debugger behaviour that really got me thinking what the hell was happening.