PDA

View Full Version : Mysteries of win32k & GDI


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 ):
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.

blabberer
July 14th, 2007, 10:13
you must be confusing yourself with the ntsystemservice dispatch table and win32k.sys systemservice dispatch table

those with index greater than 0x1000 endup in win32k.sys

thats located here

win32k!W32pServiceTable

the address e151e6e0 bf9aa260 7ffde6cc 01000000 00000000

bf9### probably points to that address thats going to executed



x win32k!W32pServiceTable
bf998c40 win32k!W32pServiceTable = <no type information>
lkd>

i dont have a /debug enabled system at hand now so cant confirm

lkd> dd win32k!W32pServiceTable
bf998c40 ???????? ???????? ???????? ????????
bf998c50 ???????? ???????? ???????? ????????
bf998c60 ???????? ???????? ???????? ????????
bf998c70 ???????? ???????? ???????? ????????
bf998c80 ???????? ???????? ???????? ????????
bf998c90 ???????? ???????? ???????? ????????
bf998ca0 ???????? ???????? ???????? ????????
bf998cb0 ???????? ???????? ???????? ????????

but if you flip to a non system process and do a dps poi win32k!W32pServiceTable

you should get all the service table calls of win32k.sys

omega_red
July 14th, 2007, 10:31
Yeah, I know a bit about different syscall tables
Here's win32k table from this system:
All addresses are around bf..., and none of them appears near this Win32Thread structure.
And that bf9aa260 is some win32k variable (diStatic). It contains 0 anyway.
Code:
Table #1: bf999280, 029b entries, params=bf999f90, \SystemRoot\System32\win32k.sys
1000: bf935662 NtGdiAbortDoc [1] (win32k.sys)
1001: bf947213 NtGdiAbortPath [1] (win32k.sys)
1002: bf87a92d NtGdiAddFontResourceW [6] (win32k.sys)
1003: bf93eddc NtGdiAddRemoteFontToDC [4] (win32k.sys)
1004: bf94882a NtGdiAddFontMemResourceEx [5] (win32k.sys)
1005: bf9358f6 NtGdiRemoveMergeFont [2] (win32k.sys)
1006: bf93599b NtGdiAddRemoteMMInstanceToDC [3] (win32k.sys)
1007: bf83db66 NtGdiAlphaBlend [12] (win32k.sys)
1008: bf948151 NtGdiAngleArc [6] (win32k.sys)
1009: bf934101 NtGdiAnyLinkedFonts [0] (win32k.sys)
100a: bf948749 NtGdiFontIsLinked [1] (win32k.sys)
100b: bf90ed70 NtGdiArcInternal [10] (win32k.sys)
100c: bf9007d1 NtGdiBeginPath [1] (win32k.sys)
100d: bf80a150 NtGdiBitBlt [11] (win32k.sys)
100e: bf94861b NtGdiCancelDC [1] (win32k.sys)
100f: bf949e17 NtGdiCheckBitmapBits [8] (win32k.sys)
1010: bf8ff0ce NtGdiCloseFigure [1] (win32k.sys)
1011: bf8817f3 NtGdiClearBitmapAttributes [2] (win32k.sys)
1012: bf9486f9 NtGdiClearBrushAttributes [2] (win32k.sys)
1013: bf949f4a NtGdiColorCorrectPalette [6] (win32k.sys)
1014: bf8240b0 NtGdiCombineRgn [4] (win32k.sys)
1015: bf8dcc85 NtGdiCombineTransform [3] (win32k.sys)
1016: bf8680fd NtGdiComputeXformCoefficients [1] (win32k.sys)
1017: bf8c2ae0 NtGdiConsoleTextOut [4] (win32k.sys)
1018: bf90ffab NtGdiConvertMetafileRect [2] (win32k.sys)
1019: bf80e3ff NtGdiCreateBitmap [5] (win32k.sys)
101a: bf8dc92d NtGdiCreateClientObj [1] (win32k.sys)
101b: bf949c0f NtGdiCreateColorSpace [1] (win32k.sys)
101c: bf94ab0e NtGdiCreateColorTransform [8] (win32k.sys)
101d: bf80fc6e NtGdiCreateCompatibleBitmap [3] (win32k.sys)
101e: bf80d0ca NtGdiCreateCompatibleDC [1] (win32k.sys)
101f: bf8d1611 NtGdiCreateDIBBrush [6] (win32k.sys)
1020: bf835fbd NtGdiCreateDIBitmapInternal [11] (win32k.sys)
1021: bf830619 NtGdiCreateDIBSection [9] (win32k.sys)
1022: bf938572 NtGdiCreateEllipticRgn [4] (win32k.sys)
1023: bf8505d2 NtGdiCreateHalftonePalette [1] (win32k.sys)
1024: bf94bb9a NtGdiCreateHatchBrushInternal [3] (win32k.sys)
1025: bf8e6487 NtGdiCreateMetafileDC [1] (win32k.sys)
1026: bf866d10 NtGdiCreatePaletteInternal [2] (win32k.sys)
1027: bf84bb68 NtGdiCreatePatternBrushInternal [3] (win32k.sys)
1028: bf860340 NtGdiCreatePen [4] (win32k.sys)
1029: bf84332c NtGdiCreateRectRgn [4] (win32k.sys)
102a: bf871571 NtGdiCreateRoundRectRgn [6] (win32k.sys)
102b: bf90feb0 NtGdiCreateServerMetaFile [6] (win32k.sys)
102c: bf81a067 NtGdiCreateSolidBrush [2] (win32k.sys)
102d: bf93376d NtGdiD3dContextCreate [4] (win32k.sys)
102e: bf933780 NtGdiD3dContextDestroy [1] (win32k.sys)
102f: bf933793 NtGdiD3dContextDestroyAll [1] (win32k.sys)
1030: bf9337a6 NtGdiD3dValidateTextureStageState [1] (win32k.sys)
1031: bf9337b9 NtGdiD3dDrawPrimitives2 [7] (win32k.sys)
1032: bf9337cc NtGdiDdGetDriverState [1] (win32k.sys)
1033: bf933642 NtGdiDdAddAttachedSurface [3] (win32k.sys)
1034: bf93388c NtGdiDdAlphaBlt [3] (win32k.sys)
1035: bf907c90 NtGdiDdAttachSurface [2] (win32k.sys)
1036: bf933837 NtGdiDdBeginMoCompFrame [2] (win32k.sys)
1037: bf907ca3 NtGdiDdBlt [3] (win32k.sys)
1038: bf907a7d NtGdiDdCanCreateSurface [2] (win32k.sys)
1039: bf933744 NtGdiDdCanCreateD3DBuffer [2] (win32k.sys)
103a: bf933655 NtGdiDdColorControl [2] (win32k.sys)
103b: bf8edd03 NtGdiDdCreateDirectDrawObject [1] (win32k.sys)
103c: bf8edd16 NtGdiDdCreateSurface [8] (win32k.sys)
103d: bf93372e NtGdiDdCreateD3DBuffer [8] (win32k.sys)
103e: bf907abc NtGdiDdCreateMoComp [2] (win32k.sys)
103f: bf9080fb NtGdiDdCreateSurfaceObject [6] (win32k.sys)
1040: bf8edf5f NtGdiDdDeleteDirectDrawObject [1] (win32k.sys)
1041: bf907c64 NtGdiDdDeleteSurfaceObject [1] (win32k.sys)
1042: bf907a90 NtGdiDdDestroyMoComp [2] (win32k.sys)
1043: bf8edf49 NtGdiDdDestroySurface [2] (win32k.sys)
1044: bf933757 NtGdiDdDestroyD3DBuffer [1] (win32k.sys)
1045: bf93384a NtGdiDdEndMoCompFrame [2] (win32k.sys)
1046: bf9081a1 NtGdiDdFlip [5] (win32k.sys)
1047: bf9088ac NtGdiDdFlipToGDISurface [2] (win32k.sys)
1048: bf907c7a NtGdiDdGetAvailDriverMemory [2] (win32k.sys)
1049: bf933668 NtGdiDdGetBltStatus [2] (win32k.sys)
104a: bf9079e8 NtGdiDdGetDC [2] (win32k.sys)
104b: bf907a27 NtGdiDdGetDriverInfo [2] (win32k.sys)
104c: bf9336d6 NtGdiDdGetDxHandle [3] (win32k.sys)
104d: bf93367e NtGdiDdGetFlipStatus [2] (win32k.sys)
104e: bf933821 NtGdiDdGetInternalMoCompInfo [2] (win32k.sys)
104f: bf93380b NtGdiDdGetMoCompBuffInfo [2] (win32k.sys)
1050: bf907aa6 NtGdiDdGetMoCompGuids [2] (win32k.sys)
1051: bf9337f5 NtGdiDdGetMoCompFormats [2] (win32k.sys)
1052: bf9089b2 NtGdiDdGetScanLine [2] (win32k.sys)
1053: bf8e421f NtGdiDdLock [3] (win32k.sys)
1054: bf933702 NtGdiDdLockD3D [2] (win32k.sys)
1055: bf8edca2 NtGdiDdQueryDirectDrawObject [11] (win32k.sys)
1056: bf933876 NtGdiDdQueryMoCompStatus [2] (win32k.sys)
1057: bf8edcdd NtGdiDdReenableDirectDrawObject [2] (win32k.sys)
1058: bf907b5c NtGdiDdReleaseDC [1] (win32k.sys)
1059: bf933860 NtGdiDdRenderMoComp [2] (win32k.sys)
105a: bf8e4065 NtGdiDdResetVisrgn [2] (win32k.sys)
105b: bf9081b7 NtGdiDdSetColorKey [2] (win32k.sys)
105c: bf933694 NtGdiDdSetExclusiveMode [2] (win32k.sys)
105d: bf9336ec NtGdiDdSetGammaRamp [3] (win32k.sys)
105e: bf9337df NtGdiDdCreateSurfaceEx [3] (win32k.sys)
105f: bf9336aa NtGdiDdSetOverlayPosition [3] (win32k.sys)
1060: bf907d30 NtGdiDdUnattachSurface [2] (win32k.sys)
1061: bf8e4015 NtGdiDdUnlock [2] (win32k.sys)
1062: bf933718 NtGdiDdUnlockD3D [2] (win32k.sys)
1063: bf90818b NtGdiDdUpdateOverlay [3] (win32k.sys)
1064: bf9336c0 NtGdiDdWaitForVerticalBlank [2] (win32k.sys)
1065: bf93389f NtGdiDvpCanCreateVideoPort [2] (win32k.sys)
1066: bf9338b5 NtGdiDvpColorControl [2] (win32k.sys)
1067: bf9338cb NtGdiDvpCreateVideoPort [2] (win32k.sys)
1068: bf9338e1 NtGdiDvpDestroyVideoPort [2] (win32k.sys)
1069: bf9338f7 NtGdiDvpFlipVideoPort [4] (win32k.sys)
106a: bf93390d NtGdiDvpGetVideoPortBandwidth [2] (win32k.sys)
106b: bf933923 NtGdiDvpGetVideoPortField [2] (win32k.sys)
106c: bf933939 NtGdiDvpGetVideoPortFlipStatus [2] (win32k.sys)
106d: bf93394f NtGdiDvpGetVideoPortInputFormats [2] (win32k.sys)
106e: bf933965 NtGdiDvpGetVideoPortLine [2] (win32k.sys)
106f: bf93397b NtGdiDvpGetVideoPortOutputFormats [2] (win32k.sys)
1070: bf933991 NtGdiDvpGetVideoPortConnectInfo [2] (win32k.sys)
1071: bf9339a7 NtGdiDvpGetVideoSignalStatus [2] (win32k.sys)
1072: bf9339bd NtGdiDvpUpdateVideoPort [4] (win32k.sys)
1073: bf9339d3 NtGdiDvpWaitForVideoPortSync [2] (win32k.sys)
1074: bf9339e9 NtGdiDvpAcquireNotification [3] (win32k.sys)
1075: bf9339ff NtGdiDvpReleaseNotification [2] (win32k.sys)
1076: bf93362f NtGdiDxgGenericThunk [6] (win32k.sys)
1077: bf8dca4f NtGdiDeleteClientObj [1] (win32k.sys)
1078: bf949c02 NtGdiDeleteColorSpace [1] (win32k.sys)
1079: bf94adca NtGdiDeleteColorTransform [2] (win32k.sys)
107a: bf80fafb NtGdiDeleteObjectApp [1] (win32k.sys)
107b: bf949300 NtGdiDescribePixelFormat [4] (win32k.sys)
107c: bf8fae59 NtGdiGetPerBandInfo [2] (win32k.sys)
107d: bf8fc4a0 NtGdiDoBanding [4] (win32k.sys)
107e: bf8462f6 NtGdiDoPalette [6] (win32k.sys)
107f: bf94819b NtGdiDrawEscape [4] (win32k.sys)
1080: bf8d4128 NtGdiEllipse [5] (win32k.sys)
1081: bf87feeb NtGdiEnableEudc [1] (win32k.sys)
1082: bf8fbde9 NtGdiEndDoc [1] (win32k.sys)
1083: bf90528c NtGdiEndPage [1] (win32k.sys)
1084: bf900871 NtGdiEndPath [1] (win32k.sys)
1085: bf86c03c NtGdiEnumFontChunk [5] (win32k.sys)
1086: bf86bfbb NtGdiEnumFontClose [1] (win32k.sys)
1087: bf86b64a NtGdiEnumFontOpen [7] (win32k.sys)
1088: bf8d1919 NtGdiEnumObjects [4] (win32k.sys)
1089: bf93866d NtGdiEqualRgn [2] (win32k.sys)
108a: bf94f3a5 NtGdiEudcLoadUnloadLink [7] (win32k.sys)
108b: bf83d3ec NtGdiExcludeClipRect [5] (win32k.sys)
108c: bf8c9d03 NtGdiExtCreatePen [11] (win32k.sys)
108d: bf843673 NtGdiExtCreateRegion [3] (win32k.sys)
108e: bf857d41 NtGdiExtEscape [8] (win32k.sys)
108f: bf9501c3 NtGdiExtFloodFill [5] (win32k.sys)
1090: bf82b9c2 NtGdiExtGetObjectW [3] (win32k.sys)
1091: bf80f2bf NtGdiExtSelectClipRgn [3] (win32k.sys)
1092: bf8326e3 NtGdiExtTextOutW [9] (win32k.sys)
1093: bf947338 NtGdiFillPath [1] (win32k.sys)
1094: bf8bccd8 NtGdiFillRgn [3] (win32k.sys)
1095: bf94729d NtGdiFlattenPath [1] (win32k.sys)
1096: bf80c227 NtGdiFlushUserBatch [0] (win32k.sys)
1097: bf8079da NtGdiFlush [0] (win32k.sys)
1098: bf9491e0 NtGdiForceUFIMapping [2] (win32k.sys)
1099: bf8717e3 NtGdiFrameRgn [5] (win32k.sys)
109a: bf93b346 NtGdiFullscreenControl [5] (win32k.sys)
109b: bf8c8fd4 NtGdiGetAndSetDCDword [4] (win32k.sys)
109c: bf816ad6 NtGdiGetAppClipBox [2] (win32k.sys)
109d: bf8bd1cb NtGdiGetBitmapBits [3] (win32k.sys)
109e: bf949102 NtGdiGetBitmapDimension [2] (win32k.sys)
109f: bf8550d0 NtGdiGetBoundsRect [3] (win32k.sys)
10a0: bf8f9158 NtGdiGetCharABCWidthsW [6] (win32k.sys)
10a1: bf9478a6 NtGdiGetCharacterPlacementW [6] (win32k.sys)
10a2: bf80f88b NtGdiGetCharSet [1] (win32k.sys)
10a3: bf8eb40e NtGdiGetCharWidthW [6] (win32k.sys)
10a4: bf8677ce NtGdiGetCharWidthInfo [2] (win32k.sys)
10a5: bf9484bd NtGdiGetColorAdjustment [2] (win32k.sys)
10a6: bf950a78 NtGdiGetColorSpaceforBitmap [1] (win32k.sys)
10a7: bf82bc8f NtGdiGetDCDword [3] (win32k.sys)
10a8: bf836670 NtGdiGetDCforBitmap [1] (win32k.sys)
10a9: bf82bb1c NtGdiGetDCObject [2] (win32k.sys)
10aa: bf8c5385 NtGdiGetDCPoint [3] (win32k.sys)
10ab: bf9486b9 NtGdiGetDeviceCaps [2] (win32k.sys)
10ac: bf94a1a1 NtGdiGetDeviceGammaRamp [2] (win32k.sys)
10ad: bf8fa1c5 NtGdiGetDeviceCapsAll [2] (win32k.sys)
10ae: bf8480db NtGdiGetDIBitsInternal [9] (win32k.sys)
10af: bf9519db NtGdiGetETM [2] (win32k.sys)
10b0: bf94ce47 NtGdiGetEudcTimeStampEx [3] (win32k.sys)
10b1: bf8ecbfc NtGdiGetFontData [5] (win32k.sys)
10b2: bf948958 NtGdiGetFontResourceInfoInternalW [7] (win32k.sys)
10b3: bf9495e3 NtGdiGetGlyphIndicesW [5] (win32k.sys)
10b4: bf949486 NtGdiGetGlyphIndicesWInternal [6] (win32k.sys)
10b5: bf9482ae NtGdiGetGlyphOutline [8] (win32k.sys)
10b6: bf9483b3 NtGdiGetKerningPairs [3] (win32k.sys)
10b7: bf93567a NtGdiGetLinkedUFIs [3] (win32k.sys)
10b8: bf8e64ef NtGdiGetMiterLimit [2] (win32k.sys)
10b9: bf93e26d NtGdiGetMonitorID [3] (win32k.sys)
10ba: bf82c560 NtGdiGetNearestColor [2] (win32k.sys)
10bb: bf94bc20 NtGdiGetNearestPaletteIndex [2] (win32k.sys)
10bc: bf948444 NtGdiGetObjectBitmapHandle [2] (win32k.sys)
10bd: bf8eaaf7 NtGdiGetOutlineTextMetricsInternalW [4] (win32k.sys)
10be: bf947705 NtGdiGetPath [4] (win32k.sys)
10bf: bf8490cb NtGdiGetPixel [3] (win32k.sys)
10c0: bf80f2cf NtGdiGetRandomRgn [3] (win32k.sys)
10c1: bf8ed73a NtGdiGetRasterizerCaps [2] (win32k.sys)
10c2: bf94968e NtGdiGetRealizationInfo [3] (win32k.sys)
10c3: bf8a038f NtGdiGetRegionData [3] (win32k.sys)
10c4: bf8c52cf NtGdiGetRgnBox [2] (win32k.sys)
10c5: bf91010a NtGdiGetServerMetaFileBits [7] (win32k.sys)
10c6: bf8759c4 NtGdiGetSpoolMessage [4] (win32k.sys)
10c7: bf951b58 NtGdiGetStats [5] (win32k.sys)
10c8: bf81fa4a NtGdiGetStockObject [1] (win32k.sys)
10c9: bf94ea39 NtGdiGetStringBitmapW [5] (win32k.sys)
10ca: bf8f4bb1 NtGdiGetSystemPaletteUse [1] (win32k.sys)
10cb: bf83ab9c NtGdiGetTextCharsetInfo [3] (win32k.sys)
10cc: bf84fb9a NtGdiGetTextExtent [5] (win32k.sys)
10cd: bf8d117f NtGdiGetTextExtentExW [8] (win32k.sys)
10ce: bf83bbde NtGdiGetTextFaceW [4] (win32k.sys)
10cf: bf83a9fa NtGdiGetTextMetricsW [3] (win32k.sys)
10d0: bf854142 NtGdiGetTransform [3] (win32k.sys)
10d1: bf948b9f NtGdiGetUFI [6] (win32k.sys)
10d2: bf948c68 NtGdiGetEmbUFI [7] (win32k.sys)
10d3: bf948d48 NtGdiGetUFIPathname [10] (win32k.sys)
10d4: bf948b20 NtGdiGetEmbedFonts [0] (win32k.sys)
10d5: bf948b2a NtGdiChangeGhostFont [2] (win32k.sys)
10d6: bf9349ac NtGdiAddEmbFontToDC [2] (win32k.sys)
10d7: bf949607 NtGdiGetFontUnicodeRanges [2] (win32k.sys)
10d8: bf83adee NtGdiGetWidthTable [7] (win32k.sys)
10d9: bf8558f5 NtGdiGradientFill [6] (win32k.sys)
10da: bf82be35 NtGdiHfontCreate [5] (win32k.sys)
10db: bf94a785 NtGdiIcmBrushInfo [8] (win32k.sys)
10dc: bf8c1c8c NtGdiInit [0] (win32k.sys)
10dd: bf881f11 NtGdiInitSpool [0] (win32k.sys)
10de: bf8165ff NtGdiIntersectClipRect [5] (win32k.sys)
10df: bf8f86a2 NtGdiInvertRgn [2] (win32k.sys)
10e0: bf8c6be1 NtGdiLineTo [3] (win32k.sys)
10e1: bf94937a NtGdiMakeFontDir [5] (win32k.sys)
10e2: bf950ab1 NtGdiMakeInfoDC [2] (win32k.sys)
10e3: bf835d8e NtGdiMaskBlt [13] (win32k.sys)
10e4: bf853f1f NtGdiModifyWorldTransform [3] (win32k.sys)
10e5: bf8e66c2 NtGdiMonoBitmap [1] (win32k.sys)
10e6: bf94864b NtGdiMoveTo [4] (win32k.sys)
10e7: bf8fc33b NtGdiOffsetClipRgn [3] (win32k.sys)
10e8: bf837186 NtGdiOffsetRgn [3] (win32k.sys)
10e9: bf84b6a2 NtGdiOpenDCW [7] (win32k.sys)
10ea: bf8c493d NtGdiPatBlt [6] (win32k.sys)
10eb: bf83573d NtGdiPolyPatBlt [5] (win32k.sys)
10ec: bf947412 NtGdiPathToRegion [1] (win32k.sys)
10ed: bf800813 NtGdiPlgBlt [11] (win32k.sys)
10ee: bf947d39 NtGdiPolyDraw [4] (win32k.sys)
10ef: bf85fbc2 NtGdiPolyPolyDraw [5] (win32k.sys)
10f0: bf947e36 NtGdiPolyTextOutW [4] (win32k.sys)
10f1: bf948739 NtGdiPtInRegion [3] (win32k.sys)
10f2: bf93880f NtGdiPtVisible [3] (win32k.sys)
10f3: bf948759 NtGdiQueryFonts [3] (win32k.sys)
10f4: bf8c219d NtGdiQueryFontAssocInfo [1] (win32k.sys)
10f5: bf8e3571 NtGdiRectangle [5] (win32k.sys)
10f6: bf8edfb2 NtGdiRectInRegion [2] (win32k.sys)
10f7: bf8394bf NtGdiRectVisible [2] (win32k.sys)
10f8: bf8d0a5a NtGdiRemoveFontResourceW [6] (win32k.sys)
10f9: bf94893c NtGdiRemoveFontMemResourceEx [1] (win32k.sys)
10fa: bf8e2fd0 NtGdiResetDC [5] (win32k.sys)
10fb: bf94be94 NtGdiResizePalette [2] (win32k.sys)
10fc: bf831368 NtGdiRestoreDC [2] (win32k.sys)
10fd: bf90df4c NtGdiRoundRect [7] (win32k.sys)
10fe: bf831378 NtGdiSaveDC [1] (win32k.sys)
10ff: bf9411d6 NtGdiScaleViewportExtEx [6] (win32k.sys)
1100: bf94908e NtGdiScaleWindowExtEx [6] (win32k.sys)
1101: bf808d5e GreSelectBitmap [2] (win32k.sys)
1102: bf94862b NtGdiSelectBrush [2] (win32k.sys)
1103: bf90096c NtGdiSelectClipPath [2] (win32k.sys)
1104: bf8240c0 NtGdiSelectFont [2] (win32k.sys)
1105: bf94863b NtGdiSelectPen [2] (win32k.sys)
1106: bf8818fa NtGdiSetBitmapAttributes [2] (win32k.sys)
1107: bf8c4285 NtGdiSetBitmapBits [3] (win32k.sys)
1108: bf94916c NtGdiSetBitmapDimension [4] (win32k.sys)
1109: bf8554d7 NtGdiSetBoundsRect [3] (win32k.sys)
110a: bf9486d9 NtGdiSetBrushAttributes [2] (win32k.sys)
110b: bf8c4323 NtGdiSetBrushOrg [4] (win32k.sys)
110c: bf94851e NtGdiSetColorAdjustment [2] (win32k.sys)
110d: bf949cc4 NtGdiSetColorSpace [2] (win32k.sys)
110e: bf94a4dd NtGdiSetDeviceGammaRamp [2] (win32k.sys)
110f: bf82f410 NtGdiSetDIBitsToDeviceInternal [16] (win32k.sys)
1110: bf89c5c2 NtGdiSetFontEnumeration [1] (win32k.sys)
1111: bf8dce05 NtGdiSetFontXform [3] (win32k.sys)
1112: bf8c6524 NtGdiSetIcmMode [3] (win32k.sys)
1113: bf8fab57 NtGdiSetLinkedUFIs [3] (win32k.sys)
1114: bf94c11e NtGdiSetMagicColors [3] (win32k.sys)
1115: bf8dcb84 NtGdiSetMetaRgn [1] (win32k.sys)
1116: bf8dcba6 NtGdiSetMiterLimit [3] (win32k.sys)
1117: bf94907e NtGdiGetDeviceWidth [1] (win32k.sys)
1118: bf94906e NtGdiMirrorWindowOrg [1] (win32k.sys)
1119: bf83d2f4 NtGdiSetLayout [3] (win32k.sys)
111a: bf84930d NtGdiSetPixel [4] (win32k.sys)
111b: bf952822 NtGdiSetPixelFormat [2] (win32k.sys)
111c: bf948729 NtGdiSetRectRgn [5] (win32k.sys)
111d: bf9486c9 NtGdiSetSystemPaletteUse [2] (win32k.sys)
111e: bf951de8 NtGdiSetTextJustification [3] (win32k.sys)
111f: bf87d5ae NtGdiSetupPublicCFONT [3] (win32k.sys)
1120: bf8dc9a8 NtGdiSetVirtualResolution [5] (win32k.sys)
1121: bf8dce76 NtGdiSetSizeDevice [3] (win32k.sys)
1122: bf904164 NtGdiStartDoc [4] (win32k.sys)
1123: bf9050dd NtGdiStartPage [1] (win32k.sys)
1124: bf8a2a4d NtGdiStretchBlt [12] (win32k.sys)
1125: bf8657b1 NtGdiStretchDIBitsInternal [16] (win32k.sys)
1126: bf8ff4e7 NtGdiStrokeAndFillPath [1] (win32k.sys)
1127: bf947619 NtGdiStrokePath [1] (win32k.sys)
1128: bf9529ca NtGdiSwapBuffers [1] (win32k.sys)
1129: bf8c4ad0 NtGdiTransformPoints [5] (win32k.sys)
112a: bf8538a2 NtGdiTransparentBlt [11] (win32k.sys)
112b: bf949251 NtGdiUnloadPrinterDriver [2] (win32k.sys)
112c: bf952c88 NtGdiUnmapMemFont [1] (win32k.sys)
112d: bf948719 NtGdiUnrealizeObject [1] (win32k.sys)
112e: bf94c12e NtGdiUpdateColors [1] (win32k.sys)
112f: bf9474fa NtGdiWidenPath [1] (win32k.sys)
1130: bf869f82 NtUserActivateKeyboardLayout [2] (win32k.sys)
1131: bf86fa8e NtUserAlterWindowStyle [3] (win32k.sys)
1132: bf9142c6 NtUserAssociateInputContext [3] (win32k.sys)
1133: bf8f510c NtUserAttachThreadInput [3] (win32k.sys)
1134: bf815a45 NtUserBeginPaint [2] (win32k.sys)
1135: bf8f4bd7 NtUserBitBltSysBmp [8] (win32k.sys)
1136: bf912c62 NtUserBlockInput [1] (win32k.sys)
1137: bf9143fd NtUserBuildHimcList [4] (win32k.sys)
1138: bf83648f NtUserBuildHwndList [7] (win32k.sys)
1139: bf84ed75 NtUserBuildNameList [4] (win32k.sys)
113a: bf912a25 NtUserBuildPropList [4] (win32k.sys)
113b: bf85a261 NtUserCallHwnd [2] (win32k.sys)
113c: bf8370cd NtUserCallHwndLock [2] (win32k.sys)
113d: bf87ef34 NtUserCallHwndOpt [2] (win32k.sys)
113e: bf8372c0 NtUserCallHwndParam [3] (win32k.sys)
113f: bf82cc3b NtUserCallHwndParamLock [3] (win32k.sys)
1140: bf8f4ae6 NtUserCallMsgFilter [2] (win32k.sys)
1141: bf8f64fd NtUserCallNextHookEx [4] (win32k.sys)
1142: bf8010bf NtUserCallNoParam [1] (win32k.sys)
1143: bf801077 NtUserCallOneParam [2] (win32k.sys)
1144: bf837280 NtUserCallTwoParam [3] (win32k.sys)
1145: bf8f96eb NtUserChangeClipboardChain [2] (win32k.sys)
1146: bf89aba4 NtUserChangeDisplaySettings [5] (win32k.sys)
1147: bf89f753 NtUserCheckImeHotKey [2] (win32k.sys)
1148: bf8cc9c3 NtUserCheckMenuItem [3] (win32k.sys)
1149: bf8783bf NtUserChildWindowFromPointEx [4] (win32k.sys)
114a: bf8fa977 NtUserClipCursor [1] (win32k.sys)
114b: bf8f85a7 NtUserCloseClipboard [0] (win32k.sys)
114c: bf84ea50 NtUserCloseDesktop [1] (win32k.sys)
114d: bf84eb12 NtUserCloseWindowStation [1] (win32k.sys)
114e: bf8c16c0 NtUserConsoleControl [3] (win32k.sys)
114f: bf8ea924 NtUserConvertMemHandle [2] (win32k.sys)
1150: bf90d585 NtUserCopyAcceleratorTable [3] (win32k.sys)
1151: bf8f4b8b NtUserCountClipboardFormats [0] (win32k.sys)
1152: bf8504f7 NtUserCreateAcceleratorTable [2] (win32k.sys)
1153: bf85ed1f NtUserCreateCaret [4] (win32k.sys)
1154: bf8814e0 NtUserCreateDesktop [5] (win32k.sys)
1155: bf91422c NtUserCreateInputContext [1] (win32k.sys)
1156: bf8f9a46 NtUserCreateLocalMemHandle [4] (win32k.sys)
1157: bf83ed9a NtUserCreateWindowEx [15] (win32k.sys)
1158: bf881c51 NtUserCreateWindowStation [7] (win32k.sys)
1159: bf911aaf NtUserDdeGetQualityOfService [3] (win32k.sys)
115a: bf87fbe5 NtUserDdeInitialize [5] (win32k.sys)
115b: bf9119df NtUserDdeSetQualityOfService [3] (win32k.sys)
115c: bf84b442 NtUserDeferWindowPos [8] (win32k.sys)
115d: bf8a0048 NtUserDefSetText [2] (win32k.sys)
115e: bf85f14b NtUserDeleteMenu [3] (win32k.sys)
115f: bf8fa916 NtUserDestroyAcceleratorTable [1] (win32k.sys)
1160: bf838fd8 NtUserDestroyCursor [2] (win32k.sys)
1161: bf91427c NtUserDestroyInputContext [1] (win32k.sys)
1162: bf84847d NtUserDestroyMenu [1] (win32k.sys)
1163: bf8496bf NtUserDestroyWindow [1] (win32k.sys)
1164: bf914a34 NtUserDisableThreadIme [1] (win32k.sys)
1165: bf80ed61 NtUserDispatchMessage [1] (win32k.sys)
1166: bf912b20 NtUserDragDetect [3] (win32k.sys)
1167: bf910fa3 NtUserDragObject [5] (win32k.sys)
1168: bf911c7f NtUserDrawAnimatedRects [4] (win32k.sys)
1169: bf911d42 NtUserDrawCaption [4] (win32k.sys)
116a: bf90b405 NtUserDrawCaptionTemp [7] (win32k.sys)
116b: bf83d569 NtUserDrawIconEx [11] (win32k.sys)
116c: bf912ced NtUserDrawMenuBarTemp [5] (win32k.sys)
116d: bf8ea5a9 NtUserEmptyClipboard [0] (win32k.sys)
116e: bf8c548a NtUserEnableMenuItem [3] (win32k.sys)
116f: bf91195a NtUserEnableScrollBar [3] (win32k.sys)
1170: bf82c6f3 NtUserEndDeferWindowPosEx [2] (win32k.sys)
1171: bf911deb NtUserEndMenu [0] (win32k.sys)
1172: bf8156fc NtUserEndPaint [2] (win32k.sys)
1173: bf8a1ce7 NtUserEnumDisplayDevices [4] (win32k.sys)
1174: bf8389a2 NtUserEnumDisplayMonitors [4] (win32k.sys)
1175: bf858fec NtUserEnumDisplaySettings [4] (win32k.sys)
1176: bf911230 NtUserEvent [1] (win32k.sys)
1177: bf8f88a8 NtUserExcludeUpdateRgn [2] (win32k.sys)
1178: bf8f4a1d NtUserFillWindow [4] (win32k.sys)
1179: bf81b798 NtUserFindExistingCursorIcon [3] (win32k.sys)
117a: bf84c8e9 NtUserFindWindowEx [5] (win32k.sys)
117b: bf914e23 NtUserFlashWindowEx [1] (win32k.sys)
117c: bf8e87cb NtUserGetAltTabInfo [6] (win32k.sys)
117d: bf82c041 NtUserGetAncestor [2] (win32k.sys)
117e: bf9147d1 NtUserGetAppImeLevel [1] (win32k.sys)
117f: bf85ceed NtUserGetAsyncKeyState [1] (win32k.sys)
1180: bf83ef76 NtUserGetAtomName [2] (win32k.sys)
1181: bf844cf5 NtUserGetCaretBlinkTime [0] (win32k.sys)
1182: bf8c502e NtUserGetCaretPos [1] (win32k.sys)
1183: bf845fb7 NtUserGetClassInfo [5] (win32k.sys)
1184: bf827199 NtUserGetClassName [3] (win32k.sys)
1185: bf8f9881 NtUserGetClipboardData [2] (win32k.sys)
1186: bf8ee077 NtUserGetClipboardFormatName [3] (win32k.sys)
1187: bf8ea69f NtUserGetClipboardOwner [0] (win32k.sys)
1188: bf8c4de7 NtUserGetClipboardSequenceNumber [0] (win32k.sys)
1189: bf911e31 NtUserGetClipboardViewer [0] (win32k.sys)
118a: bf9118c2 NtUserGetClipCursor [1] (win32k.sys)
118b: bf9114f8 NtUserGetComboBoxInfo [2] (win32k.sys)
118c: bf8676e5 NtUserGetControlBrush [3] (win32k.sys)
118d: bf907569 NtUserGetControlColor [4] (win32k.sys)
118e: bf82476f NtUserGetCPD [3] (win32k.sys)
118f: bf867984 NtUserGetCursorFrameInfo [4] (win32k.sys)
1190: bf911615 NtUserGetCursorInfo [1] (win32k.sys)
1191: bf80451f NtUserGetDC [1] (win32k.sys)
1192: bf83c031 NtUserGetDCEx [3] (win32k.sys)
1193: bf83cff6 NtUserGetDoubleClickTime [0] (win32k.sys)
1194: bf823d3d NtUserGetForegroundWindow [0] (win32k.sys)
1195: bf91106c NtUserGetGuiResources [2] (win32k.sys)
1196: bf84d28d NtUserGetGUIThreadInfo [2] (win32k.sys)
1197: bf845723 NtUserGetIconInfo [6] (win32k.sys)
1198: bf845873 NtUserGetIconSize [4] (win32k.sys)
1199: bf91468f NtUserGetImeHotKey [4] (win32k.sys)
119a: bf9144ff NtUserGetImeInfoEx [2] (win32k.sys)
119b: bf9112c1 NtUserGetInternalWindowPos [3] (win32k.sys)
119c: bf8397f5 NtUserGetKeyboardLayoutList [2] (win32k.sys)
119d: bf8f5f96 NtUserGetKeyboardLayoutName [1] (win32k.sys)
119e: bf8bd7c3 NtUserGetKeyboardState [1] (win32k.sys)
119f: bf90b752 NtUserGetKeyNameText [3] (win32k.sys)
11a0: bf823fe8 NtUserGetKeyState [1] (win32k.sys)
11a1: bf9115c1 NtUserGetListBoxInfo [1] (win32k.sys)
11a2: bf911712 NtUserGetMenuBarInfo [4] (win32k.sys)
11a3: bf911b68 NtUserGetMenuIndex [2] (win32k.sys)
11a4: bf91269c NtUserGetMenuItemRect [4] (win32k.sys)
11a5: bf819fa1 NtUserGetMessage [4] (win32k.sys)
11a6: bf912377 NtUserGetMouseMovePointsEx [5] (win32k.sys)
11a7: bf81a219 NtUserGetObjectInformation [5] (win32k.sys)
11a8: bf8f4b5f NtUserGetOpenClipboardWindow [0] (win32k.sys)
11a9: bf911e5d NtUserGetPriorityClipboardFormat [2] (win32k.sys)
11aa: bf81a084 NtUserGetProcessWindowStation [0] (win32k.sys)
11ab: bf9156a3 NtUserGetRawInputBuffer [3] (win32k.sys)
11ac: bf914fa3 NtUserGetRawInputData [5] (win32k.sys)
11ad: bf91517d NtUserGetRawInputDeviceInfo [4] (win32k.sys)
11ae: bf915472 NtUserGetRawInputDeviceList [3] (win32k.sys)
11af: bf915668 NtUserGetRegisteredRawInputDevices [3] (win32k.sys)
11b0: bf848cac NtUserGetScrollBarInfo [3] (win32k.sys)
11b1: bf84352c NtUserGetSystemMenu [2] (win32k.sys)
11b2: bf81a4cf NtUserGetThreadDesktop [2] (win32k.sys)
11b3: bf826b74 NtUserGetThreadState [1] (win32k.sys)
11b4: bf83c2bb NtUserGetTitleBarInfo [2] (win32k.sys)
11b5: bf83ce23 NtUserGetUpdateRect [3] (win32k.sys)
11b6: bf8c5176 NtUserGetUpdateRgn [3] (win32k.sys)
11b7: bf8037e9 NtUserGetWindowDC [1] (win32k.sys)
11b8: bf8f9b14 NtUserGetWindowPlacement [2] (win32k.sys)
11b9: bf90d931 NtUserGetWOWClass [2] (win32k.sys)
11ba: bf910ead NtUserHardErrorControl [3] (win32k.sys)
11bb: bf82c843 NtUserHideCaret [1] (win32k.sys)
11bc: bf911ee6 NtUserHiliteMenuItem [4] (win32k.sys)
11bd: bf912c88 NtUserImpersonateDdeClientWindow [2] (win32k.sys)
11be: bf896086 NtUserInitialize [3] (win32k.sys)
11bf: bf890626 NtUserInitializeClientPfnArrays [4] (win32k.sys)
11c0: bf9113a0 NtUserInitTask [12] (win32k.sys)
11c1: bf83c3b7 NtUserInternalGetWindowText [3] (win32k.sys)
11c2: bf814d93 NtUserInvalidateRect [3] (win32k.sys)
11c3: bf848423 NtUserInvalidateRgn [3] (win32k.sys)
11c4: bf8c4dad NtUserIsClipboardFormatAvailable [1] (win32k.sys)
11c5: bf80ea0f NtUserKillTimer [2] (win32k.sys)
11c6: bf872a3d NtUserLoadKeyboardLayoutEx [7] (win32k.sys)
11c7: bf881742 NtUserLockWindowStation [1] (win32k.sys)
11c8: bf8cc90a NtUserLockWindowUpdate [1] (win32k.sys)
11c9: bf910f86 NtUserLockWorkStation [0] (win32k.sys)
11ca: bf8c7db1 NtUserMapVirtualKeyEx [4] (win32k.sys)
11cb: bf912773 NtUserMenuItemFromPoint [4] (win32k.sys)
11cc: bf80efa5 NtUserMessageCall [7] (win32k.sys)
11cd: bf90f513 NtUserMinMaximize [3] (win32k.sys)
11ce: bf912036 NtUserMNDragLeave [0] (win32k.sys)
11cf: bf911f86 NtUserMNDragOver [2] (win32k.sys)
11d0: bf8e31d7 NtUserModifyUserStartupInfoFlags [2] (win32k.sys)
11d1: bf836181 NtUserMoveWindow [6] (win32k.sys)
11d2: bf9149cf NtUserNotifyIMEStatus [3] (win32k.sys)
11d3: bf8c1cc2 NtUserNotifyProcessCreate [4] (win32k.sys)
11d4: bf8c5435 NtUserNotifyWinEvent [4] (win32k.sys)
11d5: bf8f8524 NtUserOpenClipboard [2] (win32k.sys)
11d6: bf84ecea NtUserOpenDesktop [3] (win32k.sys)
11d7: bf87de91 NtUserOpenInputDesktop [3] (win32k.sys)
11d8: bf8f9d5c NtUserOpenWindowStation [2] (win32k.sys)
11d9: bf86a238 NtUserPaintDesktop [1] (win32k.sys)
11da: bf8036d8 NtUserPeekMessage [5] (win32k.sys)
11db: bf808b25 NtUserPostMessage [4] (win32k.sys)
11dc: bf89fb39 NtUserPostThreadMessage [4] (win32k.sys)
11dd: bf89c6c5 NtUserPrintWindow [3] (win32k.sys)
11de: bf8bfa0e NtUserProcessConnect [3] (win32k.sys)
11df: bf912805 NtUserQueryInformationThread [5] (win32k.sys)
11e0: bf914379 NtUserQueryInputContext [2] (win32k.sys)
11e1: bf912bb3 NtUserQuerySendMessage [1] (win32k.sys)
11e2: bf914ad8 NtUserQueryUserCounters [5] (win32k.sys)
11e3: bf803b74 NtUserQueryWindow [2] (win32k.sys)
11e4: bf9116d4 NtUserRealChildWindowFromPoint [3] (win32k.sys)
11e5: bf87d949 NtUserRealInternalGetMessage [6] (win32k.sys)
11e6: bf9125dc NtUserRealWaitMessageEx [2] (win32k.sys)
11e7: bf826d49 NtUserRedrawWindow [4] (win32k.sys)
11e8: bf81f44d NtUserRegisterClassExWOW [7] (win32k.sys)
11e9: bf88203d NtUserRegisterUserApiHook [2] (win32k.sys)
11ea: bf89bc09 NtUserRegisterHotKey [4] (win32k.sys)
11eb: bf9155bc NtUserRegisterRawInputDevices [3] (win32k.sys)
11ec: bf9114c4 NtUserRegisterTasklist [1] (win32k.sys)
11ed: bf807b6b NtUserRegisterWindowMessage [1] (win32k.sys)
11ee: bf89c5ed NtUserRemoveMenu [3] (win32k.sys)
11ef: bf8374fa NtUserRemoveProp [2] (win32k.sys)
11f0: bf876491 NtUserResolveDesktop [4] (win32k.sys)
11f1: bf9158b3 NtUserResolveDesktopForWOW [1] (win32k.sys)
11f2: bf848b53 NtUserSBGetParms [4] (win32k.sys)
11f3: bf8bf31e NtUserScrollDC [7] (win32k.sys)
11f4: bf8e58aa NtUserScrollWindowEx [8] (win32k.sys)
11f5: bf835c08 NtUserSelectPalette [3] (win32k.sys)
11f6: bf8c3327 NtUserSendInput [3] (win32k.sys)
11f7: bf89efd2 NtUserSetActiveWindow [1] (win32k.sys)
11f8: bf914766 NtUserSetAppImeLevel [2] (win32k.sys)
11f9: bf85de45 NtUserSetCapture [1] (win32k.sys)
11fa: bf8486c0 NtUserSetClassLong [4] (win32k.sys)
11fb: bf912053 NtUserSetClassWord [3] (win32k.sys)
11fc: bf8ea848 NtUserSetClipboardData [3] (win32k.sys)
11fd: bf8f9601 NtUserSetClipboardViewer [1] (win32k.sys)
11fe: bf86ad1d NtUserSetConsoleReserveKeys [2] (win32k.sys)
11ff: bf824263 NtUserSetCursor [1] (win32k.sys)
1200: bf912655 NtUserSetCursorContents [2] (win32k.sys)
1201: bf845a02 NtUserSetCursorIconData [4] (win32k.sys)
1202: bf911beb NtUserSetDbgTag [2] (win32k.sys)
1203: bf83c7ad NtUserSetFocus [1] (win32k.sys)
1204: bf872967 NtUserSetImeHotKey [5] (win32k.sys)
1205: bf9145e4 NtUserSetImeInfoEx [1] (win32k.sys)
1206: bf91483b NtUserSetImeOwnerWindow [2] (win32k.sys)
1207: bf8c1926 NtUserSetInformationProcess [4] (win32k.sys)
1208: bf86aae7 NtUserSetInformationThread [4] (win32k.sys)
1209: bf9117e1 NtUserSetInternalWindowPos [4] (win32k.sys)
120a: bf8f8988 NtUserSetKeyboardState [1] (win32k.sys)
120b: bf88a05b NtUserSetLogonNotifyWindow [1] (win32k.sys)
120c: bf90b618 NtUserSetMenu [3] (win32k.sys)
120d: bf911c0e NtUserSetMenuContextHelpId [2] (win32k.sys)
120e: bf89c582 NtUserSetMenuDefaultItem [3] (win32k.sys)
120f: bf911c4b NtUserSetMenuFlagRtoL [1] (win32k.sys)
1210: bf910ef8 NtUserSetObjectInformation [4] (win32k.sys)
1211: bf8674ae NtUserSetParent [2] (win32k.sys)
1212: bf84f0dc NtUserSetProcessWindowStation [1] (win32k.sys)
1213: bf82b7a5 NtUserSetProp [3] (win32k.sys)
1214: bf911bc8 NtUserSetRipFlags [2] (win32k.sys)
1215: bf80e74c NtUserSetScrollInfo [4] (win32k.sys)
1216: bf87e71f NtUserSetShellWindowEx [2] (win32k.sys)
1217: bf91208e NtUserSetSysColors [4] (win32k.sys)
1218: bf91261c NtUserSetSystemCursor [2] (win32k.sys)
1219: bf8f6159 NtUserSetSystemMenu [2] (win32k.sys)
121a: bf912b7a NtUserSetSystemTimer [4] (win32k.sys)
121b: bf84f134 NtUserSetThreadDesktop [1] (win32k.sys)
121c: bf91494e NtUserSetThreadLayoutHandles [2] (win32k.sys)
121d: bf8676a9 NtUserSetThreadState [2] (win32k.sys)
121e: bf803a83 NtUserSetTimer [4] (win32k.sys)
121f: bf867559 NtUserSetWindowFNID [2] (win32k.sys)
1220: bf83760a NtUserSetWindowLong [4] (win32k.sys)
1221: bf872265 NtUserSetWindowPlacement [2] (win32k.sys)
1222: bf82b54c NtUserSetWindowPos [7] (win32k.sys)
1223: bf843281 NtUserSetWindowRgn [3] (win32k.sys)
1224: bf855bc2 NtUserSetWindowsHookAW [3] (win32k.sys)
1225: bf89e35f NtUserSetWindowsHookEx [6] (win32k.sys)
1226: bf8815df NtUserSetWindowStationUser [4] (win32k.sys)
1227: bf8f8f39 NtUserSetWindowWord [3] (win32k.sys)
1228: bf8edad4 NtUserSetWinEventHook [8] (win32k.sys)
1229: bf82c8a5 NtUserShowCaret [1] (win32k.sys)
122a: bf8c56ac NtUserShowScrollBar [3] (win32k.sys)
122b: bf839408 NtUserShowWindow [2] (win32k.sys)
122c: bf876384 NtUserShowWindowAsync [2] (win32k.sys)
122d: bf8e3245 NtUserSoundSentry [0] (win32k.sys)
122e: bf87e9b4 NtUserSwitchDesktop [1] (win32k.sys)
122f: bf81e8fd NtUserSystemParametersInfo [4] (win32k.sys)
1230: bf90dabc NtUserTestForInteractiveUser [1] (win32k.sys)
1231: bf8f60ba NtUserThunkedMenuInfo [2] (win32k.sys)
1232: bf84266b NtUserThunkedMenuItemInfo [6] (win32k.sys)
1233: bf912427 NtUserToUnicodeEx [7] (win32k.sys)
1234: bf89f7d2 NtUserTrackMouseEvent [1] (win32k.sys)
1235: bf912244 NtUserTrackPopupMenuEx [6] (win32k.sys)
1236: bf83c522 NtUserCalcMenuBar [5] (win32k.sys)
1237: bf8eee99 NtUserPaintMenuBar [6] (win32k.sys)
1238: bf8f8191 NtUserTranslateAccelerator [3] (win32k.sys)
1239: bf85c714 NtUserTranslateMessage [2] (win32k.sys)
123a: bf89e94e NtUserUnhookWindowsHookEx [1] (win32k.sys)
123b: bf8edbaf NtUserUnhookWinEvent [1] (win32k.sys)
123c: bf912af2 NtUserUnloadKeyboardLayout [1] (win32k.sys)
123d: bf875f1a NtUserUnlockWindowStation [1] (win32k.sys)
123e: bf81fd1a NtUserUnregisterClass [3] (win32k.sys)
123f: bf881a50 NtUserUnregisterUserApiHook [0] (win32k.sys)
1240: bf91233a NtUserUnregisterHotKey [2] (win32k.sys)
1241: bf914329 NtUserUpdateInputContext [3] (win32k.sys)
1242: bf91119b NtUserUpdateInstance [3] (win32k.sys)
1243: bf8bc594 NtUserUpdateLayeredWindow [9] (win32k.sys)
1244: bf914ee5 NtUserGetLayeredWindowAttributes [4] (win32k.sys)
1245: bf848559 NtUserSetLayeredWindowAttributes [4] (win32k.sys)
1246: bf88725a NtUserUpdatePerUserSystemParameters [2] (win32k.sys)
1247: bf91284c NtUserUserHandleGrantAccess [3] (win32k.sys)
1248: bf80188c NtUserValidateHandleSecure [2] (win32k.sys)
1249: bf8f8b77 NtUserValidateRect [2] (win32k.sys)
124a: bf807e92 NtUserValidateTimerCallback [3] (win32k.sys)
124b: bf8c3ce5 NtUserVkKeyScanEx [3] (win32k.sys)
124c: bf90d300 NtUserWaitForInputIdle [3] (win32k.sys)
124d: bf90c312 NtUserWaitForMsgAndEvent [1] (win32k.sys)
124e: bf80377f NtUserWaitMessage [0] (win32k.sys)
124f: bf910eee NtUserWin32PoolAllocationStats [6] (win32k.sys)
1250: bf82463d NtUserWindowFromPoint [2] (win32k.sys)
1251: bf90da54 NtUserYieldTask [0] (win32k.sys)
1252: bf87e2a6 NtUserRemoteConnect [3] (win32k.sys)
1253: bf910d75 NtUserRemoteRedrawRectangle [4] (win32k.sys)
1254: bf910dc2 NtUserRemoteRedrawScreen [0] (win32k.sys)
1255: bf910e16 NtUserRemoteStopScreenUpdates [0] (win32k.sys)
1256: bf910e63 NtUserCtxDisplayIOCtl [3] (win32k.sys)
1257: bf8fbc90 NtGdiEngAssociateSurface [3] (win32k.sys)
1258: bf8fc640 NtGdiEngCreateBitmap [6] (win32k.sys)
1259: bf8fbc5d NtGdiEngCreateDeviceSurface [4] (win32k.sys)
125a: bf952c93 NtGdiEngCreateDeviceBitmap [4] (win32k.sys)
125b: bf8def59 NtGdiEngCreatePalette [6] (win32k.sys)
125c: bf9062fd NtGdiEngComputeGlyphSet [3] (win32k.sys)
125d: bf952de9 NtGdiEngCopyBits [6] (win32k.sys)
125e: bf8dfae5 NtGdiEngDeletePalette [1] (win32k.sys)
125f: bf8fbbe3 NtGdiEngDeleteSurface [1] (win32k.sys)
1260: bf953c4c NtGdiEngEraseSurface [3] (win32k.sys)
1261: bf8ffe99 NtGdiEngUnlockSurface [1] (win32k.sys)
1262: bf8fc095 NtGdiEngLockSurface [1] (win32k.sys)
1263: bf904e81 NtGdiEngBitBlt [11] (win32k.sys)
1264: bf900272 NtGdiEngStretchBlt [11] (win32k.sys)
1265: bf9531e1 NtGdiEngPlgBlt [11] (win32k.sys)
1266: bf8fc736 NtGdiEngMarkBandingSurface [1] (win32k.sys)
1267: bf8fd530 NtGdiEngStrokePath [8] (win32k.sys)
1268: bf9533d8 NtGdiEngFillPath [7] (win32k.sys)
1269: bf8fe1c5 NtGdiEngStrokeAndFillPath [10] (win32k.sys)
126a: bf953543 NtGdiEngPaint [5] (win32k.sys)
126b: bf95365f NtGdiEngLineTo [9] (win32k.sys)
126c: bf953788 NtGdiEngAlphaBlend [7] (win32k.sys)
126d: bf953907 NtGdiEngGradientFill [10] (win32k.sys)
126e: bf953ae0 NtGdiEngTransparentBlt [8] (win32k.sys)
126f: bf8fed36 NtGdiEngTextOut [10] (win32k.sys)
1270: bf952f85 NtGdiEngStretchBltROP [13] (win32k.sys)
1271: bf9543fe NtGdiXLATEOBJ_cGetPalette [4] (win32k.sys)
1272: bf9544ba NtGdiXLATEOBJ_iXlate [2] (win32k.sys)
1273: bf9543b0 NtGdiXLATEOBJ_hGetColorTransform [1] (win32k.sys)
1274: bf8fda2d NtGdiCLIPOBJ_bEnum [3] (win32k.sys)
1275: bf8fdada NtGdiCLIPOBJ_cEnumStart [5] (win32k.sys)
1276: bf953d16 NtGdiCLIPOBJ_ppoGetPath [1] (win32k.sys)
1277: bf953d54 NtGdiEngDeletePath [1] (win32k.sys)
1278: bf953d8e NtGdiEngCreateClip [0] (win32k.sys)
1279: bf953dc0 NtGdiEngDeleteClip [1] (win32k.sys)
127a: bf8fd098 NtGdiBRUSHOBJ_ulGetBrushColor [1] (win32k.sys)
127b: bf953dfa NtGdiBRUSHOBJ_pvAllocRbrush [2] (win32k.sys)
127c: bf953e4b NtGdiBRUSHOBJ_pvGetRbrush [1] (win32k.sys)
127d: bf906383 NtGdiBRUSHOBJ_hGetColorTransform [1] (win32k.sys)
127e: bf905ccc NtGdiXFORMOBJ_bApplyXform [5] (win32k.sys)
127f: bf8faf8d NtGdiXFORMOBJ_iGetXform [2] (win32k.sys)
1280: bf905e8d NtGdiFONTOBJ_vGetInfo [3] (win32k.sys)
1281: bf8faef3 NtGdiFONTOBJ_pxoGetXform [1] (win32k.sys)
1282: bf905931 NtGdiFONTOBJ_cGetGlyphs [5] (win32k.sys)
1283: bf8fb0fe NtGdiFONTOBJ_pifi [1] (win32k.sys)
1284: bf954575 NtGdiFONTOBJ_pfdg [1] (win32k.sys)
1285: bf95467c NtGdiFONTOBJ_pQueryGlyphAttrs [2] (win32k.sys)
1286: bf9542e0 NtGdiFONTOBJ_pvTrueTypeFontFile [2] (win32k.sys)
1287: bf953e99 NtGdiFONTOBJ_cGetAllGlyphHandles [2] (win32k.sys)
1288: bf954754 NtGdiSTROBJ_bEnum [3] (win32k.sys)
1289: bf9060bb NtGdiSTROBJ_bEnumPositionsOnly [3] (win32k.sys)
128a: bf8fb211 NtGdiSTROBJ_bGetAdvanceWidths [4] (win32k.sys)
128b: bf9060d9 NtGdiSTROBJ_vEnumStart [1] (win32k.sys)
128c: bf953f64 NtGdiSTROBJ_dwGetCodePage [1] (win32k.sys)
128d: bf954055 NtGdiPATHOBJ_vGetBounds [2] (win32k.sys)
128e: bf954772 NtGdiPATHOBJ_bEnum [2] (win32k.sys)
128f: bf9540e6 NtGdiPATHOBJ_vEnumStart [1] (win32k.sys)
1290: bf95412a NtGdiPATHOBJ_vEnumStartClipLines [4] (win32k.sys)
1291: bf9541d7 NtGdiPATHOBJ_bEnumClipLines [3] (win32k.sys)
1292: bf952c61 NtGdiGetDhpdev [1] (win32k.sys)
1293: bf95450c NtGdiEngCheckAbort [1] (win32k.sys)
1294: bf905776 NtGdiHT_Get8BPPFormatPalette [4] (win32k.sys)
1295: bf952cd5 NtGdiHT_Get8BPPMaskPalette [6] (win32k.sys)
1296: bf94139b NtGdiUpdateTransform [1] (win32k.sys)
1297: bf8dd671 NtGdiSetPUMPDOBJ [4] (win32k.sys)
1298: bf953fb2 NtGdiBRUSHOBJ_DeleteRbrush [2] (win32k.sys)
1299: bf952c88 NtGdiUnmapMemFont [1] (win32k.sys)
129a: bf817785 NtGdiDrawStream [3] (win32k.sys)

