news 2026/1/15 17:39:11

从ProcessMouseInput函数中的win32k!QueueMouseEvent到ProcessQueuedMouseEvents函数中的win32k!UnqueueMouseEvent重要

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从ProcessMouseInput函数中的win32k!QueueMouseEvent到ProcessQueuedMouseEvents函数中的win32k!UnqueueMouseEvent重要

从ProcessMouseInput函数中的win32k!QueueMouseEvent到ProcessQueuedMouseEvents函数中的win32k!UnqueueMouseEvent重要


VOID ProcessMouseInput(
PDEVICEINFO pMouseInfo)
{


pmei = pMouseInfo->mouse.Data;
while (pmei != NULL) {

。。。

/*
* Queue mouse event for the other thread to pick up when it finishes
* with the USER critical section.
* If pmeiNext == NULL, there is no more mouse input yet, so wake RIT.
*/
QueueMouseEvent(
pmei->ButtonFlags,
pmei->ButtonData,
pmei->ExtraInformation,
gptCursorAsync,
time,
#ifdef GENERIC_INPUT
PtoH(pMouseInfo),
pmei,
#endif
FALSE,
(pmeiNext == NULL));

NextMouseInputRecord:
pmei = pmeiNext;
}
}


VOID QueueMouseEvent(
USHORT ButtonFlags,
USHORT ButtonData,
ULONG_PTR ExtraInfo,
POINT ptMouse,
LONG time,
#ifdef GENERIC_INPUT
HANDLE hDevice,
PMOUSE_INPUT_DATA pmei,
#endif
BOOL bInjected,
BOOL bWakeRIT
)
{
CheckCritOut();

EnterMouseCrit();

LOGTIME(gMouseQueueMouseEventTime);

/*
* Button data must always be accompanied by a flag to interpret it.
*/
UserAssert(ButtonData == 0 || ButtonFlags != 0);

/*
* We can coalesce this mouse event with the previous event if there is a
* previous event, and if the previous event and this event involve no
* key transitions.
*/
if ((gdwMouseEvents == 0) ||
(ButtonFlags != 0) ||
(gMouseEventQueue[gdwMouseQueueHead].ButtonFlags != 0)) {
/*
* Can't coalesce: must add a new mouse event
*/
if (gdwMouseEvents >= NELEM_BUTTONQUEUE) {
/*
* But no more room!
*/
LeaveMouseCrit();
UserBeep(440, 125);
return;
}

gdwMouseQueueHead = (gdwMouseQueueHead + 1) % NELEM_BUTTONQUEUE;
gMouseEventQueue[gdwMouseQueueHead].ButtonFlags = ButtonFlags;
gMouseEventQueue[gdwMouseQueueHead].ButtonData = ButtonData;
gdwMouseEvents++;
}

gMouseEventQueue[gdwMouseQueueHead].ExtraInfo = ExtraInfo;
gMouseEventQueue[gdwMouseQueueHead].ptPointer = ptMouse;
gMouseEventQueue[gdwMouseQueueHead].time = time;
gMouseEventQueue[gdwMouseQueueHead].bInjected = bInjected;
#ifdef GENERIC_INPUT
gMouseEventQueue[gdwMouseQueueHead].hDevice = hDevice;
if (pmei) {
gMouseEventQueue[gdwMouseQueueHead].rawData = *pmei;
} else {
/*
* To indicate the rawData is invalid, set INVALID_UNIT_ID.
*/
gMouseEventQueue[gdwMouseQueueHead].rawData.UnitId = INVALID_UNIT_ID;
}
#endif

LeaveMouseCrit();

if (bWakeRIT) {
/*
* Signal RIT to complete the mouse input processing
*/
KeSetEvent(gpkeMouseData, EVENT_INCREMENT, FALSE);
}
}


1: kd> x win32k!gdwMouseQueueHead
bfa71028 win32k!gdwMouseQueueHead = 7
#define NELEM_BUTTONQUEUE 16

1: kd> x win32k!gMouseEventQueue
bfa71040 win32k!gMouseEventQueue = struct tagMOUSEEVENT []
bfa71040 win32k!gMouseEventQueue = struct tagMOUSEEVENT [16]
1: kd> dx -id 0,0,89831250 -r1 (*((win32k!tagMOUSEEVENT (*)[16])0xbfa71040))
(*((win32k!tagMOUSEEVENT (*)[16])0xbfa71040)) [Type: tagMOUSEEVENT [16]]
[0] [Type: tagMOUSEEVENT]
[1] [Type: tagMOUSEEVENT]
[2] [Type: tagMOUSEEVENT]
[3] [Type: tagMOUSEEVENT]
[4] [Type: tagMOUSEEVENT]
[5] [Type: tagMOUSEEVENT]
[6] [Type: tagMOUSEEVENT]
[7] [Type: tagMOUSEEVENT]

