win32k!ProcessKeyboardInputWorker函数和win32k!xxxProcessKeyEvent函数分析键盘扫描码和vk码
win32k!ProcessKeyboardInputWorker函数和win32k!xxxProcessKeyEvent函数分析键盘扫描码和vk码
Breakpoint 4 hit
eax=f75d698c ebx=e1418ab8 ecx=f75d0036 edx=ffffffa5 esi=00008000 edi=00000000
eip=bf8e8675 esp=f75d6970 ebp=f75d69a4 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!xxxProcessKeyEvent:
bf8e8675 55 push ebp
1: kd> kc
#
00 win32k!xxxProcessKeyEvent
01 win32k!ProcessKeyboardInputWorker
02 win32k!ProcessKeyboardInput
03 win32k!InputApc
04 nt!KiDeliverApc
05 nt!KiSwapThread
06 nt!KeWaitForMultipleObjects
07 win32k!RawInputThread
08 win32k!xxxCreateSystemThreads
09 win32k!NtUserCallOneParam
0a nt!_KiSystemService
0b SharedUserData!SystemCallStub
0c winsrv!NtUserCallOneParam
1: kd> dv
pke = 0xf75d698c
ExtraInformation = 0
bInjected = 0n0
Vk = 0x8c ''
1: kd> dx -id 0,0,8960a020 -r1 ((win32k!tagKE *)0xf75d698c)
((win32k!tagKE *)0xf75d698c) : 0xf75d698c [Type: tagKE *]
[+0x000] bScanCode : 0x7 [Type: unsigned char]
[+0x000] wchInjected : 0x7c07 [Type: unsigned short]
[+0x002] usFlaggedVk : 0x36 [Type: unsigned short]
[+0x004] dwTime : 0xffffffff [Type: unsigned long]
[+0x008] hDevice : 0x10063 [Type: void *]
[+0x00c] data [Type: _KEYBOARD_INPUT_DATA]
1: kd> dx -id 0,0,8960a020 -r1 (*((win32k!_KEYBOARD_INPUT_DATA *)0xf75d6998))
(*((win32k!_KEYBOARD_INPUT_DATA *)0xf75d6998)) [Type: _KEYBOARD_INPUT_DATA]
[+0x000] UnitId : 0x0 [Type: unsigned short]
[+0x002] MakeCode : 0x7 [Type: unsigned short]
[+0x004] Flags : 0x0 [Type: unsigned short]
[+0x006] Reserved : 0x0 [Type: unsigned short]
[+0x008] ExtraInformation : 0x0 [Type: unsigned long]
1: kd> g
Breakpoint 1 hit
eax=00000036 ebx=00008000 ecx=ffecf791 edx=00000000 esi=f75d698c edi=00004000
eip=bf8e7974 esp=f75d6940 ebp=f75d696c 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!xxxKeyEvent:
bf8e7974 55 push ebp
1: kd> dv
usFlaggedVk = 0x36
wScanCode = 7
time = 0xffecf791
ExtraInfo = 0
hDevice = 0x00010063
pkei = 0xf75d6998
bInjected = 0n0
fSASHandled = 0n16384
message = 8
fsReserveKeys = 0
fMakeAltUpASysKey = 0n0
Vk = 0x74 't'
tlpwndActivate = struct _TL
ptiCurrent = 0x00008000
fBreak = 0n-144873108
usExtraStuff = 0
bAnsiHook = 0n48
msg = 0x698c
kbds = struct tagKBDLLHOOKSTRUCT
fsModifiers = 0xf75d698c
fsModifiers = 0x30
wParam = 0
1: kd> kc
#
00 win32k!xxxKeyEvent
01 win32k!xxxProcessKeyEvent
02 win32k!ProcessKeyboardInputWorker
03 win32k!ProcessKeyboardInput
04 win32k!InputApc
05 nt!KiDeliverApc
06 nt!KiSwapThread
07 nt!KeWaitForMultipleObjects
08 win32k!RawInputThread
09 win32k!xxxCreateSystemThreads
0a win32k!NtUserCallOneParam
0b nt!_KiSystemService
0c SharedUserData!SystemCallStub
0d winsrv!NtUserCallOneParam
第二部分:
VOID ProcessKeyboardInput(PDEVICEINFO pDeviceInfo)
{
pkeiStart = pDeviceInfo->keyboard.Data;
pkeiEnd = (PKEYBOARD_INPUT_DATA)((PBYTE)pkeiStart + pDeviceInfo->iosb.Information);
for (pkei = pkeiStart; pkei < pkeiEnd; pkei++) {
ProcessKeyboardInputWorker(pkei,
#ifdef GENERIC_INPUT
pDeviceInfo,
#endif
TRUE);
}
LeaveCrit();
}
1: kd> dt DEVICEINFO e1418a48
win32k!DEVICEINFO
+0x000 head : _HEAD
+0x008 pNext : 0xe167f428 tagDEVICEINFO
+0x00c type : 0x1 ''
+0x00d bFlags : 0x2 ''
+0x00e usActions : 0
+0x010 nRetryRead : 0 ''
+0x014 ustrName : _UNICODE_STRING "\??\ACPI#PNP0303#4&5289e18&0#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}"
+0x01c handle : 0x0000022c Void
+0x020 NotificationEntry : 0xe1416e58 Void
+0x024 pkeHidChangeCompleted : 0x896049e8 _KEVENT
+0x028 iosb : _IO_STATUS_BLOCK
+0x030 ReadStatus : 0n0
+0x034 OpenerProcess : 0x000001b0 Void
+0x038 OpenStatus : 0n0
+0x03c AttrStatus : 0n0
+0x040 timeStartRead : 0xffecf8d9
+0x044 timeEndRead : 0xffecf8da
+0x048 nReadsOutstanding : 0n0
+0x04c mouse : tagMOUSE_DEVICE_INFO
+0x04c keyboard : tagKEYBOARD_DEVICE_INFO
+0x04c hid : tagHID_DEVICE_INFO
1: kd> dx -id 0,0,8960a020 -r1 (*((win32k!_IO_STATUS_BLOCK *)0xe1418a70))
(*((win32k!_IO_STATUS_BLOCK *)0xe1418a70)) [Type: _IO_STATUS_BLOCK]
[+0x000] Status : 0 [Type: long]
[+0x000] Pointer : 0x0 [Type: void *]
[+0x004] Information : 0xc [Type: unsigned long]
1: kd> dx -id 0,0,8960a020 -r1 (*((win32k!tagKEYBOARD_DEVICE_INFO *)0xe1418a94))
(*((win32k!tagKEYBOARD_DEVICE_INFO *)0xe1418a94)) [Type: tagKEYBOARD_DEVICE_INFO]
[+0x000] Attr [Type: _KEYBOARD_ATTRIBUTES]
[+0x01c] IdEx [Type: _KEYBOARD_ID_EX]
[+0x024] Data [Type: _KEYBOARD_INPUT_DATA [10]]
1: kd> dx -id 0,0,8960a020 -r1 (*((win32k!_KEYBOARD_INPUT_DATA (*)[10])0xe1418ab8))
(*((win32k!_KEYBOARD_INPUT_DATA (*)[10])0xe1418ab8)) [Type: _KEYBOARD_INPUT_DATA [10]]
[0] [Type: _KEYBOARD_INPUT_DATA]
[1] [Type: _KEYBOARD_INPUT_DATA]
[2] [Type: _KEYBOARD_INPUT_DATA]
[3] [Type: _KEYBOARD_INPUT_DATA]
[4] [Type: _KEYBOARD_INPUT_DATA]
[5] [Type: _KEYBOARD_INPUT_DATA]
[6] [Type: _KEYBOARD_INPUT_DATA]
[7] [Type: _KEYBOARD_INPUT_DATA]
[8] [Type: _KEYBOARD_INPUT_DATA]
[9] [Type: _KEYBOARD_INPUT_DATA]
1: kd> dt win32k!_KEYBOARD_INPUT_DATA 0xe1418ab8+c*0
+0x000 UnitId : 0
+0x002 MakeCode : 7
+0x004 Flags : 1
+0x006 Reserved : 0
+0x008 ExtraInformation : 0
1: kd> dt win32k!_KEYBOARD_INPUT_DATA 0xe1418ab8+c*1
+0x000 UnitId : 0
+0x002 MakeCode : 0x1d
+0x004 Flags : 0
+0x006 Reserved : 0
+0x008 ExtraInformation : 0
1: kd> dt win32k!_KEYBOARD_INPUT_DATA 0xe1418ab8+c*2
+0x000 UnitId : 0
+0x002 MakeCode : 0x1d
+0x004 Flags : 0
+0x006 Reserved : 0
+0x008 ExtraInformation : 0
1: kd> dt win32k!_KEYBOARD_INPUT_DATA 0xe1418ab8+c*3
+0x000 UnitId : 0
+0x002 MakeCode : 0x1d
+0x004 Flags : 0
+0x006 Reserved : 0
+0x008 ExtraInformation : 0
1: kd> dt win32k!_KEYBOARD_INPUT_DATA 0xe1418ab8+c*4
+0x000 UnitId : 0
+0x002 MakeCode : 0x1d
+0x004 Flags : 0
+0x006 Reserved : 0
+0x008 ExtraInformation : 0
1: kd> dt win32k!_KEYBOARD_INPUT_DATA 0xe1418ab8+c*5
+0x000 UnitId : 0
+0x002 MakeCode : 0x5b
+0x004 Flags : 2
+0x006 Reserved : 0
+0x008 ExtraInformation : 0
1: kd> dt win32k!_KEYBOARD_INPUT_DATA 0xe1418ab8+c*6
+0x000 UnitId : 0
+0x002 MakeCode : 0x5b
+0x004 Flags : 3
+0x006 Reserved : 0
+0x008 ExtraInformation : 0
1: kd> dt win32k!_KEYBOARD_INPUT_DATA 0xe1418ab8+c*7
+0x000 UnitId : 0
+0x002 MakeCode : 0x1d
+0x004 Flags : 1
+0x006 Reserved : 0
+0x008 ExtraInformation : 0
1: kd> dt win32k!_KEYBOARD_INPUT_DATA 0xe1418ab8+c*8
+0x000 UnitId : 0
+0x002 MakeCode : 0x1d
+0x004 Flags : 0
+0x006 Reserved : 0
+0x008 ExtraInformation : 0
1: kd> dt win32k!_KEYBOARD_INPUT_DATA 0xe1418ab8+c*9
+0x000 UnitId : 0
+0x002 MakeCode : 0x1d
+0x004 Flags : 0
+0x006 Reserved : 0
+0x008 ExtraInformation : 0
1: kd> dt win32k!_KEYBOARD_INPUT_DATA 0xe1418ab8+c*a
+0x000 UnitId : 0x620
+0x002 MakeCode : 0xc05
+0x004 Flags : 0x7355
+0x006 Reserved : 0x6b74
+0x008 ExtraInformation : 0xbf8a7688
第三部分:
Breakpoint 6 hit
eax=e1418ab8 ebx=e1418ab8 ecx=80ae2d98 edx=bfa6fd2c esi=e1418a48 edi=e1418ac4
eip=bf8e9575 esp=f75d69a8 ebp=f75d69c4 iopl=0 nv up ei ng nz na po cy
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000283
win32k!ProcessKeyboardInputWorker:
bf8e9575 55 push ebp
1: kd> kc
#
00 win32k!ProcessKeyboardInputWorker
01 win32k!ProcessKeyboardInput
02 win32k!InputApc
03 nt!KiDeliverApc
04 nt!KiSwapThread
05 nt!KeWaitForMultipleObjects
06 win32k!RawInputThread
07 win32k!xxxCreateSystemThreads
08 win32k!NtUserCallOneParam
09 nt!_KiSystemService
0a SharedUserData!SystemCallStub
0b winsrv!NtUserCallOneParam
1: kd> dv
pkei = 0xe1418ab8
pDeviceInfo = 0xe1418a48
fProcessRemap = 0n1
1: kd> dx -id 0,0,8960a020 -r1 ((win32k!_KEYBOARD_INPUT_DATA *)0xe1418ab8)
((win32k!_KEYBOARD_INPUT_DATA *)0xe1418ab8) : 0xe1418ab8 [Type: _KEYBOARD_INPUT_DATA *]
[+0x000] UnitId : 0x0 [Type: unsigned short]
[+0x002] MakeCode : 0x7 [Type: unsigned short]
[+0x004] Flags : 0x1 [Type: unsigned short]
[+0x006] Reserved : 0x0 [Type: unsigned short]
[+0x008] ExtraInformation : 0x0 [Type: unsigned long]
//
// Define the keyboard input data Flags.
//
#define KEY_MAKE 0
#define KEY_BREAK 1
#define KEY_E0 2
#define KEY_E1 4
#define KEY_TERMSRV_SET_LED 8
#define KEY_TERMSRV_SHADOW 0x10
#define KEY_TERMSRV_VKPACKET 0x20
#ifdef GENERIC_INPUT
/*
* Set the device handle and raw data
*/
ke.hDevice = PtoH(pDeviceInfo);
UserAssert(pkei);
ke.data = *pkei;
#endif
1: kd> dv
pkei = 0xe1418ab8
pDeviceInfo = 0xe1418a48
fProcessRemap = 0n1
Vk = 0xe1 ''
bPrefix = 0xb8 ''
ke = struct tagKE
1: kd> dx -id 0,0,8960a020 -r1 (*((win32k!tagKE *)0xf75d698c))
(*((win32k!tagKE *)0xf75d698c)) [Type: tagKE]
[+0x000] bScanCode : 0xb8 [Type: unsigned char]
[+0x000] wchInjected : 0x8ab8 [Type: unsigned short]
[+0x002] usFlaggedVk : 0xe141 [Type: unsigned short]
[+0x004] dwTime : 0xf75d69a4 [Type: unsigned long]
[+0x008] hDevice : 0x10063 [Type: void *]
[+0x00c] data [Type: _KEYBOARD_INPUT_DATA]
1: kd> dx -id 0,0,8960a020 -r1 (*((win32k!_KEYBOARD_INPUT_DATA *)0xf75d6998))
(*((win32k!_KEYBOARD_INPUT_DATA *)0xf75d6998)) [Type: _KEYBOARD_INPUT_DATA]
[+0x000] UnitId : 0x0 [Type: unsigned short]
[+0x002] MakeCode : 0x7 [Type: unsigned short]
[+0x004] Flags : 0x1 [Type: unsigned short]
[+0x006] Reserved : 0x0 [Type: unsigned short]
[+0x008] ExtraInformation : 0x0 [Type: unsigned long]
1: kd> x win32k!gSetLedReceived
bfa70240 win32k!gSetLedReceived = 0
//
// Define the keyboard indicators.
//
#define KEYBOARD_LED_INJECTED 0x8000 //Used by Terminal Server
#define KEYBOARD_SHADOW 0x4000 //Used by Terminal Server
//#if defined(FE_SB) || defined(WINDOWS_FE) || defined(DBCS)
#define KEYBOARD_KANA_LOCK_ON 8 // Japanese keyboard
//#endif // defined(FE_SB) || defined(WINDOWS_FE) || defined(DBCS)
#define KEYBOARD_CAPS_LOCK_ON 4
#define KEYBOARD_NUM_LOCK_ON 2
#define KEYBOARD_SCROLL_LOCK_ON 1
第四部分:
ProcessKeys:
if (pkei->Flags & KEY_E0) {
bPrefix = 0xE0;
} else if (pkei->Flags & KEY_E1) {
bPrefix = 0xE1;
} else {
bPrefix = 0;
}
//
// Define the keyboard input data Flags.
//
#define KEY_MAKE 0
#define KEY_BREAK 1
#define KEY_E0 2
#define KEY_E1 4
#define KEY_TERMSRV_SET_LED 8
#define KEY_TERMSRV_SHADOW 0x10
#define KEY_TERMSRV_VKPACKET 0x20
1: kd> dx -id 0,0,8960a020 -r1 ((win32k!_KEYBOARD_INPUT_DATA *)0xe1418ab8)
((win32k!_KEYBOARD_INPUT_DATA *)0xe1418ab8) : 0xe1418ab8 [Type: _KEYBOARD_INPUT_DATA *]
[+0x000] UnitId : 0x0 [Type: unsigned short]
[+0x002] MakeCode : 0x7 [Type: unsigned short]
[+0x004] Flags : 0x1 [Type: unsigned short]
[+0x006] Reserved : 0x0 [Type: unsigned short]
[+0x008] ExtraInformation : 0x0 [Type: unsigned long]
if (pkei->MakeCode == 0xFF) {
/*
* Kbd overrun (kbd hardware and/or keyboard driver) : Beep!
* (some DELL keyboards send 0xFF if keys are hit hard enough,
* presumably due to keybounce)
*/
LeaveCrit();
UserBeep(440, 125);
EnterCrit();
return;
} //可以删除,提高运行速度。
* 键盘溢出(键盘硬件和/或键盘驱动程序):哔!
*(如果按键力度足够大,某些DELL键盘会发送0xFF,
* 推测是由于按键反弹)
1: kd> dv
pkei = 0xe1418a00
pDeviceInfo = 0xe1418a48
fProcessRemap = 0n1
Vk = 0xe1 ''
bPrefix = 0x00 ''
ke = struct tagKE
1: kd> dx -id 0,0,8960a020 -r1 (*((win32k!tagKE *)0xf75d698c))
(*((win32k!tagKE *)0xf75d698c)) [Type: tagKE]
[+0x000] bScanCode : 0xb8 [Type: unsigned char]
[+0x000] wchInjected : 0x8ab8 [Type: unsigned short]
[+0x002] usFlaggedVk : 0xe141 [Type: unsigned short]
[+0x004] dwTime : 0xf75d69a4 [Type: unsigned long]
[+0x008] hDevice : 0x10063 [Type: void *]
[+0x00c] data [Type: _KEYBOARD_INPUT_DATA]
ke.bScanCode = (BYTE)(pkei->MakeCode & 0x7F); //关键一步:
1: kd> dv
pkei = 0xe1418a00
pDeviceInfo = 0xe1418a48
fProcessRemap = 0n1
Vk = 0xe1 ''
bPrefix = 0x00 ''
ke = struct tagKE
1: kd> dx -id 0,0,8960a020 -r1 (*((win32k!tagKE *)0xf75d698c))
(*((win32k!tagKE *)0xf75d698c)) [Type: tagKE]
[+0x000] bScanCode : 0x7 [Type: unsigned char]
[+0x000] wchInjected : 0x8a07 [Type: unsigned short]
[+0x002] usFlaggedVk : 0xe141 [Type: unsigned short]
[+0x004] dwTime : 0xf75d69a4 [Type: unsigned long]
[+0x008] hDevice : 0x10063 [Type: void *]
[+0x00c] data [Type: _KEYBOARD_INPUT_DATA]
if (fProcessRemap && (gpScancodeMap || gpFlexMap)) { 条件不满足
1: kd> x win32k!gpFlexMap
bfa6eda4 win32k!gpFlexMap = 0x00000000
1: kd> x win32k!gpScancodeMap
bfa71418 win32k!gpScancodeMap = 0x00000000
gbVKLastDown = Vk = VKFromVSC(&ke, bPrefix, gafRawKeyState);
/*****************************************************************************\
* VKFromVSC
*
* This function is called from KeyEvent() after each call to VSCFromSC. The
* keyboard input data passed in is translated to a virtual key code.
* This translation is dependent upon the currently depressed modifier keys.
*
* For instance, scan codes representing the number pad keys may be
* translated into VK_NUMPAD codes or cursor movement codes depending
* upon the state of NumLock and the modifier keys.
每次调用VSCFromSC后,都会从KeyEvent()函数中调用此函数。传入的键盘输入数据会被转换为虚拟键码。
这种转换取决于当前按下的修饰键。
例如,根据NumLock和修饰键的状态,代表数字键盘按键的扫描码可能会被翻译为VK_NUMPAD码或光标移动码。
第四部分:
1: kd> x win32k!gptiForeground
bfa71ab0 win32k!gptiForeground = 0xe1404c50
1: kd> dx -id 0,0,8960a020 -r1 ((win32k!tagTHREADINFO *)0xe1404c50)
((win32k!tagTHREADINFO *)0xe1404c50) : 0xe1404c50 [Type: tagTHREADINFO *]
[+0x000] pEThread : 0x897f2020 [Type: _ETHREAD *]
[+0x004] RefCount : 0x1 [Type: unsigned long]
[+0x008] ptlW32 : 0x0 [Type: _TL *]
[+0x00c] pgdiDcattr : 0x5e0570 [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 : 0xe1619070 [Type: tagPROCESSINFO *]
[+0x030] pq : 0xe1630530 [Type: tagQ *]
[+0x034] spklActive : 0xe13e6bb8 [Type: tagKL *]
[+0x038] pcti : 0xbc643b04 [Type: tagCLIENTTHREADINFO *]
[+0x03c] rpdesk : 0x894da378 [Type: tagDESKTOP *]
[+0x040] pDeskInfo : 0xbc640c9c [Type: tagDESKTOPINFO *]
[+0x044] ulClientDelta : 0xbbe70000 [Type: unsigned long]
[+0x048] pClientInfo : 0x7ffde6cc [Type: tagCLIENTINFO *]
[+0x04c] TIF_flags : 0x1100000 [Type: unsigned long]
[+0x050] pstrAppName : 0x0 [Type: _UNICODE_STRING *]
[+0x054] psmsSent : 0x0 [Type: tagSMS *]
[+0x058] psmsCurrent : 0x0 [Type: tagSMS *]
[+0x05c] psmsReceiveList : 0x0 [Type: tagSMS *]
[+0x060] timeLast : -1247250 [Type: long]
[+0x064] idLast : 0xe16fa0a8 [Type: unsigned long]
[+0x068] exitCode : 0 [Type: int]
[+0x06c] hdesk : 0x2a4 [Type: HDESK__ *]
[+0x070] cPaintsReady : 0 [Type: int]
[+0x074] cTimersReady : 0x0 [Type: unsigned int]
[+0x078] pMenuState : 0x0 [Type: tagMENUSTATE *]
[+0x07c] ptdb : 0x0 [Type: tagTDB *]
[+0x07c] pwinsta : 0x0 [Type: tagWINDOWSTATION *]
[+0x080] psiiList : 0x0 [Type: tagSVR_INSTANCE_INFO *]
[+0x084] dwExpWinVer : 0x400 [Type: unsigned long]
[+0x088] dwCompatFlags : 0x0 [Type: unsigned long]
[+0x08c] dwCompatFlags2 : 0x0 [Type: unsigned long]
[+0x090] pqAttach : 0x0 [Type: tagQ *]
[+0x094] ptiSibling : 0x0 [Type: tagTHREADINFO *]
[+0x098] pmsd : 0x0 [Type: _MOVESIZEDATA *]
[+0x09c] fsHooks : 0x108 [Type: unsigned long]
[+0x0a0] sphkCurrent : 0x0 [Type: tagHOOK *]
[+0x0a4] pSBTrack : 0x0 [Type: tagSBTRACK *]
[+0x0a8] hEventQueueClient : 0xcc [Type: void *]
[+0x0ac] pEventQueueServer : 0x894e9610 [Type: _KEVENT *]
[+0x0b0] PtiLink [Type: _LIST_ENTRY]
[+0x0b8] iCursorLevel : 0 [Type: int]
[+0x0bc] ptLast : {x=363 y=627} [Type: tagPOINT]
[+0x0c4] spwndDefaultIme : 0x0 [Type: tagWND *]
[+0x0c8] spDefaultImc : 0x0 [Type: tagIMC *]
[+0x0cc] hklPrev : 0x0 [Type: HKL__ *]
[+0x0d0] cEnterCount : 0 [Type: int]
[+0x0d4] mlPost [Type: tagMLIST]
[+0x0e0] fsChangeBitsRemoved : 0x0 [Type: unsigned short]
[+0x0e2] wchInjected : 0x0 [Type: unsigned short]
[+0x0e4] fsReserveKeys : 0x0 [Type: unsigned long]
[+0x0e8] apEvent : 0x0 [Type: _KEVENT * *]
[+0x0ec] amdesk : 0xf01ff [Type: unsigned long]
[+0x0f0] cWindows : 0x12 [Type: unsigned int]
[+0x0f4] cVisWindows : 0x1 [Type: unsigned int]
[+0x0f8] aphkStart [Type: tagHOOK * [16]]
[+0x138] cti [Type: tagCLIENTTHREADINFO]
[+0x14c] hPrevHidData : 0x0 [Type: void *]
[+0x150] cNestedCalls : 0x1 [Type: unsigned int]
1: kd> dx -id 0,0,8960a020 -r1 ((win32k!tagKL *)0xe13e6bb8)
((win32k!tagKL *)0xe13e6bb8) : 0xe13e6bb8 [Type: tagKL *]
[+0x000] head [Type: _HEAD]
[+0x008] pklNext : 0xe13e6bb8 [Type: tagKL *]
[+0x00c] pklPrev : 0xe13e6bb8 [Type: tagKL *]
[+0x010] dwKL_Flags : 0x0 [Type: unsigned long]
[+0x014] hkl : 0x4090409 [Type: HKL__ *]
[+0x018] spkf : 0xe166c5d8 [Type: tagKBDFILE *]
[+0x01c] spkfPrimary : 0xe166c5d8 [Type: tagKBDFILE *]
[+0x020] dwFontSigs : 0x3f01ff [Type: unsigned long]
[+0x024] iBaseCharset : 0x0 [Type: unsigned int]
[+0x028] CodePage : 0x4e4 [Type: unsigned short]
[+0x02a] wchDiacritic : 0x0 [Type: unsigned short]
[+0x02c] piiex : 0x0 [Type: tagIMEINFOEX *]
[+0x030] uNumTbl : 0x0 [Type: unsigned int]
[+0x034] pspkfExtra : 0x0 [Type: tagKBDFILE * *]
[+0x038] dwLastKbdType : 0x0 [Type: unsigned long]
[+0x03c] dwLastKbdSubType : 0x0 [Type: unsigned long]
[+0x040] dwKLID : 0x409 [Type: unsigned long]
1: kd> dx -id 0,0,8960a020 -r1 ((win32k!tagKBDFILE *)0xe166c5d8)
((win32k!tagKBDFILE *)0xe166c5d8) : 0xe166c5d8 [Type: tagKBDFILE *]
[+0x000] head [Type: _HEAD]
[+0x008] pkfNext : 0x0 [Type: tagKBDFILE *]
[+0x00c] hBase : 0xe16ef018 [Type: void *]
[+0x010] pKbdTbl : 0xe16ef9b0 [Type: tagKbdLayer *]
[+0x014] Size : 0xaa7 [Type: unsigned long]
[+0x018] pKbdNlsTbl : 0x0 [Type: tagKbdNlsLayer *]
[+0x01c] awchDllName [Type: unsigned short [32]]
1: kd> dx -id 0,0,8960a020 -r1 ((win32k!tagKbdLayer *)0xe16ef9b0)
((win32k!tagKbdLayer *)0xe16ef9b0) : 0xe16ef9b0 [Type: tagKbdLayer *]
[+0x000] pCharModifiers : 0xe16ef1c4 [Type: MODIFIERS *]
[+0x004] pVkToWcharTable : 0xe16ef394 [Type: _VK_TO_WCHAR_TABLE *]
[+0x008] pDeadKey : 0x0 [Type: DEADKEY *]
[+0x00c] pKeyNames : 0xe16ef5e8 [Type: VSC_LPWSTR *]
[+0x010] pKeyNamesExt : 0xe16ef8f8 [Type: VSC_LPWSTR *]
[+0x014] pKeyNamesDead : 0x0 [Type: unsigned short * *]
[+0x018] pusVSCtoVK : 0xe16ef018 : 0xff [Type: unsigned short *]
[+0x01c] bMaxVSCtoVK : 0x7f [Type: unsigned char]
[+0x020] pVSCtoVK_E0 : 0xe16ef118 [Type: _VSC_VK *]
[+0x024] pVSCtoVK_E1 : 0xe16ef1b4 [Type: _VSC_VK *]
[+0x028] fLocaleFlags : 0x10000 [Type: unsigned long]
[+0x02c] nLgMax : 0x0 [Type: unsigned char]
[+0x02d] cbLgEntry : 0x0 [Type: unsigned char]
[+0x030] pLigature : 0x0 [Type: _LIGATURE1 *]
[+0x034] dwType : 0x0 [Type: unsigned long]
[+0x038] dwSubType : 0x0 [Type: unsigned long]
1: kd> dx -id 0,0,8960a020 -r1 ((win32k!unsigned short *)0xe16ef018)
((win32k!unsigned short *)0xe16ef018) : 0xe16ef018 : 0xff [Type: unsigned short *]
0xff [Type: unsigned short]
1: kd> db 0xe16ef018
e16ef018 ff 00 1b 00 31 00 32 00-33 00 34 00 35 00 36 00 ....1.2.3.4.5.6.
e16ef028 37 00 38 00 39 00 30 00-bd 00 bb 00 08 00 09 00 7.8.9.0.........
e16ef038 51 00 57 00 45 00 52 00-54 00 59 00 55 00 49 00 Q.W.E.R.T.Y.U.I.
e16ef048 4f 00 50 00 db 00 dd 00-0d 00 a2 00 41 00 53 00 O.P.........A.S.
e16ef058 44 00 46 00 47 00 48 00-4a 00 4b 00 4c 00 ba 00 D.F.G.H.J.K.L...
e16ef068 de 00 c0 00 a0 00 dc 00-5a 00 58 00 43 00 56 00 ........Z.X.C.V.
e16ef078 42 00 4e 00 4d 00 bc 00-be 00 bf 00 a1 01 6a 02 B.N.M.........j.
e16ef088 a4 00 20 00 14 00 70 00-71 00 72 00 73 00 74 00 .. ...p.q.r.s.t.
1: kd> db 0xe16ef018+80
e16ef098 75 00 76 00 77 00 78 00-79 00 90 03 91 02 24 0c u.v.w.x.y.....$.
e16ef0a8 26 0c 21 0c 6d 00 25 0c-0c 0c 27 0c 6b 00 23 0c &.!.m.%...'.k.#.
e16ef0b8 28 0c 22 0c 2d 0c 2e 0c-2c 00 ff 00 e2 00 7a 00 (.".-...,.....z.
e16ef0c8 7b 00 0c 00 ee 00 f1 00-ea 00 f9 00 f5 00 f3 00 {...............
e16ef0d8 ff 00 ff 00 fb 00 2f 00-7c 00 7d 00 7e 00 7f 00 ....../.|.}.~...
e16ef0e8 80 00 81 00 82 00 83 00-84 00 85 00 86 00 ed 00 ................
e16ef0f8 ff 00 e9 00 ff 00 c1 00-ff 00 ff 00 87 00 ff 00 ................
e16ef108 ff 00 ff 00 ff 00 eb 00-09 00 ff 00 c2 00 00 00 ................
ff 00 1b 00 31 00 32 00-33 00 34 00 35 00 36 00
37 00 38 00 39 00 30 00-bd 00 bb 00 08 00 09 00
51 00 57 00 45 00 52 00-54 00 59 00 55 00 49 00
4f 00 50 00 db 00 dd 00-0d 00 a2 00 41 00 53 00
44 00 46 00 47 00 48 00-4a 00 4b 00 4c 00 ba 00
de 00 c0 00 a0 00 dc 00-5a 00 58 00 43 00 56 00
42 00 4e 00 4d 00 bc 00-be 00 bf 00 a1 01 6a 02
a4 00 20 00 14 00 70 00-71 00 72 00 73 00 74 00
75 00 76 00 77 00 78 00-79 00 90 03 91 02 24 0c
26 0c 21 0c 6d 00 25 0c-0c 0c 27 0c 6b 00 23 0c
28 0c 22 0c 2d 0c 2e 0c-2c 00 ff 00 e2 00 7a 00
7b 00 0c 00 ee 00 f1 00-ea 00 f9 00 f5 00 f3 00
ff 00 ff 00 fb 00 2f 00-7c 00 7d 00 7e 00 7f 00
80 00 81 00 82 00 83 00-84 00 85 00 86 00 ed 00
ff 00 e9 00 ff 00 c1 00-ff 00 ff 00 87 00 ff 00
ff 00 ff 00 ff 00 eb 00-09 00 ff 00 c2 00 00 00
#define VK_UNKNOWN 0xFF
/*
* Initialize as an unknown VK (unrecognised scancode)
*/
pke->usFlaggedVk = usVKey = VK_UNKNOWN;
1: kd> dv
pke = 0xf75d698c
bPrefix = 0x00 ''
afKeyState = 0xbfa70f20 ""
fVkPause = 0n0
usVKey = 7
1: kd> dx -id 0,0,8960a020 -r1 ((win32k!tagKE *)0xf75d698c)
((win32k!tagKE *)0xf75d698c) : 0xf75d698c [Type: tagKE *]
[+0x000] bScanCode : 0x7 [Type: unsigned char]
[+0x000] wchInjected : 0x8a07 [Type: unsigned short]
[+0x002] usFlaggedVk : 0xff [Type: unsigned short]
[+0x004] dwTime : 0xf75d69a4 [Type: unsigned long]
[+0x008] hDevice : 0x10063 [Type: void *]
[+0x00c] data [Type: _KEYBOARD_INPUT_DATA]
if (gptiForeground->spklActive) {
pKbdTbl = gptiForeground->spklActive->spkf->pKbdTbl;
usVKey = pKbdTbl->pusVSCtoVK[pke->bScanCode]; 关键一步: eax=00000036
usVKey = pKbdTbl->pusVSCtoVK[pke->bScanCode];
1: kd> p
eax=00000036 ebx=f75d698c ecx=00000007 edx=00000200 esi=bfa05c0c edi=bfa05c3c
eip=bf890311 esp=f75d695c ebp=f75d696c iopl=0 nv up ei ng nz ac pe cy
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000297
win32k!VKFromVSC+0xc1:
bf890311 6685c0 test ax,ax
pke->usFlaggedVk = usVKey;
return (BYTE)usVKey;
}
1: kd> dx -id 0,0,8960a020 -r1 ((win32k!tagKE *)0xf75d698c)
((win32k!tagKE *)0xf75d698c) : 0xf75d698c [Type: tagKE *]
[+0x000] bScanCode : 0x7 [Type: unsigned char]
[+0x000] wchInjected : 0x8a07 [Type: unsigned short]
[+0x002] usFlaggedVk : 0x36 [Type: unsigned short]
[+0x004] dwTime : 0xf75d69a4 [Type: unsigned long]
[+0x008] hDevice : 0x10063 [Type: void *]
[+0x00c] data [Type: _KEYBOARD_INPUT_DATA]
返回到:
VOID ProcessKeyboardInputWorker(
PKEYBOARD_INPUT_DATA pkei,
#ifdef GENERIC_INPUT
PDEVICEINFO pDeviceInfo,
#endif
BOOL fProcessRemap)
{
if (pkei->Flags & KEY_BREAK) {
ke.usFlaggedVk |= KBDBREAK; //最重要的一步:加上KBDBREAK标志0x8000,说明是key_up
}
参考:
1: kd> dv pkei
pkei = 0xe1418ab8
1: kd> dx -id 0,0,8960a020 -r1 ((win32k!_KEYBOARD_INPUT_DATA *)0xe1418ab8)
((win32k!_KEYBOARD_INPUT_DATA *)0xe1418ab8) : 0xe1418ab8 [Type: _KEYBOARD_INPUT_DATA *]
[+0x000] UnitId : 0x0 [Type: unsigned short]
[+0x002] MakeCode : 0x7 [Type: unsigned short]
[+0x004] Flags : 0x1 [Type: unsigned short]
[+0x006] Reserved : 0x0 [Type: unsigned short]
[+0x008] ExtraInformation : 0x0 [Type: unsigned long]
参考:
1: kd> p
eax=00000036 ebx=e1418ab8 ecx=00000007 edx=00000200 esi=00008000 edi=00000000
eip=bf8e96ae esp=f75d6980 ebp=f75d69a4 iopl=0 nv up ei pl nz na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000206
win32k!ProcessKeyboardInputWorker+0x139:
bf8e96ae f6430401 test byte ptr [ebx+4],1 ds:0023:e1418abc=01
1: kd> p
eax=00000036 ebx=e1418ab8 ecx=00000007 edx=00000200 esi=00008000 edi=00000000
eip=bf8e96b4 esp=f75d6980 ebp=f75d69a4 iopl=0 nv up ei pl nz na po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000202
win32k!ProcessKeyboardInputWorker+0x13f:
bf8e96b4 660975ea or word ptr [ebp-16h],si ss:0010:f75d698e=0036
1: kd> dx -id 0,0,8960a020 -r1 (*((win32k!tagKE *)0xf75d698c))
(*((win32k!tagKE *)0xf75d698c)) [Type: tagKE]
[+0x000] bScanCode : 0x7 [Type: unsigned char]
[+0x000] wchInjected : 0x8a07 [Type: unsigned short]
[+0x002] usFlaggedVk : 0x36 [Type: unsigned short]
[+0x004] dwTime : 0xf75d69a4 [Type: unsigned long]
[+0x008] hDevice : 0x10063 [Type: void *]
[+0x00c] data [Type: _KEYBOARD_INPUT_DATA]
or上0x8000后:
1: kd> dv
pkei = 0xe1418a00
pDeviceInfo = 0x36418a48
fProcessRemap = 0n1
Vk = 0x36 '6'
bPrefix = 0x00 ''
ke = struct tagKE
1: kd> dx -id 0,0,8960a020 -r1 (*((win32k!tagKE *)0xf75d698c))
(*((win32k!tagKE *)0xf75d698c)) [Type: tagKE]
[+0x000] bScanCode : 0x7 [Type: unsigned char]
[+0x000] wchInjected : 0x8a07 [Type: unsigned short]
[+0x002] usFlaggedVk : 0x8036 [Type: unsigned short]
[+0x004] dwTime : 0xf75d69a4 [Type: unsigned long]
[+0x008] hDevice : 0x10063 [Type: void *]
[+0x00c] data [Type: _KEYBOARD_INPUT_DATA]
//
// Keep track of real modifier key state. Conveniently, the values for
// VK_LSHIFT, VK_RSHIFT, VK_LCONTROL, VK_RCONTROL, VK_LMENU and
// VK_RMENU are contiguous. We'll construct a bit field to keep track
// of the current modifier key state. If a bit is set, the corresponding
// modifier key is down. The bit field has the following format:
//
// +---------------------------------------------------+
// | Right | Left | Right | Left | Right | Left |
// | Alt | Alt | Control | Control | Shift | Shift |
// +---------------------------------------------------+
// 5 4 3 2 1 0 Bit
//
// Add bit 7 -- VK_RWIN
// bit 6 -- VK_LWIN
switch (Vk) {
case VK_LSHIFT:
case VK_RSHIFT:
case VK_LCONTROL:
case VK_RCONTROL:
case VK_LMENU:
case VK_RMENU:
gCurrentModifierBit = 1 << (Vk & 0xf);
break;
case VK_LWIN:
gCurrentModifierBit = 0x40;
break;
case VK_RWIN:
gCurrentModifierBit = 0x80;
break;
default:
gCurrentModifierBit = 0;
}
if (gCurrentModifierBit) {
/*
* If this is a break of a modifier key then clear the bit value.
* Otherwise, set it.
*/
if (pkei->Flags & KEY_BREAK) {
gPhysModifierState &= ~gCurrentModifierBit;
} else {
gPhysModifierState |= gCurrentModifierBit;
}
}
#define VK_LSHIFT 0xA0
#define VK_RSHIFT 0xA1
#define VK_LCONTROL 0xA2
#define VK_RCONTROL 0xA3
#define VK_LMENU 0xA4
#define VK_RMENU 0xA5
#define ACCF_ACCESSENABLED 0x00000100
#define TEST_ACCF(f) TEST_FLAG(gdwPUDFlags, f)
1: kd> x win32k!gdwPUDFlags
bfa52fc0 win32k!gdwPUDFlags = 0x1684100
if (AccessProceduresStream(&ke, pkei->ExtraInformation, 0)) {
xxxProcessKeyEvent(&ke, (ULONG_PTR)pkei->ExtraInformation,
pkei->Flags & KEY_TERMSRV_SHADOW ? TRUE : FALSE);
}
/***************************************************************************\
* AccessProceduresStream
*
* This function controls the order in which the access functions are called.
* All key events pass through this routine. If an access function returns
* FALSE then none of the other access functions in the stream are called.
* This routine is called initially from KeyboardApcProcedure(), but then
* can be called any number of times by the access functions as they process
* the current key event or add more key events.
*
* Return value:
* TRUE All access functions returned TRUE, the key event can be
* processed.
* FALSE An access function returned FALSE, the key event should be
* discarded.
*
* History:
* 11 Feb 93 GregoryW Created.
\***************************************************************************/
BOOL AccessProceduresStream(PKE pKeyEvent, ULONG ExtraInformation, int dwProcIndex)
{
int index;
CheckCritIn();
for (index = dwProcIndex; index < ARRAY_SIZE(aAccessibilityProc); index++) {
if (!aAccessibilityProc[index](pKeyEvent, ExtraInformation, index+1)) {
return FALSE;
}
}
return TRUE;
}
1: kd> x win32k!aAccessibilityProc
bfa03ac8 win32k!aAccessibilityProc = <function> *[5]
1: kd> dx -id 0,0,8960a020 -r1 (*((win32k!int (*(*)[5])(tagKE *,unsigned long,int))0xbfa03ac8))
(*((win32k!int (*(*)[5])(tagKE *,unsigned long,int))0xbfa03ac8)) [Type: int (* [5])(tagKE *,unsigned long,int)]
[0] : 0xbf8ec264 [Type: int (*)(tagKE *,unsigned long,int)]
[1] : 0xbf8eb95f [Type: int (*)(tagKE *,unsigned long,int)]
[2] : 0xbf8ebc51 [Type: int (*)(tagKE *,unsigned long,int)]
[3] : 0xbf8ec324 [Type: int (*)(tagKE *,unsigned long,int)]
[4] : 0xbf8ec5aa [Type: int (*)(tagKE *,unsigned long,int)]
1: kd> u bf8ec264
win32k!HighContrastHotKey [d:\srv03rtm\windows\core\ntuser\kernel\access.c @ 1788]:
bf8ec264 55 push ebp
bf8ec265 8bec mov ebp,esp
bf8ec267 53 push ebx
bf8ec268 e8b01afcff call win32k!_AssertCritIn (bf8add1d)
bf8ec26d 0fb6152014a7bf movzx edx,byte ptr [win32k!gLatchBits (bfa71420)]
bf8ec274 0fb60d2314a7bf movzx ecx,byte ptr [win32k!gPhysModifierState (bfa71423)]
bf8ec27b 8b4508 mov eax,dword ptr [ebp+8]
bf8ec27e 8a5802 mov bl,byte ptr [eax+2]
1: kd> u bf8eb95f
win32k!FilterKeys [d:\srv03rtm\windows\core\ntuser\kernel\access.c @ 480]:
bf8eb95f 55 push ebp
bf8eb960 8bec mov ebp,esp
bf8eb962 53 push ebx
bf8eb963 56 push esi
bf8eb964 57 push edi
bf8eb965 e8b323fcff call win32k!_AssertCritIn (bf8add1d)
bf8eb96a 8b7508 mov esi,dword ptr [ebp+8]
bf8eb96d 8a4e02 mov cl,byte ptr [esi+2]
1: kd> u bf8ebc51
win32k!xxxStickyKeys [d:\srv03rtm\windows\core\ntuser\kernel\access.c @ 724]:
bf8ebc51 55 push ebp
bf8ebc52 8bec mov ebp,esp
bf8ebc54 51 push ecx
bf8ebc55 a10814a7bf mov eax,dword ptr [win32k!grpdeskRitInput (bfa71408)]
bf8ebc5a 8b4010 mov eax,dword ptr [eax+10h]
bf8ebc5d 8b400c mov eax,dword ptr [eax+0Ch]
bf8ebc60 53 push ebx
bf8ebc61 56 push esi
1: kd> u bf8ec324
win32k!MouseKeys [d:\srv03rtm\windows\core\ntuser\kernel\access.c @ 1857]:
bf8ec324 55 push ebp
bf8ec325 8bec mov ebp,esp
bf8ec327 53 push ebx
bf8ec328 56 push esi
bf8ec329 e8ef19fcff call win32k!_AssertCritIn (bf8add1d)
bf8ec32e 0fb6052014a7bf movzx eax,byte ptr [win32k!gLatchBits (bfa71420)]
bf8ec335 8b4d08 mov ecx,dword ptr [ebp+8]
bf8ec338 0fb6152314a7bf movzx edx,byte ptr [win32k!gPhysModifierState (bfa71423)]
1: kd> u bf8ec5aa
win32k!ToggleKeys [d:\srv03rtm\windows\core\ntuser\kernel\access.c @ 2167]:
bf8ec5aa 55 push ebp
bf8ec5ab 8bec mov ebp,esp
bf8ec5ad 53 push ebx
bf8ec5ae 56 push esi
bf8ec5af 57 push edi
bf8ec5b0 e86817fcff call win32k!_AssertCritIn (bf8add1d)
bf8ec5b5 8b4508 mov eax,dword ptr [ebp+8]
bf8ec5b8 8a4802 mov cl,byte ptr [eax+2]
1: kd> kc
#
00 win32k!xxxProcessKeyEvent
01 win32k!ProcessKeyboardInputWorker
02 win32k!ProcessKeyboardInput
03 win32k!InputApc
04 nt!KiDeliverApc
05 nt!KiSwapThread
06 nt!KeWaitForMultipleObjects
07 win32k!RawInputThread
08 win32k!xxxCreateSystemThreads
09 win32k!NtUserCallOneParam
0a nt!_KiSystemService
0b SharedUserData!SystemCallStub
0c winsrv!NtUserCallOneParam
1: kd> dv
pke = 0xf75d698c
ExtraInformation = 0
bInjected = 0n0
Vk = 0x8c ''
1: kd> dx -id 0,0,8960a020 -r1 ((win32k!tagKE *)0xf75d698c)
((win32k!tagKE *)0xf75d698c) : 0xf75d698c [Type: tagKE *]
[+0x000] bScanCode : 0x7 [Type: unsigned char]
[+0x000] wchInjected : 0x8a07 [Type: unsigned short]
[+0x002] usFlaggedVk : 0x8036 [Type: unsigned short]
[+0x004] dwTime : 0xf75d69a4 [Type: unsigned long]
[+0x008] hDevice : 0x10063 [Type: void *]
[+0x00c] data [Type: _KEYBOARD_INPUT_DATA]