blabberer
July 14th, 2007, 11:58
sorry no idea i thought you were trying to retrieve the tcb.servicetable

see if some thing below makes sense

Code:

Opened log file 'c:\win32k.log'
lkd> !thread 80daac20
THREAD 80daac20 Cid 01c8.06f8 Teb: 7ff9f000 Win32Thread: e10f2880 WAIT: (UserRequest) UserMode Non-Alertable
80d8ce90 NotificationEvent
80d798b0 SynchronizationEvent
80d7beb0 SynchronizationEvent
80de24f8 NotificationTimer
Not impersonating
DeviceMap e10069e8
Owning Process 80d07da8 Image: WINLOGON.EXE
Wait Start TickCount 2757608 Ticks: 173967 (0:00:45:18.234)
Context Switch Count 1537 LargeStack
UserTime 00:00:00.031
KernelTime 00:00:00.234
Win32 Start Address USERENV!GPOThread (0x75a7db95)
Start Address kernel32!BaseThreadStartThunk (0x77e7d342)
Stack Init f6f08000 Current f6f0795c Base f6f08000 Limit f6f05000 Call 0
Priority 1 BasePriority 1 PriorityDecrement 0 DecrementCount 16
Kernel stack not resident.


lkd> dt nt!_Ethread Tcb.ServiceTable 80daac20
nt!_ETHREAD
+0x000 Tcb :
+0x0e0 ServiceTable : 0x8054ae80
lkd> .printf "%y\n", 8054ae80
nt!KeServiceDescriptorTableShadow (8054ae80)
lkd> dd e10f2880
e10f2880 80daac20 00000001 00000000 00000000
e10f2890 00000000 00000000 00000000 00000000
e10f28a0 00000000 00000000 00000000 e20307b0
e10f28b0 e26adc30 e202d008 bc6028d8 80cda118
e10f28c0 bc600650 7ff9f6cc 03000000 00000000
e10f28d0 00000000 00000000 00000000 00000000
e10f28e0 00000000 00000000 00000094 00000000
e10f28f0 00000000 00000000 00000000 00000000
lkd> dt nt!_Ethread Tcb.ServiceTable poi(e10f2880)
nt!_ETHREAD
+0x000 Tcb :
+0x0e0 ServiceTable : 0x8054ae80