1: kd> dx -id 0,0,89831250 -r1 (*((win32k!tagMOUSEEVENT *)0xbfa711ac))
(*((win32k!tagMOUSEEVENT *)0xbfa711ac)) [Type: tagMOUSEEVENT]
[+0x000] ButtonFlags : 0x0 [Type: unsigned short]
[+0x002] ButtonData : 0x0 [Type: unsigned short]
[+0x004] ExtraInfo : 0x0 [Type: unsigned long]
[+0x008] ptPointer : {x=638 y=431} [Type: tagPOINT]
[+0x010] time : -3486703 [Type: long]
[+0x014] bInjected : 0 [Type: int]
[+0x018] hDevice : 0x10049 [Type: void *]
[+0x01c] rawData [Type: _MOUSE_INPUT_DATA]


1: kd> x win32k!gpkeMouseData
bfa71404 win32k!gpkeMouseData = 0x898ccba8


1: kd> x win32k!apobjects
bfa6ed8c win32k!apObjects = 0x89489d08
1: kd> dd 0x89489d08
89489d08 8957a860 898ccba8 8978eec8 8957cd48
89489d18 80bf4220 8957ccf8 8978ee88 00000000

#define ID_INPUT 0
#define ID_MOUSE 1

#define ID_TIMER 2
#define ID_HIDCHANGE 3
#define ID_SHUTDOWN 4


VOID ProcessQueuedMouseEvents(
VOID)
{
MOUSEEVENT MouseEvent;
static POINT ptCursorLast = {0,0};

while (UnqueueMouseEvent(&MouseEvent)) {


BOOL UnqueueMouseEvent(
PMOUSEEVENT pme
)
{
DWORD dwTail;

EnterMouseCrit();

LOGTIME(gMouseUnqueueMouseEventTime);

if (gdwMouseEvents == 0) {
LeaveMouseCrit();
return FALSE;
} else {
dwTail = (gdwMouseQueueHead - gdwMouseEvents + 1) % NELEM_BUTTONQUEUE;
*pme = gMouseEventQueue[dwTail];
gdwMouseEvents--;
}

LeaveMouseCrit();
return TRUE;
}

1: kd> g
Breakpoint 15 hit
eax=f75d6a8c ebx=00000000 ecx=00000000 edx=00000000 esi=bfa01624 edi=bfa03214
eip=bf873b5a esp=f75d6a84 ebp=f75d6ac0 iopl=0 nv up ei ng nz ac po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000292
win32k!UnqueueMouseEvent:
bf873b5a 55 push ebp
1: kd> kc
#
00 win32k!UnqueueMouseEvent
01 win32k!ProcessQueuedMouseEvents
02 win32k!RawInputThread
03 win32k!xxxCreateSystemThreads
04 win32k!NtUserCallOneParam
05 nt!_KiSystemService
06 SharedUserData!SystemCallStub
07 winsrv!NtUserCallOneParam
1: kd> kv
# ChildEBP RetAddr Args to Child
00 f75d6a80 bf8e8ab6 f75d6a8c 00000000 898a5528 win32k!UnqueueMouseEvent (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\windows\core\ntuser\kernel\ntinput.c @ 1921]
01 f75d6ac0 bf891cd3 bf9dd6a0 bf9dab54 00000088 win32k!ProcessQueuedMouseEvents+0xf (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\windows\core\ntuser\kernel\ntinput.c @ 5869]
02 f75d6d1c bf8b21b0 00000001 00000002 f75d6d48 win32k!RawInputThread+0x828 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\windows\core\ntuser\kernel\ntinput.c @ 6391]
03 f75d6d2c bf806d52 f75c64a0 f75d6d58 0088fff4 win32k!xxxCreateSystemThreads+0x92 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\windows\core\ntuser\kernel\desktop.c @ 338]
04 f75d6d48 80afbcb2 00000000 00000022 80afb956 win32k!NtUserCallOneParam+0xa0 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\windows\core\ntuser\kernel\ntstubs.c @ 4789]
05 f75d6d48 7ffe0304 00000000 00000022 80afb956 nt!_KiSystemService+0x13f (FPO: [0,3] TrapFrame @ f75d6d64) (CONV: cdecl) [d:\srv03rtm\base\ntos\ke\i386\trap.asm @ 1328]
06 0088ffe0 75340774 75318a89 00000000 00000022 SharedUserData!SystemCallStub+0x4 (FPO: [0,0,0])
07 0088ffe8 00000000 00000022 00000004 00000000 winsrv!NtUserCallOneParam+0xc (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\windows\core\umode\daytona\obj\i386\usrstubs.c @ 2683]
1: kd> dv
pme = 0xf75d6a8c


