omega_red
July 14th, 2007, 06:35
I've accidentally found a "vulnerability" in GDI (BSOD from user mode, although requiring pretty unusual conditions
)
So, I've been digging through win32k recently (again) to better understand what's going on. On the way I stumped on the mysterious _gptiCurrent variable. It's used in most NtUser... functions (IDA gives 775 references). Example from random one (not related to the crash
):
The test byte ptr [eax+4Bh], 20h construct is very common, although the code often accesses fields at various offsets in this structure. But what is in there, really?
I noticed that EnterCrit() is commonly called before access to _gptiCurrent. So, let's take a look:
Pretty clear, eh? Almost... First we have critical section and then getting current ETHREAD. But what does PsGetThreadWin32Thread do?
One step closer... Tcb is KTHREAD, so let's look there:
Riight... This doesn't look meaningful, does it?
Quick look at WRK sources didn't provide any meaningful hints, except it's used by win32k (doh, I guess we knew that already). Next step: google
From http://www.archivum.info/microsoft.public.win32.programmer.kernel/2005-08/msg00298.html:
That's in line with our previous findings, but no new information either. Hmm... What about !thread in windbg?
It's listed there, so it must have some use for debugging... Let's take a look at windbg documentation:
Eh? System Service Dispatch Table?
WTF? Certainly doesn't look like SSDT. First dword is our ETHREAD. Only other immediately recognizable value is 7ffde6cc at +44, it's pointer to TEB.Win32ClientInfo. bf9aa260 is win32k!diStatic according to symbols. Other values are just pointers to something. Following randomly by thee pointers I can see memory with some win32k function pointers at times, but all this doesn't really look like syscall dispatch table.
I don't have much time to analyze this further, so thought I'll post about it here, maybe someone will know something more.

So, I've been digging through win32k recently (again) to better understand what's going on. On the way I stumped on the mysterious _gptiCurrent variable. It's used in most NtUser... functions (IDA gives 775 references). Example from random one (not related to the crash

Code:
_NtUserCreateDesktop@20 proc near
...
push 0Ch
push offset unk_BF98C9E0
call __SEH_prolog
call _EnterCrit@0 ; EnterCrit()
mov eax, _gptiCurrent
test byte ptr [eax+4Bh], 20h
jnz short loc_BF88149E
The test byte ptr [eax+4Bh], 20h construct is very common, although the code often accesses fields at various offsets in this structure. But what is in there, really?
I noticed that EnterCrit() is commonly called before access to _gptiCurrent. So, let's take a look:
Code:
_EnterCrit@0 proc near
call ds:__imp__KeEnterCriticalRegion@0 ; KeEnterCriticalRegion()
push 1 ; Wait
push _gpresUser ; Resource
call ds:__imp__ExAcquireResourceExclusiveLite@8 ; ExAcquireResourceExclusiveLite(x,x)
call ds:__imp__PsGetCurrentThread@0 ; PsGetCurrentThread()
push eax
call ds:__imp__PsGetThreadWin32Thread@4 ; PsGetThreadWin32Thread(x)
mov _gptiCurrent, eax
retn
_EnterCrit@0 endp
Pretty clear, eh? Almost... First we have critical section and then getting current ETHREAD. But what does PsGetThreadWin32Thread do?
Code:
PVOID
PsGetThreadWin32Thread(
__in PETHREAD Thread
)
{
return Thread->Tcb.Win32Thread;
}
One step closer... Tcb is KTHREAD, so let's look there:
Code:
nt!_ETHREAD
+0x000 Tcb : _KTHREAD
nt!_KTHREAD
...
+0x130 Win32Thread : Ptr32 Void
Riight... This doesn't look meaningful, does it?

Quick look at WRK sources didn't provide any meaningful hints, except it's used by win32k (doh, I guess we knew that already). Next step: google

From http://www.archivum.info/microsoft.public.win32.programmer.kernel/2005-08/msg00298.html:
Quote:
[Originally Posted by Skywing] I'm assuming you're really meaning _KTHREAD.Win32Thread and not _TEB.Win32ThreadInfo because they're different things. Anyways, _KTHREAD.Win32Thread is a pointer to a win32k.sys data structure that is created the first time a thread makes an NtUser/NtGdi system service call. So threads that don't call USER or GDI functions might not have a Win32Thread pointer. |
That's in line with our previous findings, but no new information either. Hmm... What about !thread in windbg?
Code:
THREAD 81f8eda8 Cid 026c.0270 Teb: 7ffde000 Win32Thread: e151e6a0 RUNNING on processor 0
It's listed there, so it must have some use for debugging... Let's take a look at windbg documentation:
Quote:
System Service Dispatch Table - The hexadecimal number after the word Win32Thread is the address of the system service dispatch table. |
Eh? System Service Dispatch Table?
Code:
e151e6a0 81f8eda8 00000001 00000000 00000000
e151e6b0 00000000 00000000 00000000 00000000
e151e6c0 00000000 00000000 00000000 e156d868
e151e6d0 e153dd88 00000000 e151e7d4 00000000
e151e6e0 bf9aa260 7ffde6cc 01000000 00000000
e151e6f0 00000000 00000000 00000000 00000000
e151e700 00000000 00000000 00000000 00000000
e151e710 00000000 00000000 00000000 00000000
e151e720 00000400 00000000 00000000 00000000
e151e730 00000000 00000000 00000000 00000000
e151e740 00000000 00000020 82091ab0 00000000
WTF? Certainly doesn't look like SSDT. First dword is our ETHREAD. Only other immediately recognizable value is 7ffde6cc at +44, it's pointer to TEB.Win32ClientInfo. bf9aa260 is win32k!diStatic according to symbols. Other values are just pointers to something. Following randomly by thee pointers I can see memory with some win32k function pointers at times, but all this doesn't really look like syscall dispatch table.
I don't have much time to analyze this further, so thought I'll post about it here, maybe someone will know something more.