another instance you can see the pointer refererancing its self in the struct Tcb

lkd> dt nt!_Ethread Tcb. poi(e22fd008)
nt!_ETHREAD
+0x000 Tcb :
+0x000 Header : _DISPATCHER_HEADER
+0x010 MutantListHead : _LIST_ENTRY [ 0x80d24590 - 0x80d24590 ]
+0x018 InitialStack : 0xf816d000
+0x01c StackLimit : 0xf816a000
+0x020 Teb : 0x7ffd6000
+0x024 TlsArray : (null)
+0x028 KernelStack : 0xf816cc70
+0x02c DebugActive : 0 ''
+0x02d State : 0x5 ''
+0x02e Alerted : [2] ""
+0x030 Iopl : 0 ''
+0x031 NpxState : 0xa ''
+0x032 Saturation : 0 ''
+0x033 Priority : 8 ''
+0x034 ApcState : _KAPC_STATE
+0x04c ContextSwitches : 0x4eed5
+0x050 IdleSwapBlock : 0 ''
+0x051 Spare0 : [3] ""
+0x054 WaitStatus : 0
+0x058 WaitIrql : 0 ''
+0x059 WaitMode : 1 ''
+0x05a WaitNext : 0 ''
+0x05b WaitReason : 0xf ''
+0x05c WaitBlockList : 0x80d245f0 _KWAIT_BLOCK
+0x060 WaitListEntry : _LIST_ENTRY [ 0x0 - 0x8054acc8 ]
+0x060 SwapListEntry : _SINGLE_LIST_ENTRY
+0x068 WaitTime : 0x2f0ada
+0x06c BasePriority : 8 ''
+0x06d DecrementCount : 0x10 ''
+0x06e PriorityDecrement : 0 ''
+0x06f Quantum : 1 ''
+0x070 WaitBlock : [4] _KWAIT_BLOCK
+0x0d0 LegoData : (null)
+0x0d4 KernelApcDisable : 0
+0x0d8 UserAffinity : 1
+0x0dc SystemAffinityActive : 0 ''
+0x0dd PowerState : 0 ''
+0x0de NpxIrql : 0 ''
+0x0df InitialNode : 0 ''
+0x0e0 ServiceTable : 0x8054ae80
+0x0e4 Queue : 0x80dec0a8 _KQUEUE
+0x0e8 ApcQueueLock : 0
+0x0f0 Timer : _KTIMER
+0x118 QueueListEntry : _LIST_ENTRY [ 0x80cd9790 - 0x80dec0c8 ]
+0x120 SoftAffinity : 1
+0x124 Affinity : 1
+0x128 Preempted : 0 ''
+0x129 ProcessReadyQueue : 0 ''
+0x12a KernelStackResident : 0 ''
+0x12b NextProcessor : 0 ''
+0x12c CallbackStack : (null)
+0x130 Win32Thread : 0xe22fd008 <--------
+0x134 TrapFrame : 0xf816cd64 _KTRAP_FRAME
+0x138 ApcStatePointer : [2] 0x80d245b4 _KAPC_STATE
+0x140 PreviousMode : 1 ''
+0x141 EnableStackSwap : 0x1 ''
+0x142 LargeStack : 0x1 ''
+0x143 ResourceIndex : 0x57 'W'
+0x144 KernelTime : 0xb0
+0x148 UserTime : 0x1a4
+0x14c SavedApcState : _KAPC_STATE
+0x164 Alertable : 0 ''
+0x165 ApcStateIndex : 0 ''
+0x166 ApcQueueable : 0x1 ''
+0x167 AutoAlignment : 0 ''
+0x168 StackBase : 0xf816d000
+0x16c SuspendApc : _KAPC
+0x19c SuspendSemaphore : _KSEMAPHORE
+0x1b0 ThreadListEntry : _LIST_ENTRY [ 0xffbd8978 - 0x80de5c00 ]
+0x1b8 FreezeCount : 0 ''
+0x1b9 SuspendCount : 0 ''
+0x1ba IdealProcessor : 0 ''
+0x1bb DisableBoost : 0 ''
lkd>
lkd> .logclose
Closing open log file c:\win32k.log