VOID RawInputThread(
PRIT_INIT pInitData)
{


if (Status == ID_MOUSE) {
/*
* A desktop thread got some Mouse input for us. Process it.
*/
ProcessQueuedMouseEvents();

}

1: kd> x win32k!apobjects
bfa6ed8c win32k!apObjects = 0x89489d08
1: kd> dd 0x89489d08
89489d08 8957a860 898ccba8 8978eec8 8957cd48
89489d18 80bf4220 8957ccf8 8978ee88 00000000
89489d28 0a060007 20646156 89756180 89811e28
89489d38 897906c0 000008d0 00000926 01400000
89489d48 89562508 e14c5008 e14c5160 81000000
89489d58 00040006 6966744e 894f3889 8975b0a1
89489d68 8975bc90 0000020a 0000011c 00000100
89489d78 0a220004 6966744e 0108070a 00000000
1: kd> dt kevent 898ccba8
CSRSRV!KEVENT
+0x000 Header : _DISPATCHER_HEADER
1: kd> dx -id 0,0,89831250 -r1 (*((CSRSRV!_DISPATCHER_HEADER *)0x898ccba8))
(*((CSRSRV!_DISPATCHER_HEADER *)0x898ccba8)) [Type: _DISPATCHER_HEADER]
[+0x000] Type : 0x1 [Type: unsigned char]
[+0x001] Absolute : 0x0 [Type: unsigned char]
[+0x002] Size : 0x4 [Type: unsigned char]
[+0x003] Inserted : 0x0 [Type: unsigned char]
[+0x003] DebugActive : 0x0 [Type: unsigned char]
[+0x000] Lock : 262145 [Type: long]
[+0x004] SignalState : 0 [Type: long]
[+0x008] WaitListHead [Type: _LIST_ENTRY]
1: kd> dx -id 0,0,89831250 -r1 (*((CSRSRV!_LIST_ENTRY *)0x898ccbb0))
(*((CSRSRV!_LIST_ENTRY *)0x898ccbb0)) [Type: _LIST_ENTRY]
[+0x000] Flink : 0x898ccbb0 [Type: _LIST_ENTRY *]
[+0x004] Blink : 0x898ccbb0 [Type: _LIST_ENTRY *]

注意:


LONG
KeSetEvent (
IN PRKEVENT Event,
IN KPRIORITY Increment,
IN BOOLEAN Wait
)
{
OldState = Event->Header.SignalState;
Event->Header.SignalState = 1;

} else {
KiWaitTestSynchronizationObject(Event, Increment);
}


KiWaitTestSynchronizationObject (
IN PVOID Object,
IN KPRIORITY Increment
)
{
if (WaitBlock->WaitType == WaitAny) {
Event->Header.SignalState = 0;
KiUnwaitThread(Thread, (NTSTATUS)WaitBlock->WaitKey, Increment);
break;
}


注意:所以现在的信号状态= 0;

1: kd> kv 3
# ChildEBP RetAddr Args to Child
00 f75d6a80 bf8e8ab6 f75d6a8c 00000000 898a5528 win32k!UnqueueMouseEvent (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\windows\core\ntuser\kernel\ntinput.c @ 1921]
01 f75d6ac0 bf891cd3 bf9dd6a0 bf9dab54 00000088 win32k!ProcessQueuedMouseEvents+0xf (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\windows\core\ntuser\kernel\ntinput.c @ 5869]
02 f75d6d1c bf8b21b0 00000001 00000002 f75d6d48 win32k!RawInputThread+0x828 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\windows\core\ntuser\kernel\ntinput.c @ 6391]
windbg> .open -a ffffffffbf873b5a
1: kd> x win32k!gdwMouseEvents
bfa71024 win32k!gdwMouseEvents = 1


1: kd> x win32k!gdwMouseQueueHead
bfa71028 win32k!gdwMouseQueueHead = 7


MOUSEEVENT |<----win32k!gdwMouseQueueHead
MOUSEEVENT |
MOUSEEVENT |
MOUSEEVENT |<----win32k!gdwMouseEvents
MOUSEEVENT |
MOUSEEVENT |
MOUSEEVENT |<----dwTail


1: kd> x win32k!gMouseEventQueue
bfa71040 win32k!gMouseEventQueue = struct tagMOUSEEVENT []
bfa71040 win32k!gMouseEventQueue = struct tagMOUSEEVENT [16]
1: kd> dx -id 0,0,89831250 -r1 (*((win32k!tagMOUSEEVENT (*)[16])0xbfa71040))
(*((win32k!tagMOUSEEVENT (*)[16])0xbfa71040)) [Type: tagMOUSEEVENT [16]]

[7] [Type: tagMOUSEEVENT]

1: kd> dx -id 0,0,89831250 -r1 (*((win32k!tagMOUSEEVENT *)0xbfa711ac))
(*((win32k!tagMOUSEEVENT *)0xbfa711ac)) [Type: tagMOUSEEVENT]
[+0x000] ButtonFlags : 0x0 [Type: unsigned short]
[+0x002] ButtonData : 0x0 [Type: unsigned short]
[+0x004] ExtraInfo : 0x0 [Type: unsigned long]
[+0x008] ptPointer : {x=638 y=431} [Type: tagPOINT]
[+0x010] time : -3486703 [Type: long]
[+0x014] bInjected : 0 [Type: int]
[+0x018] hDevice : 0x10049 [Type: void *]
[+0x01c] rawData [Type: _MOUSE_INPUT_DATA]


return TRUE;
}

