JIURL keyboard drive 2

zhaozj2021-02-16  53

JIURL keyboard driver 2 Author: JIURL Home: http://jiurl.yeah.net Date: 2003-12-13

2 Application Layer Basics Before discussing this issue using the keyboard, we first introduce some of the issues, applications, applications, and driver communications. 2.1 How the application uses CREATEFILE, READFILE, WRITEFILE, DEVICEIOCONTFILE, CloseHandle to indicate the driver to complete some task using the Drive Application. For example, we use readfile in your application to allow the driver to read hardware devices, we use WriteFile in your application to allow the drive to write hardware devices, we use DeviceIocontorl in your application to allow the driver to complete some drive support. READFILE, WRITEFILE, DEVICEIOCONTROL These three APIs require a handle as a parameter to determine which driver they want to complete their request. This handle is obtained by CreateFile. Use CloseHandle to close this handle. Simply put, in the application, first get a handle through the createfile, then the application can use this handle as a parameter, use readfile, writefile, and deviceioControl to perform some action. When it is no longer used, turn off this handle through CloseHandle. These APIs are located in kernel32.dll, which eventually calls the corresponding functions in the kernel through the system service (INT 2E), such as NTCREATEFILE, NTREADFILE, etc. NTCREATEFILE, NTREADFILE and other functions, an IRP is created, and this IRP is initialized with incoming parameters, and then the IRP is sent to the drive to proceed. The corresponding ntcreatefile generates IRP_MJ_CREATE IRP, NTREADFILE generates IRP of IRP_MJ_READ. Driven these IRPs, processed according to the situation, for IRP_MJ_READ, the part to process the IRP_MJ_READ in the drive can be called, which may last the operation of the reading hardware. 2.2 Getting the Handle of the Specified Drive For the driver that is used to be used by the application, in the initialization process, a SymbolicLink can be placed in the object manager namespace (Object Manager Namespace) during the initialization process. In this way, ".// That SymbolicLink's name" as the LPFileName parameter of CreateFile, call CREATEFILE, the handle you can find the corresponding driver (//. / will be converted into / ?? /). After using this handle as parameters, readfile, Writefile, DeviceIoControl, and generated IRPs are sent to the corresponding device object. That is to say, just drive the SymbolicLink of the device object to / ?? / down, and the application knows the name of this SymbolicLink, you can use createfile to get the appropriate handle.

HANDLE CreateFile (LPCTSTR lpFileName, // file nameDWORD dwDesiredAccess, // access modeDWORD dwShareMode, // share modeLPSECURITY_ATTRIBUTES lpSecurityAttributes, // SDDWORD dwCreationDisposition, // how to createDWORD dwFlagsAndAttributes, // file attributesHANDLE hTemplateFile // handle to template file); can Use tools WinObj to view object manager namespaces (Object Manager Namespace). WinObj can be obtained from http://www.sysinternals.com. About the detailed introduction of kernel objects and naming address space, you can refer to "JIURL Play Win2K Object", this article can be found on my homepage. In the initialization of the drive, the device object is created by calling IOCREATEVICE, you can specify a device name as the parameter of IOCREATEVICE (or may not be specified, such a device object has no name). This way this device object will be placed in Object Manager Namespace / Device. However, the application can only access the namespace / ?? /, so if the driver wants to expose the device object to the application, create a SymbolicLink to the device object is put on / ?? / For devices placed in / device / under, other drivers can use IOGETDEVICEOBJECTPOINTER to get pointers for this device object if you know its name. The driver can establish the SymbolicLink of the device object by IOCREATESYMBOLICLINK. This way the application must also know the name of the SymbolicLink, and then you can use createfile with this symbolic link name to get the handle. From IOCREATESYMBOLICLINK parameters, we can know that only SymbolicLink is established for device objects with named IOCREATESYMBOLICLINK. Another method is to use a GUID to identify a device interface. Drive uses the GUID for the identity device to call ioregisterDeviceInterface, then use iOSetDeviceInterfaceState, you will generate a symbolic link to the device object on / ?? / down. The application uses the same GUID to do parameters, using the API: SetupdiGetClassDevs, SetupdieNumDeviceInterfaces, setupdiGetDeviceInterfaceDetail, you can get the symbolic link name of the created / ?? / next, you can use createFile to use CreateFile with this symbolic link name to get the handle. Introduction to the handle. Each process has a handle table, a pointer to the kernel object in the handle, and the handle is the index of the kernel object in the handle. The pointer to the corresponding kernel object can be found in the handle of the process through the handle. For a detailed introduction of the handle, you can refer to "JIURL play WIN2K process threads handle_table", this article can be found on my homepage. 2.3 Some Conclusions The SymbolicLink object can find the appropriate device object. The address of the corresponding device object is saved in the SymbolicLink object. The device object does not save any information for its SymbolicLink object.

The address of the SymbolicLink object is saved in Object Manager Namespace. That is to say, just know the name of SymbolicLink, you can find it in the object manager namespace. The handle obtained by the application createfile, found in the process of the process, file object (File Object). Any information of this file object is not saved in the device object corresponding to the file object. Any information of this file object is not saved in the corresponding SymbolicLink object. The address of this file object is saved in the application's handle, and the application can find this file object through the handle. The address of the corresponding device object is saved in this file object. It can be guessed that the application will find the SymolicLink object according to the SymolicLink name in the parameter with CreateFile, and then find the address of the device object saved in the object, then save the address of the found device object in the file object. in. The 04 struct _Device_Object * DeviceObject of the file object is saved to save the address of the corresponding device object. For the driver that needs to be exposed to the application. First, the drive needs to create a SymbolicLink for the device object in / ?? / under /?, For the device object, regardless of the way it takes. After that, the application must know the name of this SymbolicLink, no matter what kind of way it takes. The application is then used as a ".// that symboliclink's name" to use createfile to get a handle using CreateFile. In this way, DeviceIocontrol (), WriteFile (), readfile () uses the handle you get with CreateFile as a parameter, they can find the corresponding file object, and the corresponding device object is saved in this file object. This allows IRP to these devices. The conclusion above is to observe a small example. 2.4 IRP will be the top IRP of the stack of the equipment stack will be sent to the top of the equipment stack. Createfile, Readfile, Writefile, DeviceioControl, CloseHandle. They will eventually generate an IRP and send it to an device object. For CreateFile, find a device object with the name of SymbolicLink. For other several functions, through the handle, find a file object, the pointer to the device object is saved in the file object. However, the generated IRP does not necessarily send the object object found, but the top of the top of the device object to which the device object is sent. And usually we are transmitted to the device objects found by the parameters of CreateFile, ReadFile, Writefile, DeviceIocontrol, and CloseHandle, which will be the PDO of its equipment stack (that is, its device object in the destination stack). CreateFile, ReadFile, Writefile, DeviceIocontrol, CloseHandle will first find the device object in the destination stack, and then turn the IRP to the top of the device of the device stack. So, regardless of the device object we find through the parameters in what location, top, middle, under, under the top, middle, bottom, no matter what location, IRP will send it to the stack of this equipment stack. The above content is discovered by tracking NT! NTCREATEFILE and NT! NTREADFILE. 2.5 nt! NTCREATEFILE Introduction We briefly introduce NT! NTCREATEFILE.

By a series of calls NT! NTCREATEFILE, will eventually call NT! IOPPARSEDEVICE. The Call Stack below shows this call. ... nt! IopParseDevice 0xa04nt! ObpLookupObjectName 0x4c4nt! ObOpenObjectByName 0xc5nt! IoCreateFile 0x3ecnt! NtCreateFile 0x2ent! KiSystemService 0xc4 ... in nt! IopParseDevice call nt! IoGetAttachedDevice, get the top of the device stack of device objects. Call IOAAllocateirp Create IRP. Call NT! OBCREATEOBJECT Create a file object. Initialize this file object. The 04 struct _Device_Object * DeviceObject assignment is the device object that is found by incoming parameters. Call NT! IOPFCALLLDRIVER, that is, IOCALLDRIVER, send IRP to the top of the stack of the device. After the drive is processed, return to NT! IOPPARSEDEVICE to continue execution. NT! Iopparsedevice Returns to NT! ObopenObjectByname. Continue to execute in NT! ObopenObjectByname, call NT! ObpCreateHandle Create a new handle in the process's handle, the object of this handle is the file object that just created initialized. 2.6 NT! NTREADFILE Introduction We briefly introduce NT! NTREADFILE. In the incoming parameter, there is a handle that opens the previous CreateFile, and a file object can be found in the process handle table, and the pointer to the object object is saved in this file object. Call the IOGETREDDEVICEOBJECT to get the device object of the device stack of this device object. Call IOAAllocateirp Create IRP. Initialize this IRP and set this IRP according to the incoming parameters. Then call IOCALLDRIVER to send this IRP to the device object and processes the drive. The object being sent to the device is an apparatus object that uses IoGetRelatedDeviceObject obtained by IOGETREDDEVICEOBJECT. The Call Stack below shows this call. ... NT! IOPFCALLDRIVER 0X35NT! IOPSYNCHRONSSERVICETAIL 0X60NT! NTREADFILE 0X5F4NT! KISYSTEMSERVICE 0XC4 ... 3 Keyboard Drive Application layer Which application is using keyboard driver? How did it use the keyboard drive? This is the problem that the keyboard drive is definitely encountered, and we will come now to discuss it. 3.1 Keyboard Drive User Keyboard Drive Users are thread win32k! Rawinputthread. The process of thread win32k! Rawinputthread is CSRSS.exe. I came first, I have seen this through Windbg! IRPFIND command. Later, when watching the keyboard driver, observe KBDClass! KEYBOARDCLASSREAD, KBDCLASS! KeyboardClassCreate's Call Stack also saw this. KBDClass! KeyboardClassCreate is the function of IRP_MJ_CREATE in the drive of the top device object of the keyboard device stack.

So when someone uses createfile to open a handle of a device object on the keyboard device, createFile will eventually send an IRP_MJ_CREATE IRP to the top of the keyboard device stack, which will cause kbdclass! KeyboardClassCreate called. So we step down on this function to see who is the call to this function. See who is to get the handle of the keyboard. At the end of the system initialization, interrupts occurred on KBDClass! KeyboardClassCreate and enters the debugger. First let's see who is currently the current thread.

! Kd> threadTHREAD fe42e5e0 Cid a0.bc Teb: 00000000 Win32Thread: e194a9e8 RUNNINGIRP List: fe43e9a8: (0006,0148) Flags: 00000884 Mdl: 00000000Not impersonatingOwning Process fe43b760Wait Start TickCount 5168 Elapsed Ticks: 0Context Switch Count 9 UserTime 0: 00: 00.0000 KernelTime 0: 00:!! 00.0250Start Address win32k RawInputThread (0xa000e7cd) Stack Init f90f0000 Current f90ef864 Base f90f0000 Limit f90ed000 Call 0Priority 19 BasePriority 13 PriorityDecrement 0 DecrementCount 0ChildEBP RetAddr Args to Childf90ef608 8041f54b fe4f5df0 fe43e9a8 fe43e9b8 kbdclass KeyboardClassCreatef90ef61c 804a3e54 804a392a fe4dd718 f90ef90c nt IopfCallDriver! 0x35f90ef7a4 8044e27e fe4dd730 00000000 f90ef850 nt! IopParseDevice 0xa04f90ef810 804957ae 00000000 f90ef900 00000000 nt! ObpLookupObjectName 0x4c4f90ef920 804a78b8 00000000 00000000 e18f5900 nt! ObOpenObjectByName 0xc5f90ef9f4 804a0c5b e197101c 00100001 f90efb14 nt! IoCreateFile 0x3ecf90efa34 80461691 e197101c 00100001 f90efb14 nt! NtCreateFile 0x2ef90efa34 80400 9d1 e197101c 00100001 f90efb14 nt! KiSystemService 0xc4f90efad8 a000e304 e197101c 00100001 f90efb14 nt! ZwCreateFile 0xbf90efb2c a000e192 e1971008 80400b46 00000001 win32k! OpenDevice 0x8ef90efb58 a000eb74 00000001 00000000 00000000 win32k! ProcessDeviceChanges 0x92f90efda8 804524f6 00000003 00000000 00000000 win32k! RawInputThread 0x463f90efddc 80465b62 a000e7cd f8d5f7d0 00000000 nt ! PspSystemThreadStartup 0x6900000000 f000ff53 f000e2c3 f000ff53 f000ff53 nt! KiThreadStartup 0x16f000ff53 00000000 00000000 00000000 00000000 0xf000ff53 see Start Address to win32k! RawInputThread. Description Thread Win32k! RawinputThread's handle of the keyboard through CreateFile. See the CID is A0.BC. Describe the process of the thread is A0. Let's take a look at who the A0 process is.

! Kd> process a0 0Searching for Process with Cid == a0PROCESS fe43b760 SessionId: 0 Cid: 00a0 Peb: 7ffdf000 ParentCid: 0090DirBase: 03642000 ObjectTable: fe43b6c8 TableSize: 53.Image: csrss.exe see Image a0 process is csrss.exe . KBDClass! KeyboardClassRead is the function of IRP_MJ_READ in the drive of the top device object of the keyboard device stack. So when someone uses readfile to request read data, the readfile will eventually send an IRP_MJ_READ's IRP to the top of the keyboard device stack, which will cause kbdclass! KeyboardClassRead being called. So we step down on this function to see who is the call to this function. See who is required to read data from the keyboard. After interruption occurs on KBDClass! KeyboardClassCreate, enter the debugger. Let's see who is currently the current thread. KD>! Threadthread fe42e5E0 CID A0.BC TEB: 00000000 Win32thread: E194A9E8 Running ... Start Address Win32k! Rawinputthread (0xA000E7CD) ... See start address for Win32k! Rawinputthread. Description Thread WIN32K! RAWINPUTTHREAD is required to read data from the keyboard via readfile. See the CID is A0.BC. Describe the process of thread or A0. These are enough to illustrate the user-driven user is thread win32k! Rawinputthread. The process of thread win32k! Rawinputthread is CSRSS.exe. 3.2 Win32k! Rawinputthread gets the handle Introduction Win32k! RawinputThread will call NT! ZwcreateFile, get a handle of PDO, which can find the keyboard device stack, for use after ZwreadFile, ZwdeviceIocontrolFile, etc. First we look at the Call Stack when you break in KBDClass! KeyboardClassCreate, see the entire calling process of kbdclass! Keys! KeyboardClassCreate.

! # ChildEBP RetAddr Args to Child 00 f90ef608 8041f54b fe4f5df0 fe43e9a8 fe43e9b8 kbdclass KeyboardClassCreate (struct _DEVICE_OBJECT * DeviceObject = 0xfe4f5df0, struct _IRP * Irp = 0xfe43e9a8) (CONV: stdcall) 01 f90ef61c 804a3e54 804a392a fe4dd718 f90ef90c nt IopfCallDriver 0x35 (FPO:! [ ! 0,0,2]) 02 f90ef7a4 8044e27e fe4dd730 00000000 f90ef850 nt IopParseDevice 0xa04 (FPO:! [Non-Fpo]) 03 f90ef810 804957ae 00000000 f90ef900 00000000 nt ObpLookupObjectName 0x4c4 (FPO: [Non-Fpo]) 04 f90ef920 804a78b8 00000000 00000000 e18f5900 nt ObOpenObjectByName 0xc5 (FPO: [Non-Fpo])!! 05 f90ef9f4 804a0c5b e197101c 00100001 f90efb14 nt IoCreateFile 0x3ec (FPO: [Non-Fpo])! 06 f90efa34 80461691 e197101c 00100001 f90efb14 nt NtCreateFile 0x2e (FPO : [Non-Fpo]) 07 f90efa34 804009d1 e197101c 00100001 f90efb14 nt KiSystemService 0xc4 (FPO:!! [0,0] TrapFrame @ f90efa68) 08 f90efad8 a000e304 e197101c 00100001 f90efb14 nt ZwCreateFile 0xb (FPO: [11,0,0 ]) 09 F90EFB2C A000E192 E1971008 80400B46 00000001 WIN32K! OpenDevice 0x8e (fPO: ! [Non-Fpo]) 0a f90efb58 a000eb74 00000001 00000000 00000000 win32k ProcessDeviceChanges 0x92 (FPO:! [EBP 0xf90efda8] [1,5,4]) 0b f90efda8 804524f6 00000003 00000000 00000000 win32k RawInputThread 0x463 (FPO: [Non-Fpo ]) 0c f90efddc 80465b62 a000e7cd f8d5f7d0 00000000 nt PspSystemThreadStartup 0x69 (FPO:!! [Non-Fpo]) 0d 00000000 f000ff53 f000e2c3 f000ff53 f000ff53 nt KiThreadStartup 0x16WARNING:. Frame IP not in any known module Following frames may be wrong.0e f000ff53 00000000 0000000000 00000000 00000000 0xf000FF53 I simplely followed the process of getting the handle of Win32k! Rawinputthread, I will make a simple introduction to this process.

Win32k! Rawinputthread Gets the PDO in the keyboard device stack through Guid_Class_Keyboard (simple PDO is the SymbolicLink "name of the device object of the device stack. Performed to Win32k! OpenDevice, one of its parameters can find the SymbolicLink name of the PDO of the keyboard device stack. Win32k! OpenDevice has a local variable of an Object_Attributes structure, which initializes this local variable, assigns the PUNICODE_STRING ObjectName at the Object_Attributes 0x8 with the keyboard device stack in the keyboard device stack in the incoming parameter. Then call zwcreatefile. ZwcreateFile completes the work of the handle, and finally returns the resulting handle by incoming parameters. Win32k! Rawinputthread saves the resulting handle, supplied back to ReadFile, DeviceIocontrol, etc. ZWCREATEFILE calls NTCReateFile in the kernel through the system service. NTCREATEFILE executes in NT! IOPPARSEDEVICE, call NT! IOGETATACHEDDEVICE, obtains the device object of the keyboard device stack through the PDO device object. Use the 30 char stacksize of the obtained device object as the parameter to IOAllocateIRP, create an IRP. Call NT! OBCREATEOBJECT Create a file object. Initialize this file object, 04 struct _device_object * deviceObject assigns PDO of the keyboard device stack. Call NT! IOPFCALLLDRIVER, send IRP to drive to proceed accordingly. Then a series of returns, returned to NT! ObopenObjectByname. Continue execution in NT! ObopenObjectByname, call NT! ObpCreateHandle Create a new handle in the handle of the process (CSRSS.exe), the object of this handle is the file object that just creates initialization, the DeviceObject in the file object points to the keyboard. PDO of the equipment stack. Before and after NT! ObpCreateHandle, we use commands! Handle 0 3 A0 (A0 for the process ID of the CSRSS.exe process), observe the front and rear changes of the CSRSS.exe process handle, and see the file objects that come out. 3.3 Win32k! RawinputThread How to get the button from the keyboard to get the button's data Win32k! RawinputThread After obtaining the handle, call NT! ZWREADFILE, call NT! ZWREADFILE, to the keyboard driver to read data. The nt! zwreadfile creates an IRP transmission keyboard driver in nt! zwreadfile, tells the keyboard driver to request read data. Keyboard drives usually make this IRP Pending (usually this, in detail, we discuss in keyboard drive parts). That is to say, IRP_MJ_READ will not be satisfied, it will always be placed there, waiting for data from the keyboard. The thread Win32k! Rawinputthread, which is sent to the request, will also wait, waiting for this reading.

The hit is destined, this IRP has emerged, and then uses it in their life, starting a quiet wait, and when it is waiting, it will have a hurry. Its life may be short, perhaps long, depending on what it will wait. What is it waiting for? It is waiting for you, press the key on the keyboard. Let me illustrate the source of keyboard data, the source of keyboard data is the keyboard. When there is a button on the keyboard being pressed, the object of the IRP_MJ_READ IRP wait for. When the keyboard is pressed, the interrupt of the keyboard is triggered, causing the execution of the interrupt service routine, and the interrupt service routine that the keyboard interrupt is provided by the keyboard driver. The keyboard drive reads the scan code from the port. After some columns, finally hand over the data obtained from the keyboard to the IRP and end this IRP. The end of this IRP will cause Win32k! RawinputThread threads to wait for this read operation. Win32k! RawinputThread thread will process the obtained data, distribute to the appropriate process. Once the input data is processed, the win32k! Rawinputthread thread will immediately call a NT! ZwReadFile, and the keyboard droves to read the data. So starting again, waiting for the key on the keyboard being pressed. Simply put, win32k! Rawinputthread thread is always NT! Zwreadfile requires read data. Then wait for the keys on the keyboard to be pressed. When the key on the keyboard is pressed, Win32k! RawinputThread processes the data obtained by NT! Zwreadfile, then NT! ZWREADFILE requires reading data, and then waits for the keys on the keyboard to be pressed. The content introduced above is when I see the keyboard drive for IRP_MJ_READ, in KBDClass! KeyboardClassRead, IRP does not get data, but by IomarkirPpending, I want to think about it, understand. I simply follow the process of getting the process from the keyboard to get button data from the keyboard, and I have a simple introduction to this process. First we look at the Call Stack when you break in KBDClass! KeyboardClassRead, see the entire calling process of kbdclass! KeyboardClassRead.

! # ChildEBP RetAddr Args to Child 00 f90ef8dc 8041f54b fe4f5df0 fe43e9a8 fe43e9a8 kbdclass KeyboardClassRead (struct _DEVICE_OBJECT * Device = 0xfe4f5df0, struct _IRP * Irp = 0xfe43e9a8) (CONV: stdcall) 01 f90ef8f0 804ba5e8 fe43eacc fe43e9a8 00000000 nt IopfCallDriver 0x35 (FPO:! [ 0,0,2]) 02 f90ef904 804a2d4c fe4f5df0 fe43e9a8 fe42d668 nt IopSynchronousServiceTail 0x60 (FPO:!! [Non-Fpo]) 03 f90ef9d8 80461691 000000d4 00000000 a005c962 nt NtReadFile 0x5f4 (FPO: [Non-Fpo]) 04 f90ef9d8 804011d5 ! 000000d4 00000000 a005c962 nt KiSystemService 0xc4 (FPO: [0,0] TrapFrame @ f90efa04) 05 f90efa74 a005c91d 000000d4 00000000 a005c962 nt ZwReadFile 0xb (FPO: [9,0,0])! 06 f90efaa8 a005c991 e1971008 fe43e9e8 80430982 win32k! StartDeviceRead 0x8c (FPO: [1,0,3]) 07 f90efab4 80430982 e1971008 e1971028 00000000 win32k InputApc 0x41 (FPO: [3,0,1])!! 08 f90efae8 80403a44 00000000 00000000 00000000 nt KiDeliverApc 0xdb (FPO: [NON-FPO]) 09 F90EFB08 8042D33D 80400B46 00000001 000000 NT! Kiswapthread 0xFC (FPO: [EBP 0xF90EFB3C !] [0,0,4]) 0a f90efb3c a000eaf5 00000004 fe42e5a8 00000001 nt KeWaitForMultipleObjects 0x266 (FPO:! [Non-Fpo]) 0b f90efda8 804524f6 00000002 00000000 00000000 win32k RawInputThread 0x3c2 (FPO: [Non-Fpo]) 0c ! f9dc 80465b62 a000e7cd f8d5f7d0 00000000 nt PspSystemThreadStartup 0x69 (FPO: [Non-Fpo])! 0d 00000000 f000ff53 f000e2c3 f000ff53 f000ff53 nt KiThreadStartup 0x16WARNING:. Frame IP not in any known module Following frames may be wrong.0e f000ff53 00000000 00000000 00000000 00000000 0xF000FF53 Thread Win32k! RawinputThread calls NT! Zwreadfile requires read data.

When we see a call; NTSTATUS ZwReadFile (IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER ByteOffset OPTIONAL, IN PULONG Key OPTIONAL) The parameter FileHandle is the handle obtained by Win32k! Rawinputthread with ZWCREATEFILE. The parameter APCROUTINE is the entry address of Win32k! InputAPC. That is to say, when ReadFile's IRP ends, Win32k! INPUTAPC will be called. ZwreadFile passes the system service, eventually calls NT! NTREADFILE. NT! NTREADFILE. The handle of the parameter is incorporated, corresponding to a file object, and the pointer to the device object of the PDO in the keyboard device stack is saved. Call the ObreferenceObjectbyHandle with this handle to get the file object corresponding to the handle. Then use the obtained file object to call IOGETREDDEVICEOBJECT, which will get the pointer to the top device object in the keyboard device stack. Use the NT! IOAllocateirp to call NT! IOAllocateIRP, constructed NT! IOAllocateIRP, constructed the IRP, and then initialize this IRP with incoming parameters. Then call IocallDriver and send this IRP to the keyboard drive. Keyboard drives typically call omarkirppending to make this IRP Pending. Usually, this is the case in detail We discuss in the keyboard drive section. So this IRP is waiting there. With regard to this waiting IRP, we can use Windbg! Irpfind commands to find it. In turn, this is explained, we use! Irpfind Why can I always see a pending's IRP for IRP_MJ_READ on the keyboard device stack top.

! Kd> irpfindunable to get large pool allocation table - either wrong symbols or pool tagging is disabledSearching NonPaged pool? (Fe313000: fe52b000) for Tag: Irp Irp [Thread] irpStack: (Mj, Mn) DevObj [Driver] ... fe439008 [FE427940] Irpstack: (3, 0) Fe4f5df0 [/ driver / kbdclass] ... This IRP address is Fe439008, let's take a look at its details KD>! Irp fe439008irp is active with 6 stacks 6 is current (= 0xfe43912c) ) No Mdl System buffer = fe426568 Thread fe427940: Irp stack trace cmd flg cl Device File Completion-Context [0, 0] 0 ​​0 00000000 00000000 00000000-00000000 Args:. 00000000 00000000 00000000 00000000 [0, 0] 0 ​​0 00000000 00000000 00000000 -00000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 [0, 0] 0 0 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011 ER / KBDClassArgs: 0000000078 00000000 0000000000 00000000 I saw this IRP PENDING. At this time, the thread Win32k! RawinputThread will wait on a NT! KewaitFormultiPleObjects, one of the objects waiting, wants to drive the IRP read from the keyboard. When the keyboard is pressed, the interrupt is initiated, causing the driver to read the scan code of the button from the port. Drive through a series of processes, finally calling IOCOMPLETEREQUEST to end the IRP waiting. The end of the IRP will make the thread win32k! Rawinputthread's waiting for the waiting for the data from the keyboard on NT! KewaitFormultipleObjects. This will make the incoming parameter APCROUTINE of ZwReadFile, is executed, and Win32K! InputAPC is executed. Win32k! InputApc. Call two functions, win32k! Processkeyboardinput, win32k! StartdevicRead. Win32k! ProcessKeyBoardInput is responsible for handling the input data just read, such as the process that is distributed to the keyboard button. After the data is processed, it is also the end of Win32k! ProcessKeyboardInput. Win32k! StartDeviceRead is called, Win32k! StartDeviceRead calls NT! ZWREADFILE to read data.

转载请注明原文地址:https://www.9cbs.com/read-26129.html

New Post(0)