Kayaker
July 14th, 2007, 14:39
From the looks of it the WinDbg description of Win32Thread as the address of the GDI SSDT is just plain wrong.

Skywing is correct in his strict description, so is the definition from
http://www.codeproject.com/debug/cdbntsd6.asp

"The next is the "Win32Thread". What's this? This is a per-thread data structure that WIN32k.SYS maintains."


Yes, it's related to whether a thread has a gui component (console threads don't have a valid Win32Thread address), but it's sure not the SSDT.

It seems you can pick up some info on the structure from searching for PsSetThreadWin32Thread in win32k.sys.

For example, if we call the "unknown" KTHREAD.Win32Thread pointer structure gptiCurrent, and this is returned by PsGetThreadWin32Thread.

From a previous call to PsGetThreadWin32Thread we can trace that gptiCurrent is the argument on the stack..


Code:
.text:BF845CB1 mov esi, [ebp+gptiCurrent]
.text:BF845CB4 cmp [esi+4], edi
.text:BF845CB7 jnz short loc_BF845D23
.text:BF845CB9 mov ecx, [esi+0A8h] ; Object
.text:BF845CBF cmp ecx, edi
.text:BF845CC1 jz short loc_BF845CC9
.text:BF845CC3 call ds:ObfDereferenceObject