1: kd> x win32k!gdwMouseEvents
bfa71024 win32k!gdwMouseEvents = 0

1: kd> dv
pme = 0xf75d6a8c
1: kd> dx -id 0,0,89831250 -r1 ((win32k!tagMOUSEEVENT *)0xf75d6a8c)
((win32k!tagMOUSEEVENT *)0xf75d6a8c) : 0xf75d6a8c [Type: tagMOUSEEVENT *]
[+0x000] ButtonFlags : 0x0 [Type: unsigned short]
[+0x002] ButtonData : 0x0 [Type: unsigned short]
[+0x004] ExtraInfo : 0x0 [Type: unsigned long]
[+0x008] ptPointer : {x=638 y=431} [Type: tagPOINT]
[+0x010] time : -3486703 [Type: long]
[+0x014] bInjected : 0 [Type: int]
[+0x018] hDevice : 0x10049 [Type: void *]
[+0x01c] rawData [Type: _MOUSE_INPUT_DATA]

VOID ProcessQueuedMouseEvents(
VOID)
{
MOUSEEVENT MouseEvent;
static POINT ptCursorLast = {0,0};

while (UnqueueMouseEvent(&MouseEvent)) { 返回到这里:


gpsi->ptCursor = MouseEvent.ptPointer;

1: kd> x win32k!gpsi
bfa70698 win32k!gpsi = 0xbc610c9c
1: kd> dx -id 0,0,89831250 -r1 ((win32k!tagSERVERINFO *)0xbc610c9c)

[+0x898] ptCursor : {x=242 y=482} [Type: tagPOINT]

#define IsMouseSinkPresent() (gHidCounters.cMouseSinks > 0)

1: kd> x win32k!gHidCounters
bfa6ed70 win32k!gHidCounters = struct tagHID_COUNTERS
1: kd> dx -id 0,0,89831250 -r1 (*((win32k!tagHID_COUNTERS *)0xbfa6ed70))
(*((win32k!tagHID_COUNTERS *)0xbfa6ed70)) [Type: tagHID_COUNTERS]
[+0x000] cKbdSinks : 0x0 [Type: unsigned long]
[+0x004] cMouseSinks : 0x0 [Type: unsigned long]
[+0x008] cHidSinks : 0x0 [Type: unsigned long]


1: kd> dv
ptCursorLast = {x=242 y=482}
MouseEvent = struct tagMOUSEEVENT
1: kd> dx -id 0,0,89831250 -r1 (*((win32k!tagMOUSEEVENT *)0xf75d6a8c))
(*((win32k!tagMOUSEEVENT *)0xf75d6a8c)) [Type: tagMOUSEEVENT]
[+0x000] ButtonFlags : 0x0 [Type: unsigned short]
[+0x002] ButtonData : 0x0 [Type: unsigned short]
[+0x004] ExtraInfo : 0x0 [Type: unsigned long]
[+0x008] ptPointer : {x=638 y=431} [Type: tagPOINT]
[+0x010] time : -3486703 [Type: long]
[+0x014] bInjected : 0 [Type: int]
[+0x018] hDevice : 0x10049 [Type: void *]
[+0x01c] rawData [Type: _MOUSE_INPUT_DATA]


[+0x8a0] dwLastRITEventTickCount : 0xffcad2f7 [Type: unsigned long]

gpsi->dwLastRITEventTickCount = MouseEvent.time;


[+0x8a0] dwLastRITEventTickCount : 0xffcacc11 [Type: unsigned long]


[+0x898] ptCursor : {x=242 y=482} [Type: tagPOINT]

gpsi->ptCursor = MouseEvent.ptPointer;

[+0x898] ptCursor : {x=638 y=431} [Type: tagPOINT]

1: kd> x win32k!gpqForeground
bfa71aa0 win32k!gpqForeground = 0xe16027f8
1: kd> dx -id 0,0,89831250 -r1 ((win32k!tagQ *)0xe16027f8)
((win32k!tagQ *)0xe16027f8) : 0xe16027f8 [Type: tagQ *]
[+0x000] mlInput [Type: tagMLIST]
[+0x00c] ptiSysLock : 0x0 [Type: tagTHREADINFO *]
[+0x010] idSysLock : 0x1 [Type: unsigned long]
[+0x014] idSysPeek : 0x0 [Type: unsigned long]
[+0x018] ptiMouse : 0xe1406ea8 [Type: tagTHREADINFO *]
[+0x01c] ptiKeyboard : 0xe1406ea8 [Type: tagTHREADINFO *]

#define TestRawInputMode(pti, mode) \
((pti) && (pti)->ppi && (pti)->ppi->pHidTable && (pti)->ppi->pHidTable->f##mode)

[+0x188] pHidTable : 0x0 [Type: tagPROCESS_HID_TABLE *]

#ifdef GENERIC_INPUT
if ((gpqForeground && TestRawInputMode(PtiMouseFromQ(gpqForeground), RawMouse))
#ifdef GI_SINK
|| IsMouseSinkPresent()
#endif
) { 条件不成立。
PostRawMouseInput(gpqForeground, MouseEvent.time, MouseEvent.hDevice, &MouseEvent.rawData);
}
#endif

1: kd> p
eax=e1402e70 ebx=00000000 ecx=0000027e edx=000023d4 esi=00000000 edi=bfa03214
eip=bf8e8cb4 esp=f75d6a88 ebp=f75d6ac0 iopl=0 nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000246
win32k!ProcessQueuedMouseEvents+0x20d:
bf8e8cb4 e87a3dfcff call win32k!zzzSetFMouseMoved (bf8aca33)
1: kd> t
eax=e1402e70 ebx=00000000 ecx=0000027e edx=000023d4 esi=00000000 edi=bfa03214
eip=bf8aca33 esp=f75d6a84 ebp=f75d6ac0 iopl=0 nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000246
win32k!zzzSetFMouseMoved:
bf8aca33 55 push ebp
1: kd> kc
#
00 win32k!zzzSetFMouseMoved
01 win32k!ProcessQueuedMouseEvents
02 win32k!RawInputThread
03 win32k!xxxCreateSystemThreads
04 win32k!NtUserCallOneParam
05 nt!_KiSystemService
06 SharedUserData!SystemCallStub
07 winsrv!NtUserCallOneParam


1: kd> x win32k!gspwndScreenCapture
bfa71adc win32k!gspwndScreenCapture = 0x00000000

1: kd> x win32k!gspwndMouseOwner
bfa71648 win32k!gspwndMouseOwner = 0x00000000
1: kd> x win32k!gspwndInternalCapture
bfa71ad8 win32k!gspwndInternalCapture = 0x00000000


if ((pwnd = gspwndMouseOwner) == NULL) {
if ((pwnd = gspwndInternalCapture) == NULL) {

UserAssert(grpdeskRitInput != NULL);

#ifdef REDIRECTION
if (pwndStart == NULL) {
pwndStart = grpdeskRitInput->pDeskInfo->spwnd;
}
pwnd = SpeedHitTest(pwndStart, ptMouse);
#else
pwnd = SpeedHitTest(grpdeskRitInput->pDeskInfo->spwnd, gpsi->ptCursor);
#endif // REDIRECTION

}
}

1: kd> x win32k!grpdeskRitInput
bfa71408 win32k!grpdeskRitInput = 0x8948aa78
1: kd> dx -id 0,0,89831250 -r1 ((win32k!tagDESKTOP *)0x8948aa78)
((win32k!tagDESKTOP *)0x8948aa78) : 0x8948aa78 [Type: tagDESKTOP *]
[+0x000] dwSessionId : 0x0 [Type: unsigned long]
[+0x004] pDeskInfo : 0xbc640c9c [Type: tagDESKTOPINFO *]
[+0x008] pDispInfo : 0xbc611c8c [Type: tagDISPLAYINFO *]

1: kd> dx -id 0,0,89831250 -r1 ((win32k!tagDESKTOPINFO *)0xbc640c9c)
((win32k!tagDESKTOPINFO *)0xbc640c9c) : 0xbc640c9c [Type: tagDESKTOPINFO *]
[+0x000] pvDesktopBase : 0xbc640000 [Type: void *]
[+0x004] pvDesktopLimit : 0xbc660000 [Type: void *]
[+0x008] spwnd : 0xbc640dd4 [Type: tagWND *]

1: kd> dx -id 0,0,89831250 -r1 ((win32k!tagWND *)0xbc640dd4)
((win32k!tagWND *)0xbc640dd4) : 0xbc640dd4 [Type: tagWND *]

[+0x040] rcWindow : {LT(0, 0) RB(1024, 768) [1024 x 768]} [Type: tagRECT]
[+0x050] rcClient : {LT(0, 0) RB(1024, 768) [1024 x 768]} [Type: tagRECT]
[+0x060] lpfnWndProc : 0xbf85c485 [Type: long (*)(tagWND *,unsigned int,unsigned int,long)]

1: kd> u bf85c485
win32k!xxxDesktopWndProc [d:\srv03rtm\windows\core\ntuser\kernel\desktop.c @ 1151]:
bf85c485 55 push ebp
bf85c486 8bec mov ebp,esp
bf85c488 83ec68 sub esp,68h

1: kd> t
eax=bc640c9c ebx=00000000 ecx=0000027e edx=000023d4 esi=00000000 edi=bfa03214
eip=bf810864 esp=f75d6a64 ebp=f75d6a80 iopl=0 nv up ei ng nz na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000286
win32k!SpeedHitTest:
bf810864 55 push ebp
1: kd> dv
pwndParent = 0xbc640dd4
pt = {x=638 y=431}
1: kd> kc
#
00 win32k!SpeedHitTest
01 win32k!zzzSetFMouseMoved
02 win32k!ProcessQueuedMouseEvents
03 win32k!RawInputThread
04 win32k!xxxCreateSystemThreads
05 win32k!NtUserCallOneParam
06 nt!_KiSystemService
07 SharedUserData!SystemCallStub
08 winsrv!NtUserCallOneParam
1: kd> gu
WARNING: Software breakpoints on session addresses can cause bugchecks.
Use hardware execution breakpoints (ba e) if possible.
eax=bc645734 ebx=00000000 ecx=0000027e edx=000023d4 esi=00000000 edi=bfa03214
eip=bf8acab3 esp=f75d6a74 ebp=f75d6a80 iopl=0 nv up ei ng nz na po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000282
win32k!zzzSetFMouseMoved+0x80:
bf8acab3 8bd8 mov ebx,eax

eax=bc645734 是编辑区窗口,父窗口是Help对话框。

1: kd> dt win32k!wnd bc645734
+0x000 head : _THRDESKHEAD
+0x014 state : 0x20000
+0x018 state2 : 0x80000300
+0x01c ExStyle : 0x40000804
+0x020 style : 0x50000844
+0x024 hModule : 0x75080000 Void
+0x028 hMod16 : 0
+0x02a fnid : 0x2a5
+0x02c spwndNext : 0xbc64589c tagWND
+0x030 spwndPrev : 0xbc6455cc tagWND
+0x034 spwndParent : 0xbc644c14 tagWND
+0x038 spwndChild : (null)
+0x03c spwndOwner : (null)
+0x040 rcWindow : tagRECT
+0x050 rcClient : tagRECT
+0x060 lpfnWndProc : 0x77d0126c long USER32!EditWndProcW+0

1: kd> dx -id 0,0,89831250 -r1 (*((win32k!_LARGE_UNICODE_STRING *)0xbc6457b4))
(*((win32k!_LARGE_UNICODE_STRING *)0xbc6457b4)) [Type: _LARGE_UNICODE_STRING]
[+0x000] Length : 0x0 [Type: unsigned long]
[+0x004 (30: 0)] MaximumLength : 0x2 [Type: unsigned long]
[+0x004 (31:31)] bAnsi : 0x0 [Type: unsigned long]
[+0x008] Buffer : 0xbc64583c : 0x0 [Type: unsigned short *]
1: kd> dx -id 0,0,89831250 -r1 ((win32k!tagWND *)0xbc644c14)
((win32k!tagWND *)0xbc644c14) : 0xbc644c14 [Type: tagWND *]

[+0x040] rcWindow : {LT(373, 205) RB(757, 583) [384 x 378]} [Type: tagRECT]
[+0x050] rcClient : {LT(376, 227) RB(754, 580) [378 x 353]} [Type: tagRECT]
[+0x060] lpfnWndProc : 0x77ce6bd6 [Type: long (*)(tagWND *,unsigned int,unsigned int,long)]

1: kd> u 77ce6bd6
USER32!DefDlgProcW [d:\srv03rtm\windows\core\ntuser\client\dlgmgr.c @ 1013]:
77ce6bd6 ?? ???
^ Memory access error in 'u 77ce6bd6'
1: kd> dx -id 0,0,89831250 -r1 (*((win32k!_LARGE_UNICODE_STRING *)0xbc644c94))
(*((win32k!_LARGE_UNICODE_STRING *)0xbc644c94)) [Type: _LARGE_UNICODE_STRING]
[+0x000] Length : 0x14 [Type: unsigned long]
[+0x004 (30: 0)] MaximumLength : 0x16 [Type: unsigned long]
[+0x004 (31:31)] bAnsi : 0x0 [Type: unsigned long]
[+0x008] Buffer : 0xbc643f74 : 0x4c [Type: unsigned short *]
1: kd> db 0xbc643f74
bc643f74 4c 00 6f 00 67 00 6f 00-6e 00 20 00 48 00 65 00 L.o.g.o.n. .H.e.
bc643f84 6c 00 70 00 00 00 55 48-5f 54 41 49 4c 00 ab ab l.p...UH_TAIL...

1: kd> x win32k!gpqCursor
bfa71a98 win32k!gpqCursor = 0xe163f6f0


1: kd> dx -id 0,0,89831250 -r1 (*((win32k!_THRDESKHEAD *)0xbc645734))
(*((win32k!_THRDESKHEAD *)0xbc645734)) [Type: _THRDESKHEAD]
[+0x000] h : 0x1004a [Type: void *]
[+0x004] cLockObj : 0x2 [Type: unsigned long]
[+0x008] pti : 0xe1406ea8 [Type: tagTHREADINFO *]
[+0x00c] rpdesk : 0x8948aa78 [Type: tagDESKTOP *]
[+0x010] pSelf : 0xbc645734 : 0x4a [Type: unsigned char *]
1: kd> dx -id 0,0,89831250 -r1 ((win32k!tagTHREADINFO *)0xe1406ea8)
((win32k!tagTHREADINFO *)0xe1406ea8) : 0xe1406ea8 [Type: tagTHREADINFO *]
[+0x000] pEThread : 0x89575020 [Type: _ETHREAD *]
[+0x004] RefCount : 0x1 [Type: unsigned long]
[+0x008] ptlW32 : 0x0 [Type: _TL *]
[+0x00c] pgdiDcattr : 0x5e0740 [Type: void *]
[+0x010] pgdiBrushAttr : 0x0 [Type: void *]
[+0x014] pUMPDObjs : 0x0 [Type: void *]
[+0x018] pUMPDHeap : 0x0 [Type: void *]
[+0x01c] pUMPDObj : 0x0 [Type: void *]
[+0x020] GdiTmpAllocList [Type: _LIST_ENTRY]
[+0x028] ptl : 0x0 [Type: _TL *]
[+0x02c] ppi : 0xe1402e70 [Type: tagPROCESSINFO *]
[+0x030] pq : 0xe16027f8 [Type: tagQ *]

1: kd> x win32k!gpqCursor
bfa71a98 win32k!gpqCursor = 0xe163f6f0


1: kd> dx -id 0,0,89831250 -r1 ((win32k!tagQ *)0xe163f6f0)
((win32k!tagQ *)0xe163f6f0) : 0xe163f6f0 [Type: tagQ *]
[+0x000] mlInput [Type: tagMLIST]
[+0x00c] ptiSysLock : 0x0 [Type: tagTHREADINFO *]
[+0x010] idSysLock : 0x1 [Type: unsigned long]
[+0x014] idSysPeek : 0x0 [Type: unsigned long]
[+0x018] ptiMouse : 0xe1639460 [Type: tagTHREADINFO *]
[+0x01c] ptiKeyboard : 0xe1639460 [Type: tagTHREADINFO *]
[+0x020] spwndCapture : 0x0 [Type: tagWND *] 为0

1: kd> dx -id 0,0,89831250 -r1 ((win32k!tagTHREADINFO *)0xe1639460)
((win32k!tagTHREADINFO *)0xe1639460) : 0xe1639460 [Type: tagTHREADINFO *]
[+0x000] pEThread : 0x89804020 [Type: _ETHREAD *]


1: kd> !thread 0x89804020
THREAD 89804020 Cid 01b0.01e0 Teb: 7ffd8000 Win32Thread: e1639460 WAIT: (WrUserRequest) UserMode Non-Alertable
8957cd20 SynchronizationEvent
89505548 SynchronizationEvent
89804b80 SynchronizationEvent
IRP List:
897d0890: (0006,01d8) Flags: 00000970 Mdl: 00000000
8989e008: (0006,0190) Flags: 00000970 Mdl: 00000000
89530910: (0006,01d8) Flags: 00000970 Mdl: 00000000
89756e70: (0006,0190) Flags: 00000970 Mdl: 00000000
Not impersonating
DeviceMap e10003d8
Owning Process 89831250 Image: csrss.exe
Attached Process N/A Image: N/A
Wait Start TickCount 274654759 Ticks: 124 (0:00:00:01.937)
Context Switch Count 601 IdealProcessor: 1 LargeStack
UserTime 00:00:00.000
KernelTime 00:00:00.687
Stack Init f75f7000 Current f75f692c Base f75f7000 Limit f75f4000 Call 00000000
Priority 15 BasePriority 13 PriorityDecrement 0 IoPriority 0 PagePriority 0
ChildEBP RetAddr Args to Child
f75f6944 80a440eb f7737120 89804020 89804080 nt!KiSwapContext+0x26 (FPO: [Uses EBP] [0,0,4]) [d:\srv03rtm\base\ntos\ke\i386\ctxswap.asm @ 139]
f75f697c 80a358c7 00000000 e1639460 00000002 nt!KiSwapThread+0x627 (FPO: [Non-Fpo]) (CONV: fastcall) [d:\srv03rtm\base\ntos\ke\thredsup.c @ 2000]
f75f69b4 bf8a4685 00000003 89804b50 00000001 nt!KeWaitForMultipleObjects+0x3b5 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\ke\wait.c @ 816]
f75f6a04 bf8b123e 00000002 89804b50 bf8fe215 win32k!xxxMsgWaitForMultipleObjects+0xeb (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\windows\core\ntuser\kernel\queue.c @ 4540]
f75f6d1c bf8b21ba bfa70aa0 00000001 f75f6d48 win32k!xxxDesktopThread+0x437 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\windows\core\ntuser\kernel\desktop.c @ 594]
f75f6d2c bf806d52 bfa70aa0 f75f6d58 008cfff4 win32k!xxxCreateSystemThreads+0x9c (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\windows\core\ntuser\kernel\desktop.c @ 347]
f75f6d48 80afbcb2 00000000 00000022 80afb956 win32k!NtUserCallOneParam+0xa0 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\windows\core\ntuser\kernel\ntstubs.c @ 4789]
f75f6d48 7ffe0304 00000000 00000022 80afb956 nt!_KiSystemService+0x13f (FPO: [0,3] TrapFrame @ f75f6d64) (CONV: cdecl) [d:\srv03rtm\base\ntos\ke\i386\trap.asm @ 1328]
008cffe0 75340774 75318a89 00000000 00000022 SharedUserData!SystemCallStub+0x4 (FPO: [0,0,0])
008cffe8 00000000 00000022 00000004 00000000 winsrv!NtUserCallOneParam+0xc (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\windows\core\umode\daytona\obj\i386\usrstubs.c @ 2683]