So gptiCurrent + 0xA8 == an Object pointer

Similarly from other bits of code it looks like offsets 0x4c and 0xe4 are memory pointers because they trace down to calls to ExFreePoolWithTag.

Not a lot of info on how win32k.sys initializes the structure pointer Win32Thread.

blabberer
July 15th, 2007, 01:52
googling for _gpticurrent i saw a few chinese boards having some enumhook code

http://translate.google.com/translate?hl=en&sl=zh-CN&u=http://www.zhongts.net/MyEssay/EnumHook.htm&sa=X&oi=translate&resnum=2&ct=result&prev=/search%3Fq%3D_gpticurrent%26hl%3Den

there is a source code for a enumhook.sys

which has some details about members of this elusive NON SSDT

Code:

invoke DbgPrint, $CTA0("ETHREAD:%08X, Win32Thread:%08X\n", eax, _gptiCurrent

assume esi : nothing
mov ebx, -1
.while ebx!=12
invoke _PhkFirstValid, _gptiCurrent, ebx
assume eax : ptr HOOK
.while eax
push eax ;_PhkNextValid 的参数

;根据 win32k.sys 中的 _xxxHkCallHook 得到下面的代码
mov edx, [eax].ihmod
cmp edx, -1
jz @F
mov esi, _gptiCurrent ;esi -> ThreadInfo
mov esi, [esi+2Ch] ;esi -> ProcessInfo
mov edx, [esi+edx*4+0A8h] ;edx = [esi].ahmodLibLoaded[ihmod]


i attached the code here for archival purpose and for inquiring minds
dont blame me for chinese comments

ZaiRoN
July 15th, 2007, 07:10
Quote:
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?
Code:
typedef struct _THREADINFO {
ULONG a[10]; // W32THREAD
PTL ptl; // Listhead for thread lock list +28
PPROCESSINFO ppi; // process info struct for this thread +2C
PQ pq; // keyboard and mouse input queue +30
PKL spklActive; // active keyboard layout for this thread +34
PCLIENTTHREADINFO pcti; // Info that must be visible from client +38
PDESKTOP rpdesk;
PDESKTOPINFO pDeskInfo; // Desktop info visible to client +40
PCLIENTINFO pClientInfo;// Client info stored in TEB +44
ULONG TIF_flags; // TIF_ flags go here. +48
PUNICODE_STRING pstrAppName;// Application module name. +4C
PSMS psmsSent; // Most recent SMS this thread has sent
PSMS psmsCurrent; // Received SMS this thread is currently processing
PSMS psmsReceiveList;// SMSs to be processed
LONG timeLast; // Time, position, and ID of last message
ULONG_PTR idLast;
int cQuit;
int exitCode;
HANDLE hdesk; // Desktop handle. Changed from "HDESK hdesk"
int cPaintsReady;
unsigned int cTimersReady;
PMENUSTATE pMenuState;
union {
PTDB ptdb; // Win16Task Schedule data for WOW thread
PWINDOWSTATION pwinsta; // Window station for SYSTEM thread
};
PSVR_INSTANCE_INFO psiiList; // thread DDEML instance list
ULONG dwExpWinVer;
ULONG dwCompatFlags; // The Win 3.1 Compat flags
ULONG dwCompatFlags2; // new DWORD to extend compat flags for NT5+ features
PQ pqAttach; // calculation variabled used in zzzAttachThreadInput()
void* ptiSibling; // Pointer to sibling thread info. Chnaged from "PTHREADINFO ptiSibling"
PMOVESIZEDATA pmsd;
ULONG fsHooks; // WHF_ Flags for which hooks are installed
PHOOK sphkCurrent;// Hook this thread is currently processing
PSBTRACK pSBTrack;
HANDLE hEventQueueClient;
PKEVENT pEventQueueServer;
LIST_ENTRY PtiLink; // Link to other threads on desktop
int iCursorLevel; // keep track of each thread's level
ULONG b[2]; //POINT ptLast;
PWND spwndDefaultIme;// Default IME Window for this thread
PIMC spDefaultImc; // Default input context for this thread
HANDLE hklPrev; // Previous active. Changed from "HKL hklPrev"
int cEnterCount;
MLIST mlPost; // posted message list.
USHORT fsChangeBitsRemoved;// Bits removed during PeekMessage
WCHAR wchInjected; // character from last VK_PACKET
ULONG fsReserveKeys; // Keys that must be sent to the active +E0
PKEVENT *apEvent; // Wait array for xxxPollAndWaitForSingleObject +E4
ACCESS_MASK amdesk; // Granted access +E8
unsigned int cWindows; // Number of windows owned by this thread +EC
unsigned int cVisWindows; // Number of visible windows on this thread +F0
PHOOK aphkStart[CWINHOOKS]; // Hooks registered for this thread, local hook +F4
CLIENTTHREADINFO cti; // Use this when no desktop is available +F8
} THREADINFO, *PTHREADINFO;
Don't remember exactly where it comes from, maybe from some chinese pages. Iirc I changed something...

The test instruction tests TIF_flags field. In this case compare the value with TIF_ALLOWFOREGROUNDACTIVATE (0x20).

omega_red
July 15th, 2007, 12:30
Thanks a lot guys! I knew the knowledge is out there somewhere.
ZaiRoN, your typedef confirms my hypothesis about the source of this crash.

I'll post details later - just received mail from MS that it's not a security issue (agreed), but they'll have a look at the "product team". Well, unhandled null pointer dereference in kernel mode should be fixed anyway IMO.

Edit: oh, 100th post! *opens up a beer*

blabberer
July 15th, 2007, 12:56
looking at Zairons post especially
PMENUSTATE pMenuState;

rekindled some memories
iirc there was an old kernel debugger extension userkdx.dll
which used to dump out this pmemustate

i just digged it out

ms still provides a userkdx.dbg file from its symbol server but it seems it has been either abandoned or whatever

you can look for sven-b-schreibers book (he recently freed it online iirc)
kerneldebugger command.pdf

which referances this

any way the digged extension doesnt work normally in latest windbg
but spleunking a little
it produces bogus answers

so the functionality still exists to gather this info

some one should find what it is reading in ZwDebugControl in old version

here is a bogus output

Code:

indows XP Kernel Version 2600 (Service Pack 1) UP Free x86 compatible
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 2600.xpsp1.020828-1920
Kernel base = 0x804d4000 PsLoadedModuleList = 0x8054be30
Debug session time: Sun Jul 15 23:16:40.468 2007 (GMT+6)
System Uptime: 0 days 13:08:52.159
lkd> .load userkdx.dll
lkd> !dms

*** Extension DLL(1381 Free) does not match target system(2600 Free)

PMENUSTATE @ 0x0
fInEndMenu
pGlobalPopupMenu 0x360032
ptMouseLast {0x460020, 0x650072}
mnFocus 0xa1e210 cmdLast 0
ptiMenuStateOwner 0x40000060


anyone upto reversing this userkdx.dll and updating these functions ?

disassembly of the said extension

Code:

73047EC0 MOV ESI, DWORD PTR DS:[730657CC]
73047EC6 PUSH DWORD PTR SS:[EBP+C]
73047EC9 PUSH 73053DA8 ; ASCII "PMENUSTATE @ 0x%lX
"
73047ECE CALL NEAR DWORD PTR DS:[ESI+4]
73047ED1 ADD ESP, 8
73047ED4 TEST BYTE PTR SS:[EBP-18], 1
73047ED8 JE SHORT 73047EEA
73047EDA PUSH 73053D98 ; ASCII "fMenuStarted
"
73047EDF MOV EAX, DWORD PTR DS:[730657CC]
73047EE4 CALL NEAR DWORD PTR DS:[EAX+4]
73047EE7 ADD ESP, 4
73047EEA TEST BYTE PTR SS:[EBP-18], 2
73047EEE JE SHORT 73047F00
73047EF0 PUSH 73053CD4 ; ASCII "fIsSysMenu
"
73047EF5 MOV EAX, DWORD PTR DS:[730657CC]
73047EFA CALL NEAR DWORD PTR DS:[EAX+4]
73047EFD ADD ESP, 4
73047F00 TEST BYTE PTR SS:[EBP-18], 4
73047F04 JE SHORT 73047F16
73047F06 PUSH 73053D84 ; ASCII "fInsideMenuLoop
"
73047F0B MOV EAX, DWORD PTR DS:[730657CC]
73047F10 CALL NEAR DWORD PTR DS:[EAX+4]
73047F13 ADD ESP, 4
73047F16 TEST BYTE PTR SS:[EBP-18], 8
73047F1A JE SHORT 73047F2C
73047F1C PUSH 73053D74 ; ASCII "fButtonDown
"
73047F21 MOV EAX, DWORD PTR DS:[730657CC]
73047F26 CALL NEAR DWORD PTR DS:[EAX+4]
73047F29 ADD ESP, 4
73047F2C TEST BYTE PTR SS:[EBP-18], 10
73047F30 JE SHORT 73047F42
73047F32 PUSH 73053D68 ; ASCII "fInEndMenu
"
73047F37 MOV EAX, DWORD PTR DS:[730657CC]
73047F3C CALL NEAR DWORD PTR DS:[EAX+4]
73047F3F ADD ESP, 4
73047F42 MOV ESI, 73053AE0 ; ASCII "%-20s%#10lx
"
73047F47 MOV EAX, DWORD PTR DS:[730657CC]
73047F4C PUSH DWORD PTR SS:[EBP-1C]
73047F4F PUSH 73053D54 ; ASCII "pGlobalPopupMenu"
73047F54 PUSH ESI
73047F55 CALL NEAR DWORD PTR DS:[EAX+4]
73047F58 ADD ESP, 0C
73047F5B MOV EAX, DWORD PTR DS:[730657CC]
73047F60 PUSH DWORD PTR SS:[EBP-10]
73047F63 PUSH DWORD PTR SS:[EBP-14] ; msvcrt.77C46BA7
73047F66 PUSH 73053D48 ; ASCII "ptMouseLast"
73047F6B PUSH 73053D34 ; ASCII "%-20s{%#lx, %#lx}
"
73047F70 CALL NEAR DWORD PTR DS:[EAX+4]
73047F73 ADD ESP, 10
73047F76 MOV EAX, DWORD PTR DS:[730657CC]
73047F7B PUSH DWORD PTR SS:[EBP-8] ; kernel32.77E83AE0
73047F7E PUSH 73053D2C ; ASCII "cmdLast"
73047F83 PUSH DWORD PTR SS:[EBP-C] ; kernel32._except_handler3
73047F86 PUSH 73053D24 ; ASCII "mnFocus"
73047F8B PUSH 73053B78 ; ASCII "%-20s%#10lx %-20s%#10lx
"
73047F90 CALL NEAR DWORD PTR DS:[EAX+4]
73047F93 ADD ESP, 14
73047F96 PUSH DWORD PTR SS:[EBP-4]
73047F99 PUSH 73053D10 ; ASCII "ptiMenuStateOwner"
73047F9E PUSH ESI
73047F9F MOV ESI, DWORD PTR DS:[730657CC]
73047FA5 CALL NEAR DWORD PTR DS:[ESI+4]
73047FA8 ADD ESP, 0C
73047FAB MOV EAX, 1
73047FB0 POP ESI ; ntdll.77F7671A
73047FB1 MOV ESP, EBP
73047FB3 POP EBP ; ntdll.77F7671A
73047FB4 RETN 8


Kayaker
July 16th, 2007, 01:12
Hold on a sec, let's not compare mangos and pomegranates, or apples and oranges or whatever.
I think the structure Zairon posted, as nice a find as it is, is TEB.Win32ThreadInfo, at TEB +0x40,
and not KTHREAD.Win32Thread. See Skywing's warning above not to confuse the two.

If fact, at one site which references that same structure definition they show how to get it from the TEB at fs:18

Code:

PTHREADINFO WINAPI NtPtiCurrent(void)
{
PTHREADINFO pti = NULL;

__asm
{
mov eax,fs:[00000018h]
mov eax,[eax+40h]
mov pti , eax ; pti THREADINFO.
}
return pti;
}


But, since that's not the structure we want, it's back to IDA, Softice and LiveKd...

Searching for instances of PsSetThreadWin32Thread in win32k.sys in IDA (there are only 2 in xpsp2), we find the following proc where the initial memory allocation for a new KTHREAD.Win32Thread structure seems to be made. KTHREAD is the first structure in the ETHREAD structure so the pointers are effectively the same. Win32Thread is at KTHREAD + 0x130.

Note that the memory pool tag name is "Usti" and is 0x14C bytes in size.

Code:

:BF847097 CreateWin32Thread proc near ; CODE XREF: :BF80F018
:BF847097
:BF847097 ETHREAD = dword ptr 8
:BF847097
:BF847097 WIN32THREAD = esi
:BF847097 mov edi, edi
:BF847099 push ebp
:BF84709A mov ebp, esp
:BF84709C push WIN32THREAD
:BF84709D push 1 ; int
:BF84709F push Tag_Usti ; Tag
:BF8470A5 push bytes_0x14C ; NumberOfBytes
:BF8470AB call AllocateTaggedPool
:BF8470B0 mov WIN32THREAD, eax
:BF8470B2 test WIN32THREAD, WIN32THREAD
:BF8470B4 jz short loc_BF8470EC
:BF8470B6 mov ecx, bytes_0x14C
:BF8470BC push edi
:BF8470BD mov edx, ecx
:BF8470BF shr ecx, 2
:BF8470C2 xor eax, eax
:BF8470C4 mov edi, WIN32THREAD
:BF8470C6 rep stosd
:BF8470C8 mov ecx, edx
:BF8470CA and ecx, 3
:BF8470CD push 0
:BF8470CF rep stosb
:BF8470D1 mov eax, [ebp+ETHREAD]
:BF8470D4 push WIN32THREAD
:BF8470D5 push eax
:BF8470D6 mov [WIN32THREAD], eax ; initialize first dword with
:BF8470D6 ; pointer to ETHREAD/KTHREAD
:BF8470D8 call ds:PsSetThreadWin32Thread
:BF8470DE push WIN32THREAD ; WIN32THREAD
:BF8470DF call ObjReferenceObject_ETHREAD
:BF8470E4 xor eax, eax
:BF8470E6 pop edi
:BF8470E7
:BF8470E7 loc_BF8470E7: ; CODE XREF: CreateWin32Thread+5Aj
:BF8470E7 pop WIN32THREAD
:BF8470E8 pop ebp
:BF8470E9 retn 4
:BF8470EC ; ---------------------------------------------------------------------------
:BF8470EC
:BF8470EC loc_BF8470EC: ; CODE XREF: CreateWin32Thread+1Dj
:BF8470EC mov eax, 0C0000017h
:BF8470F1 jmp short loc_BF8470E7
:BF8470F1 CreateWin32Thread endp


So now we have a structure size for what I'm calling WIN32THREAD (sizeof 0x14C). Since it's a tagged pool we should be able to see it with OSR's PoolTag utility, which shows realtime the #Allocs and #Frees for all tagged memory pools in the system. Sure enough, when you start a gui app the #Allocs increase by 1, when you close it the #Frees increase by 1.
The only anomaly here is that the Bytes Used increase/decreases by 0x158 and not 0x14C as expected. Might be a quirk in PoolTag or maybe it knows something I don't, but by all indications in IDA and Softice, the value is 0x14C.

So taking another look at the Win32Thread structure pointer at KTHREAD+0x130 for a random process:

Code:

kd> dd poi(0xffae1b50 + 0x130) L 0x14c/4

e122b008 ffae1b50 00000001 0004e030 ffffffff
e122b018 0012b166 00000000 00030740 00350fa8
e122b028 00000784 0000000d 0000000d 00000000
e122b038 e122b038 00000000 00000000 00000000
e122b048 00000000 00000000 00000000 00000000
e122b058 00000000 00000000 bf892c21 bf88a73f
e122b068 bf88a678 00000000 e122e070 e122e070
e122b078 e1722008 e1722008 e12055d8 e12055d8
e122b088 812c5398 bc6314a0 bc631390 00000000
e122b098 e112ce68 e112ce68 00000001 00000030
e122b0a8 00000004 00000001 10000000 00000000
e122b0b8 00000000 00000000 00000000 00000000
e122b0c8 00000000 00000000 00000000 00000000
e122b0d8 00000000 00000000 00000000 00000000
e122b0e8 00000000 00000000 00000000 00000000
e122b0f8 00000000 00000000 00000000 00000000
e122b108 00000000 00000000 00000000 00000000
e122b118 00000000 00000000 00000000 00000000
e122b128 00000000 00000000 81210688 0000002c
e122b138 000f037f 00000000 00010001 e19fcd48
e122b148 00000000 00000020 e178ba18


We know +00 is the ETHREAD/KTHREAD pointer itself. We can see what looks like 4 sets of LIST_ENTRY structures, 3 of them beginning at offset +0x68.

Note the 3 dwords beginning at +0x58, bf892c21, bf88a73f, bf88a678. These are function pointers which seem to be set into the WIN32THREAD structure during another interesting win32k.sys function which maps the process section:

Code:

:BF8E3551 ; int __stdcall sub_BF8E3551(PVOID BaseAddress,HANDLE SectionHandle)
:BF8E3551 sub_BF8E3551 proc near ; CODE XREF: :BF8465AAp
:BF8E3551
:BF8E3551 ViewSize = dword ptr -4
:BF8E3551 BaseAddress = dword ptr 8
:BF8E3551 SectionHandle = dword ptr 0Ch
...
:BF8E3569 push offset loc_BF88A678
:BF8E356E push offset loc_BF88A73F ; allocates a memory pool tagged "GUma"
:BF8E3573 push offset loc_BF892C21

...
:BF8E3587 call ds:RtlInitializeGenericTableAvl
...
:BF8E35A2 call ds:PsGetProcessPeb
...
:BF8E35E2 call ds:ObOpenObjectByPointer
...
:BF8E35FF push eax ; BaseAddress
:BF8E3600 push 0FFFFFFFFh ; ProcessHandle
:BF8E3602 push [ebp+SectionHandle] ; SectionHandle
:BF8E3605 call ds:ZwMapViewOfSection


A lot of this stuff can be accessed by setting a Softice breakpoint on ntoskrnl!PsConvertToGuiThread which in turn calls win32k!PspW32ProcessCallout and the procs I listed above. Lots of interesting stuph in there, but it's all pretty confusing at first blush, though it's always fun to try to suss out unknown structures

In retrospect, setting a bp on
:BF8470AB call AllocateTaggedPool
then starting a new process and tracing from the break, you can see the structure being filled in, but I'm not 100% sure it matches the process ETHREAD value. The code area is related to creating a new process but in exactly what way I can't define.

Cheers,
Kayaker

ZaiRoN
July 16th, 2007, 07:08
Ok thx, you clear all the doubts I had about that structure. Seems like there are only some equal fields.

blabberer
July 16th, 2007, 11:22
playing a little with userkdx a little i accidently found that _w32threadifno type info is available in xp as well

Code:

lkd> dt win32k!_W32THREAD -v -b e252eeb0
struct _W32THREAD, 10 elements, 0x28 bytes
+0x000 pEThread : 0x80e0db68
+0x004 RefCount : 1
+0x008 ptlW32 : (null)
+0x00c pgdiDcattr : (null)
+0x010 pgdiBrushAttr : (null)
+0x014 pUMPDObjs : (null)
+0x018 pUMPDHeap : (null)
+0x01c dwEngAcquireCount : 0
+0x020 pSemTable : (null)
+0x024 pUMPDObj : (null)

user
August 9th, 2007, 10:51
Quote:
[Originally Posted by omega_red;67187]I'll post details later - just received mail from MS that it's not a security issue (agreed), but they'll have a look at the "product team". Well, unhandled null pointer dereference in kernel mode should be fixed anyway IMO.
A question: What was the basis for this 'not exploitable' verdict? Just because it's a NULL deref doesn't imply it's not exploitable per se, so I assume you/they did some further analysis...

omega_red
November 24th, 2007, 17:06
Posted more details here: https://www.openrce.org/blog/view/966/Null_pointer_dereference_in_win32k.

dELTA
November 24th, 2007, 17:54
Cool, and thanks for letting us know.

aionescu
January 25th, 2008, 10:20
Thanks omega_red... I just found this thread and looked around Win32k.sys a bit last night and found four vulnerabilities, including the one you mentioned --Microsoft was wrong to assume this can only happen before Winlogon loads! (Sorry for being vague -- you know how disclosure works).

I sent reports to my friends over at MSFT, but these bugs are so fun I'd love to give a talk at Blackhat about them as soon as they release patches!

dELTA
January 26th, 2008, 03:46
Cool!
(Maybe I'll see you in Vegas then... )

omega_red
January 29th, 2008, 06:05
Hehe, nice that you've found something interesting Alex. I suspected that this could be more serious, but I've never been much into the software vulnerabilities area. Any code execution stuff in there?

Maximus
January 29th, 2008, 10:00
rofl Win32 must be a gold-mine for bugs. Didnt even have the time to examine it...

Code:

EngDebugPrint(PCH MyPrefix, char *DebugMsg, va_list MyArgList)
{
ULONG nBugCheck;
char MyCool256byteBuffer[256];

nBugCheck = BugCheckParameter2;
DbgPrint(MyPrefix);
vsprintf(MyCool256byteBuffer, DebugMsg, MyArgList);
return DbgPrint(MyCool256byteBuffer);
}


I am curious to know what's happen if my DebugMsg is >256... will my OS bsod in mysterious ways?

being it a DEBUG function, it reinforces my idea that for working at M$ you are thoroughly tested thru an IQ test and taken if...

----edit
ouch, how can i make the code box bigger?!
----edit 2
* Every driver that uses this function i.e. in response to IOControls with string data or such might be used to access R0, of course.
* Every poor driver developer that output a string by this way is exposed to WTF! crashes...
* etc. etc.

Kayaker
February 11th, 2008, 01:10
Quote:
[Originally Posted by blabberer;67222]playing a little with userkdx a little i accidently found that _w32threadifno type info is available in xp as well

Code:

lkd> dt win32k!_W32THREAD -v -b e252eeb0
struct _W32THREAD, 10 elements, 0x28 bytes
+0x000 pEThread : 0x80e0db68
+0x004 RefCount : 1
+0x008 ptlW32 : (null)
+0x00c pgdiDcattr : (null)
+0x010 pgdiBrushAttr : (null)
+0x014 pUMPDObjs : (null)
+0x018 pUMPDHeap : (null)
+0x01c dwEngAcquireCount : 0
+0x020 pSemTable : (null)
+0x024 pUMPDObj : (null)


...and some months later... I found something that seems to confirm this structure definition of ETHREAD.Win32Thread is correct.

I was looking at some of the win32k!Eng*Semaphore functions, which is entirely the fault of Maximus :

http://community.reverse-engineering.net/viewtopic.php?f=10&t=6647

Specifically I was trying to figure out why the offset HSemaphore+0x18 points to an ETHREAD structure in the function EngIsSemaphoreOwnedByCurrentThread.

While looking at EngAcquireSemaphore I saw that it increments W32THREAD.dwEngAcquireCount at 0x1C as posted by blabberer.

Code:

EngAcquireSemaphore(
IN HSEMAPHORE hsem
);

:BF806E7A __stdcall EngAcquireSemaphore(x) proc...
:BF806E7A Resource = dword ptr 8
:BF806E7A
:BF806E7A mov edi, edi
:BF806E7C push ebp
:BF806E7D mov ebp, esp
:BF806E7F mov ecx, [ebp+Resource] ; Resource
:BF806E82 call GreAcquireSemaphore(x)
:BF806E87 call ds:PsGetCurrentThread()
:BF806E8D push eax
:BF806E8E call ds:PsGetThreadWin32Thread(x) // returns ETHREAD.Win32Thread
:BF806E94 test eax, eax
:BF806E96 jz short loc_BF806E9B
:BF806E98 inc dword ptr [eax+1Ch] / W32THREAD.dwEngAcquireCount
:BF806E9B
:BF806E9B loc_BF806E9B: ; CODE XREF: EngAcquireSemaphore(x)+1C
:BF806E9B pop ebp
:BF806E9C retn 4
:BF806E9C __stdcall EngAcquireSemaphore(x) endp


Unfortunately those Eng* functions can only be used from display drivers and not kernel mode drivers, so it's a little tricky to suss 'em out.

Kayaker

blabberer
February 12th, 2008, 11:50
Quote:

Unfortunately those Eng* functions can only be used from display drivers and not kernel mode drivers, so it's a little tricky to suss 'em out.


if some fortunate or unfortunate soul tries to suss em out here is a little hack
to get all those sussed out information back to original win32k.sys 's PDB

so that windbg or livekd recognises them without any problems

1) you would need ddk or wdk or whatever rtm it is called nowadays
for the cl.exe and build environment

2) you would need a c file that contains the definitions like blah.c

you would need the following command to put your blah.c information into
microsofts pdb file

here is the command line

Code:

C:\win32kpdb>cl.exe /Zi /Gz /c /Fdwin32k.pdb /ID:\WINDDK\3790~1.183\inc\wxp /ID:
\WINDDK\3790~1.183\inc /ID:\WINDDK\3790~1.183\inc\crt /ID:\WINDDK\3790~1.183\inc
\ddk\wxp /ID:\WINDDK\3790~1.183\inc\hal\wxp /ID:\WINDDK\3790~1.183\inc\ifs\wxp /
ID:\WINDDK\3790~1.183\inc\mfc42 /ID:\WINDDK\3790~1.183\inc\wxp /ID:\WINDDK\3790~
1.183\inc\processor /ID:\WINDDK\3790~1.183\inc\ddk\wdm\wxp /D_X86_=1 tagthread.c



i used specific include paths specific to my setup of ddk your mileage may vary you would need to define _x86_ macro
tag thread.c is the file that contains the information that i added to win32k.sys file

whose contents at that time of experiment was

Code:

#include <ntddk.h>

typedef void *POINTER;

typedef POINTER PDESKTOPINFO;
typedef POINTER PPROCESSINFO;
typedef POINTER PTL;
typedef POINTER PQ;
typedef POINTER PKL;
typedef POINTER PCLIENTTHREADINFO;
typedef POINTER PDESKTOP;
typedef POINTER PCLIENTINFO;
typedef POINTER PSMS;
typedef POINTER PMENUSTATE;
typedef POINTER PTDB;
typedef POINTER PWINDOWSTATION;
typedef POINTER PSVR_INSTANCE_INFO;
typedef POINTER PMOVESIZEDATA;
typedef POINTER PSBTRACK;
typedef POINTER PWND;
typedef POINTER PIMC;
typedef POINTER PQMSG;
typedef POINTER PCLS;
typedef POINTER PWOWPROCESSINFO;
typedef POINTER PDESKTOPVIEW;
typedef POINTER PCURSOR;
typedef POINTER PW32JOB;
typedef POINTER KERNEL_ULONG_PTR;