if ((pwndOldCursor != NULL) && (PtoHq(pwndOldCursor) != PtoHq(pwnd))) {
PDESKTOP pdesk = GETPDESK(pwndOldCursor);
if (pdesk->dwDTFlags & DF_MOUSEMOVETRK) { 条件不满足
PTHREADINFO pti = GETPTI(pdesk->spwndTrack);
PostEventMessage(pti, pti->pq, QEVENT_CANCELMOUSEMOVETRK,
pdesk->spwndTrack, pdesk->dwDTFlags, pdesk->htEx,
DF_MOUSEMOVETRK);
pdesk->dwDTFlags &= ~DF_MOUSEMOVETRK;
}
}


gpqCursor = pq;

/*
* Call zzzUpdateCursorImage() so the new gpqCursor's
* notion of the current cursor is represented.
*/
zzzUpdateCursorImage();

/*
* Wake some thread within this queue to process this mouse event.
*/
WakeSomeone(pq, WM_MOUSEMOVE, NULL);

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/4 20:39:22

9个开题报告神器,AI工具推荐让论文更高效!

9个开题报告神器&#xff0c;AI工具推荐让论文更高效&#xff01; 论文路上的“三座大山”&#xff1a;时间、重复率与效率 对于大多数本科生而言&#xff0c;撰写开题报告和毕业论文是一段既紧张又充满挑战的旅程。从选题到资料搜集&#xff0c;从文献综述到框架搭建&#xff…

作者头像 李华
网站建设 2026/1/13 14:24:13

【ros2】告别重复代码:Xacro让URDF编写效率翻倍

文章目录 告别重复代码:Xacro让URDF编写效率翻倍 一、Xacro到底解决了什么问题? 二、Xacro基础语法:先掌握这5个核心 1. 第一步:声明Xacro命名空间(必写!) 2. 变量定义与引用:`<xacro:property>` (1)定义变量 (2)引用变量 3. 数学计算:直接在`${}`中写公式 …

作者头像 李华
网站建设 2026/1/12 12:23:12

8 个论文写作工具,本科生期末论文轻松搞定!

8 个论文写作工具&#xff0c;本科生期末论文轻松搞定&#xff01; 论文路上的“拦路虎”&#xff0c;你是否也经历过&#xff1f; 对于大多数本科生来说&#xff0c;期末论文写作从来不是一件轻松的事。从选题到查资料&#xff0c;从写大纲到撰写正文&#xff0c;每一个环节都…

作者头像 李华
网站建设 2026/1/9 23:45:07

网络安全怎么快速入门,新手也能少走半年弯路!

后台总收到私信&#xff1a;“学网安该先看 Linux 还是先学 Burp&#xff1f;”“找了一堆教程&#xff0c;越学越乱怎么办&#xff1f;”—— 其实不是你学得慢&#xff0c;是没找对循序渐进的路径。很多人一上来就跟风学工具、刷漏洞&#xff0c;结果基础不牢&#xff0c;后期…

作者头像 李华
网站建设 2025/12/31 17:06:08

LeetCode hot 100 —— 哈希(面试纯背版)(一)

一、哈希 1、俩数之和 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。 你可以按任意顺序返回答案。 示例 1: 输…

作者头像 李华