typedef PTHREADINFO;
typedef PHOOK;

typedef struct tagCLIENTTHREADINFO {
UINT CTIF_flags;
WORD fsChangeBits; // Bits changes since last compared
WORD fsWakeBits; // Bits currently available
WORD fsWakeBitsJournal; // Bits saved while journalling
WORD fsWakeMask; // Bits looking for when asleep
LONG timeLastRead; // Time of last input read
} CLIENTTHREADINFO;


typedef struct tagPROCESSINFO { //W32PROCESS;
//***************************************** begin: USER specific fields
PTHREADINFO ptiList; // threads in this process
PTHREADINFO ptiMainThread; // pti of "main thread"
PDESKTOP rpdeskStartup; // initial desktop
PCLS pclsPrivateList; // this processes' private classes
PCLS pclsPublicList; // this processes' public classes
PWOWPROCESSINFO pwpi; // Wow PerProcess Info

PPROCESSINFO ppiNext; // next ppi structure in start list
PPROCESSINFO ppiNextRunning;
int cThreads; // count of threads using this process info
HDESK hdeskStartup; // initial desktop handle
UINT cSysExpunge; // sys expunge counter
DWORD dwhmodLibLoadedMask; // bits describing loaded hook dlls
HANDLE ahmodLibLoaded[CLIBS]; // process unique hmod array for hook dlls
PWINDOWSTATION prpwinsta; // process windowstation
HWINSTA hwinsta; // windowstation handle
ACCESS_MASK amwinsta; // windowstation accesses

DWORD dwHotkey; // hot key from progman
HMONITOR hMonitor; // monitor handle from CreateProcess
PDESKTOPVIEW pdvList; // list of desktop views
UINT iClipSerialNumber; // clipboard serial number
RTL_BITMAP bmHandleFlags; // per handle flags
PCURSOR pCursorCache; // process cursor/icon cache
PVOID pClientBase; // LEAVE THIS FOR HYDRA; offset to the shared section
DWORD dwLpkEntryPoints; // user mode language pack installed

PW32JOB pW32Job; // pointer to the W32JOB structure

DWORD dwImeCompatFlags; // per-process Ime Compatibility flags
LUID luidSession; // logon session id
USERSTARTUPINFO usi; // process startup info

#ifdef VALIDATEHANDLEQUOTA
LONG lHandles;
#endif

#ifdef USE_MIRRORING
DWORD dwLayout; // the default Window orientation for this process
#endif

} PROCESSINFO;

typedef struct _HEAD {
DWORD h; //HHOOK
DWORD cLockObj;
} HEAD, *PHEAD;

typedef struct _THROBJHEAD {
HEAD hdr;
DWORD pti;
} THROBJHEAD, *PTHROBJHEAD;

typedef struct _DESKHEAD {
DWORD rpdesk;
DWORD pSelf;
} DESKHEAD, *PDESKHEAD;

typedef struct _THRDESKHEAD {
THROBJHEAD tohdr;
DESKHEAD dhdr;
} THRDESKHEAD, *PTHRDESKHEAD;


typedef struct tagHOOK { /* hk */
THRDESKHEAD head;
PHOOK phkNext;
int iHook; // WH_xxx hook type
KERNEL_ULONG_PTR offPfn;
UINT flags; // HF_xxx flags
int ihmod;
PTHREADINFO ptiHooked; // Thread hooked.
PDESKTOP rpdesk; // Global hook pdesk. Only used when
// hook is locked and owner is destroyed
#ifdef HOOKBATCH
DWORD cEventMessages; // Number of events in the cache
DWORD iCurrentEvent; // Current cache event
DWORD CacheTimeOut; // Timeout between keys
PEVENTMSG aEventCache; // The array of Events
#endif // HOOKBATCH
} HOOK;




typedef struct _THREADINFO {
ULONG a[10]; // W32THREAD
PTL ptl; // Listhead for thread lock list +28
PPROCESSINFO ppi; // process info struct for this thread +2C
PQ pq; // keyboard and mouse input queue +30
PKL spklActive; // active keyboard layout for this thread +34
PCLIENTTHREADINFO pcti; // Info that must be visible from client +38
PDESKTOP rpdesk;
PDESKTOPINFO pDeskInfo; // Desktop info visible to client +40
PCLIENTINFO pClientInfo; // Client info stored in TEB +44
ULONG TIF_flags; // TIF_ flags go here. +48
PUNICODE_STRING pstrAppName; // Application module name. +4C
PSMS psmsSent; // Most recent SMS this thread has sent
PSMS psmsCurrent; // Received SMS this thread is currently processing
PSMS psmsReceiveList;// SMSs to be processed
LONG timeLast; // Time, position, and ID of last message
ULONG_PTR idLast;
int cQuit;
int exitCode;
HANDLE hdesk; // Desktop handle. Changed from "HDESK hdesk"
int cPaintsReady;
unsigned int cTimersReady;
PMENUSTATE pMenuState;
union {
PTDB ptdb; // Win16Task Schedule data for WOW thread
PWINDOWSTATION pwinsta; // Window station for SYSTEM thread
};
PSVR_INSTANCE_INFO psiiList; // thread DDEML instance list
ULONG dwExpWinVer;
ULONG dwCompatFlags; // The Win 3.1 Compat flags
ULONG dwCompatFlags2; // new DWORD to extend compat flags for NT5+ features
PQ pqAttach; // calculation variabled used in zzzAttachThreadInput()
void* ptiSibling; // Pointer to sibling thread info. Chnaged from "PTHREADINFO ptiSibling"
PMOVESIZEDATA pmsd;
ULONG fsHooks; // WHF_ Flags for which hooks are installed
PHOOK sphkCurrent; // Hook this thread is currently processing
PSBTRACK pSBTrack;
HANDLE hEventQueueClient;
PKEVENT pEventQueueServer;
LIST_ENTRY PtiLink; // Link to other threads on desktop
int iCursorLevel; // keep track of each thread's level
ULONG b[2]; //POINT ptLast;
PWND spwndDefaultIme;// Default IME Window for this thread
PIMC spDefaultImc; // Default input context for this thread
HANDLE hklPrev; // Previous active. Changed from "HKL hklPrev"
int cEnterCount;
MLIST mlPost; // posted message list.
USHORT fsChangeBitsRemoved;// Bits removed during PeekMessage
WCHAR wchInjected; // character from last VK_PACKET
ULONG fsReserveKeys; // Keys that must be sent to the active +E0
PKEVENT *apEvent; // Wait array for xxxPollAndWaitForSingleObject +E4
ACCESS_MASK amdesk; // Granted access +E8
unsigned int cWindows; // Number of windows owned by this thread +EC
unsigned int cVisWindows; // Number of visible windows on this thread +F0
PHOOK aphkStart[CWINHOOKS]; // Hooks registered for this thread, local hook +F4
CLIENTTHREADINFO cti; // Use this when no desktop is available +F8
} THREADINFO, *PTHREADINFO;

THREADINFO thinf;


this is how you do it
Code:


copy the win32k.pdb from symbol cache into a folder
copy this tagthread.c (this is crap i have changed many HWINSTA etc
symbols to ULONG to fool errors and test

and go to the build environment and pass the commandline

copy back the new win32k.pbd to symbol cache (remember save original
before replacing)

go to kd and do dt _win32k!_Threadinfo <some address> here

it should show some real information in formatted style

like below if you are successfull


result as follows

Code:




lkd> !ready
Processor 0: Ready Threads at priority 8
THREAD ff5e3020 Cid 0350.0b64 Teb: 7ffad000 Win32Thread: e123adc0 READY
THREAD 810c0020 Cid 0314.07b0 Teb: 7ff8d000 Win32Thread: 00000000 WAIT
THREAD ffbad020 Cid 0314.0330 Teb: 7ffdb000 Win32Thread: e2107a50 WAIT
THREAD ff98bcb0 Cid 0350.0c24 Teb: 7ffde000 Win32Thread: e245c400 WAIT
THREAD ff5e3020 Cid 0350.0b64 Teb: 7ffad000 Win32Thread: e123adc0 READY
lkd> dt win32k!_Threadinfo e123adc0
win32k!_THREADINFO
+0x000 a : [10] 0xff5e3020 <--- this is w32thread
but i just took zairon post definition as it is to test
+0x028 ptl : (null)
+0x02c ppi : 0xe24db0c0
+0x030 pq : 0xe1080c18
+0x034 spklActive : 0xe20bcf08
+0x038 pcti : 0xbc662b18
+0x03c rpdesk : 0x810f0e10
+0x040 pDeskInfo : 0xbc630650
+0x044 pClientInfo : 0x7ffad6cc
+0x048 TIF_flags : 0x1000000
+0x04c pstrAppName : (null)
+0x050 psmsSent : (null)
+0x054 psmsCurrent : (null)
+0x058 psmsReceiveList : (null)
+0x05c timeLast : 0
+0x060 idLast : 0
+0x064 cQuit : 0
+0x068 exitCode : 40
+0x06c hdesk : (null)
+0x070 cPaintsReady : 0
+0x074 cTimersReady : 0
+0x078 pMenuState : (null)
+0x07c ptdb : (null)
+0x07c pwinsta : (null)
+0x080 psiiList : 0x00000400
+0x084 dwExpWinVer : 0
+0x088 dwCompatFlags : 0x10000
+0x08c dwCompatFlags2 : 0
+0x090 pqAttach : 0xe153e8f8
+0x094 ptiSibling : (null)
+0x098 pmsd : (null)
+0x09c fsHooks : 0
+0x0a0 sphkCurrent : 0
+0x0a4 pSBTrack : 0x00000704
+0x0a8 hEventQueueClient : 0xff9c3f40
+0x0ac pEventQueueServer : 0xe153e9a4 _KEVENT
+0x0b0 PtiLink : _LIST_ENTRY [ 0xe1036e5c - 0x0 ]
+0x0b8 iCursorLevel : 0
+0x0bc b : [2] 0
+0x0c4 spwndDefaultIme : (null)
+0x0c8 spDefaultImc : (null)
+0x0cc hklPrev : (null)
+0x0d0 cEnterCount : 0
+0x0d4 mlPost : 0
+0x0d8 fsChangeBitsRemoved : 0
+0x0da wchInjected : 0
+0x0dc fsReserveKeys : 0
+0x0e0 apEvent : (null)
+0x0e4 amdesk : 0
+0x0e8 cWindows : 0xf01ff
+0x0ec cVisWindows : 0
+0x0f0 aphkStart : [20] 0
+0x140 cti : 0
lkd>

have fun


Kayaker
February 12th, 2008, 21:13
Thanks blabberer. I remember you showing me this a while back, I think in reference to this thread actually, and I can vouch that it works great. Might be a nice way to attach some of Alex Ionescu's NDK undocumented headers to Windbg output capabilities.

aionescu
February 17th, 2008, 17:45
Problem is that the structure is out-of-date...see 'PtiLink'.

I've been using a similar trick of my own, but actually just load my module with a separate name, then I can do dt mymodule!_TYPE <ptr>.

You can use .reload with a PDB and a valid kmode address and it usually works.

aionescu
February 17th, 2008, 17:47
Not sure where you got that, but in IDA I see:

vsprintf_s

Which is the "safe" version, and the length is set to 256.

Quote:
[Originally Posted by Maximus;72351]rofl Win32 must be a gold-mine for bugs. Didnt even have the time to examine it...

Code:

EngDebugPrint(PCH MyPrefix, char *DebugMsg, va_list MyArgList)
{
ULONG nBugCheck;
char MyCool256byteBuffer[256];

nBugCheck = BugCheckParameter2;
DbgPrint(MyPrefix);
vsprintf(MyCool256byteBuffer, DebugMsg, MyArgList);
return DbgPrint(MyCool256byteBuffer);
}


I am curious to know what's happen if my DebugMsg is >256... will my OS bsod in mysterious ways?

being it a DEBUG function, it reinforces my idea that for working at M$ you are thoroughly tested thru an IQ test and taken if...

----edit
ouch, how can i make the code box bigger?!
----edit 2
* Every driver that uses this function i.e. in response to IOControls with string data or such might be used to access R0, of course.
* Every poor driver developer that output a string by this way is exposed to WTF! crashes...
* etc. etc.

Maximus
February 18th, 2008, 08:37
!!
thanks, but this leaves me with a big problem now... what's happened to the win2k.sys of THIS machine!? The code I see is different, and WinUpdate is ON (even if in manual mode).
mmh...
edit------------
mmh... only some minor, optional update is missing... oook. I'll check on other windows machines...

Maximus
February 22nd, 2008, 16:22
Quote:

vsprintf_s

Which is the "safe" version, and the length is set to 256.


out of curiosity, i checked today other windows versions. I do not see it nor in others XP (updated&original), not in 2k3server.
the call is made by 3 parameters, not 4 as vsprintf_s requires. Also, i do not see the '256' anywhere.

What strange version of Windows XP are you using? Is there a version of WinXP which uses vsprintf_s and my xppro uses it not?

aaah i see now what you are looking. Well, please ask to your MS friends if they can fix this in other OSes too -especially XP
I dont like much Vista...

aionescu
March 16th, 2008, 17:09
Can you confirm that on SRV03SP1 this function still uses strcpy with no extra validation? That's pretty disgusting. The bug isn't there on Vista.

habituallurker
March 18th, 2008, 12:45
XP SP2 5.1.2600.3099: The bug exists, but is mitigated by GS cookies:

Code:
.text:BF9332A4 ; int __stdcall EngDebugPrint(PCH Format,int,int)
.text:BF9332A4 public _EngDebugPrint@12
.text:BF9332A4 _EngDebugPrint@12 proc near
.text:BF9332A4
.text:BF9332A4 var_104= byte ptr -104h
.text:BF9332A4 var_4= dword ptr -4
.text:BF9332A4 Format= dword ptr 8
.text:BF9332A4 arg_4= dword ptr 0Ch
.text:BF9332A4 arg_8= dword ptr 10h
.text:BF9332A4
.text:BF9332A4 mov edi, edi
.text:BF9332A6 push ebp
.text:BF9332A7 mov ebp, esp
.text:BF9332A9 sub esp, 104h
.text:BF9332AF mov eax, gscookie
.text:BF9332B4 push esi
.text:BF9332B5 mov esi, [ebp+arg_4]
.text:BF9332B8 mov [ebp+var_4], eax
.text:BF9332BB mov eax, [ebp+Format]
.text:BF9332BE push edi
.text:BF9332BF mov edi, [ebp+arg_8]
.text:BF9332C2 push eax ; Format
.text:BF9332C3 call _DbgPrint
.text:BF9332C8 push edi ; va_list
.text:BF9332C9 lea eax, [ebp+var_104]
.text:BF9332CF push esi ; char *
.text:BF9332D0 push eax ; char *
.text:BF9332D1 call _vsprintf
.text:BF9332D6 lea eax, [ebp+var_104]
.text:BF9332DC push eax ; Format
.text:BF9332DD call _DbgPrint
.text:BF9332E2 mov ecx, [ebp+var_4]
.text:BF9332E5 add esp, 14h
.text:BF9332E8 pop edi
.text:BF9332E9 pop esi
.text:BF9332EA call @__security_check_cookie@4 ; __security_check_cookie(x)
.text:BF9332EF leave
.text:BF9332F0 retn 0Ch
.text:BF9332F0 _EngDebugPrint@12 endp

Maximus
March 18th, 2008, 14:31
Actually, all the functions i did check when roamed w2k have the error not fixed in XP, but in vista (i.e. the debug function).

By the way... why the hell the Win2k of Vista is compiled with a LOCAL rtl included in it, instead of accessing the ntos one!?!?!?!? It's just a waste of PC memory with no real advantages (no higher speed etc.).
Mah, i start to understand why Vista is SO demanding in resources... if all files are compiled this way....


mmh... I'd like give another look at win2k for curiosity [damn, i found there of good only one XP/Vista string overflow from userland, nice but not yet what I wanted], but work is calling in this period

tx for having such bugs fixed in XPsp3 if possible ...I dream to be able to migrate to linux and not vista, in future ...but i dont bet much for it

aionescu
May 10th, 2008, 18:53
Looks like the bug probably got fixed in Windows Server 2003 SP1 and later, but not downstream.

Exploiting this bug would also require you to bypass the stack cookie, which may not be trivial in this context. Also, pretty much the only way you can attack the system is to have a video driver that calls EngDbgPrint (pretty unlikely) with a string that you can control (very unlikely) and that can include any possible character (even more unlikely).

Finally, the rtl you're thinking isn't the same RTL as in ntos/ntdll. Win32k has always had its own "rtl" library to deal with things such as LARGE_UNICODE_STRING and other Win32k-internal types.

Quote:
[Originally Posted by Maximus;73451]Actually, all the functions i did check when roamed w2k have the error not fixed in XP, but in vista (i.e. the debug function).

By the way... why the hell the Win2k of Vista is compiled with a LOCAL rtl included in it, instead of accessing the ntos one!?!?!?!? It's just a waste of PC memory with no real advantages (no higher speed etc.).
Mah, i start to understand why Vista is SO demanding in resources... if all files are compiled this way....


mmh... I'd like give another look at win2k for curiosity [damn, i found there of good only one XP/Vista string overflow from userland, nice but not yet what I wanted], but work is calling in this period

tx for having such bugs fixed in XPsp3 if possible ...I dream to be able to migrate to linux and not vista, in future ...but i dont bet much for it

aionescu
May 10th, 2008, 19:05
omega_red: Looks like I'll be making it at Blackhat after all. Thanks again for making me look down some common paths as the issue you've brought up. Don't worry, the talk won't be about your bug per se, since that's your own work. But I'll definitely mention you when I bring up your bug as an example!

Maximus
May 11th, 2008, 08:30
Yep, these bugs are fixed in Vista, so probably elsewhere. But not in Xp, unfortunately.

I've not said it is simple to exploit them, i just pointed that just opening w2k shown up quite a number of exploitable weaknesses, just in a bunch hours of free-time, hobby analysis. Which is surely not very encouraging, if we are talking about the overall security of it, no?

About w2k and rtl... no. w2k in xp does use ntos for supporting wide chars, many RTL operations, memmoves etc. unless it does cross-ref ntos export calls in whole w2k code for joke and fun...
This is not true for Vista, which uses its own embedded RTL code to do the same things (comparing the codes, it seems that the vista build just embedded the RTL at compile time using a compiler option, since code is 'almost' identical, bug included).

But it is irritating to open a critical OS file and find such weaknesses with virtually no analysis spent over it. Because such bugs (like the vsprintf one) are huge, easily spottable and ...and we are in 2k8.

aionescu
December 13th, 2009, 11:12
1) Four disclosures and a BlackHat talk later, Microsoft in their infinite wisdom decided not to fix one of the bugs I talked about (related to the Winlogon issue dELTA found), and even make it worse by adding two more functions that exhibit the same bugs (these ones leading to privilege escalation, not just Dos!) So if you attended/read my paper on "pointer assumptions" on the CSRSS/desktop issue, well the bug is still there (and in multiple system calls)
2) In Win7, the Win32k.PDB now contains all the user types, like tagTHREADINFO & friends. I don't know if it's an oversight, but it's making analysis much easier

Just wanted to update this thread

dELTA
December 13th, 2009, 20:32
Hey Alex, nice to have you passing by, and thanks for the update.

For the sake of truth and honesty though, it was omega_red that found the bug, not me.

I was just the annoying guy who chatted you up after the above mentioned Black Hat talk.

aionescu
December 13th, 2009, 22:05
Errr crud, sorry omega_red, no disrespect intended!

Thanks dELTA

So maybe anyone has some suggestions? This latest bug has two possibilities:

1) A race condition in which you can increment any value of your choice (the race can be made to work 100% of the time). After the race, the value is restored back.
2) A condition in which you can OR the value 2 to any value of your choice.

Just curious what some of you would do to "weaponize" this?

For both of these, I went back to my 2003 subversion whitepaper, in which I re-enabled access to \Device\PhysicalMemory by patching the kernel.

The check basically does this:

if (AccessMode == UserMode) && (Object->Flags & PROTECTED) fail;

The assembler is really: if (AccessMode == KernelMode) break; if (ObjectFlags & PROTECTED) break; fail;

For #1, I simply patch KernelMode to UserMode (0 + 1 = 1) during the race, and then I can get my handle.

For #2, I patch KernelMode to IllegalMode (0 + 2 = 2) and then patch the je in the if with jbe (je + 2 is jbe). Thus the code becomes (if AccessMode <= 2) break;, which means the protected check is not done anymore.

The problem is this requires a Vista system with > 255MB memory (easy) or a Win 7 system with > 2GB (harder) since Large Pages are not enabled otherwise, meaning the kernel will be R/O.

On 64-bit, PatchGuard becomes an issue.

So just out of curiosity, what are some things you'd think of doing with a 1-byte increment (which is volatile/temporary) or a 2-byte OR (which is permanent, but it's an OR) to elevate from user to kernel, that don't involve code patching.

omega_red
December 16th, 2009, 05:04
Quote:
[Originally Posted by aionescu;84020]Errr crud, sorry omega_red, no disrespect intended!


No problem, I'm glad that you actually took your time to investigate this!