⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jiurl键盘驱动 4.htm

📁 JIURL键盘驱动
💻 HTM
📖 第 1 页 / 共 5 页
字号:
      DeviceName ,调用时不为空,说明这个设备对象有名字。在我这里这个名字是 
      "\Device\KeyboardClass0"。<BR><BR>调用 ExAllocatePool 为 kbdclass 
      的输入数据队列分配内存,分配内存的大小为 
      deviceExtension-&gt;KeyboardAttributes.InputDataQueueLength。而 
      deviceExtension-&gt;KeyboardAttributes.InputDataQueueLength 是由 
      Globals.InitExtension.KeyboardAttributes.InputDataQueueLength 赋值的。而 
      Globals.InitExtension.KeyboardAttributes.InputDataQueueLength 是在 kbdclass 
      的 DriverEntry 中初始化的。即读取注册表 
      HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Kbdclass\Parameters\KeyboardDataQueueSize 
      ,然后乘以 sizeof(KEYBOARD_INPUT_DATA)。<BR><BR>deviceExtension-&gt;InputData 
      保存申请空间的首地址。<BR>然后调用 
      KbdInitializeDataQueue,初始化,&nbsp;<BR>deviceExtension-&gt;InputCount = 
      0;<BR>deviceExtension-&gt;DataIn = 
      deviceExtension-&gt;InputData;<BR>deviceExtension-&gt;DataOut = 
      deviceExtension-&gt;InputData;<BR>也就是开始的时候,DataIn,DataOut 
      都指向输入数据队列的开头。<BR><BR>调用 IoAttachDeviceToDeviceStack 将产生的 kbdclass 
      的设备对象放入键盘设备栈。现在键盘设备栈就已经连接完了。<BR><BR>kbdclass!KbdSendConnectRequest 以一个 
      CONNECT_DATA ,IOCTL_INTERNAL_KEYBOARD_CONNECT 为参数调用 
      IoBuildDeviceIoControlRequest,创建一个 IRP_MJ_INTERNAL_DEVICE_CONTROL 的 IRP 
      ,调用 IoCallDriver 传给 i8024prt。这个 CONNECT_DATA 中有kbdclass处理输入数据的回调函数 
      kbdclass!KeyboardClassServiceCallback 的地址。IoCallDriver 根据这个 IRP ,调用 
      i8042prt!I8xInternalDeviceControl。在 i8042prt!I8xInternalDeviceControl 
      中会把这个 CONNECT_DATA 保存在 kbExtension-&gt;ConnectData 
      中。这样,以后i8042prt得到了按键的数据以后,就可以调用kbdclass指定的这个回调函数,让 kbdclass 
      作出处理。这里i8042prt!I8xInternalDeviceControl 处理 
      IOCTL_INTERNAL_KEYBOARD_CONNECT 
      的部分,还早在这时就给上一层一个设置hook机会,如果在这时设置hook,可能会对初始化的某些过程hoot,不过 kbdclass 
      对此没有处理。<BR><BR>[IRP_MJ_PNP IRP_MN_QUERY_LEGACY_BUS_INFORMATION]<BR><BR># 
      ChildEBP RetAddr Args to Child&nbsp;<BR>00 f901f638 8041f54b fe4f5df0 
      fe4fea08 fe4f5df0 kbdclass!KeyboardPnP(struct _DEVICE_OBJECT * 
      DeviceObject = 0xfe4f5df0, struct _IRP * Irp = 0xfe4fea08) (CONV: 
      stdcall)<BR>01 f901f64c 8049cb91 f901f6bc fe4dd730 fe4fedc0 
      nt!IopfCallDriver+0x35 (FPO: [0,0,2])<BR>02 f901f678 8048f328 fe4f5df0 
      f901f698 f901f6c4 nt!IopSynchronousCall+0xca (FPO: [Non-Fpo])<BR>03 
      f901f6bc 804a4bd1 fe4dd730 00000000 fe4fedc0 
      nt!IopQueryLegacyBusInformation+0x2c (FPO: [Non-Fpo])<BR>04 f901f77c 
      8054f1bb 80000048 00000005 f901f800 nt!IopCallDriverAddDevice+0x634 (FPO: 
      [Non-Fpo])<BR>05 f901f798 804e504e fe4fed68 f901f864 fe4d6368 
      nt!IopProcessAddDevicesWorker+0x6c (FPO: [2,0,3])<BR>06 f901f7a8 8054f184 
      fe4d6368 8054f147 f901f864 nt!IopForAllChildDeviceNodes+0x1f (FPO: 
      [3,0,1])<BR>07 f901f7c4 804e504e fe4d6368 f901f864 fe4e7c28 
      nt!IopProcessAddDevicesWorker+0x3d (FPO: [2,0,3])<BR>08 f901f7d4 8054f184 
      fe4e7c28 8054f147 f901f864 nt!IopForAllChildDeviceNodes+0x1f (FPO: 
      [3,0,1])<BR>09 f901f7f0 804e504e fe4e7c28 f901f864 fe5181a8 
      nt!IopProcessAddDevicesWorker+0x3d (FPO: [2,0,3])<BR>0a f901f800 8054f184 
      fe5181a8 8054f147 f901f864 nt!IopForAllChildDeviceNodes+0x1f (FPO: 
      [3,0,1])<BR>0b f901f81c 804e504e fe5181a8 f901f864 fe51b5e8 
      nt!IopProcessAddDevicesWorker+0x3d (FPO: [2,0,3])<BR>0c f901f82c 8054f184 
      fe51b5e8 8054f147 f901f864 nt!IopForAllChildDeviceNodes+0x1f (FPO: 
      [3,0,1])<BR>0d f901f848 8054f114 fe51b5e8 f901f864 00000003 
      nt!IopProcessAddDevicesWorker+0x3d (FPO: [2,0,3])<BR>0e f901f86c 8054dfdf 
      fe51baa8 0000ffff 00000003 nt!IopProcessAddDevices+0x59 (FPO: 
      [Non-Fpo])<BR>0f f901f8c0 8054c5c9 00000000 00000032 00000000 
      nt!IopInitializeSystemDrivers+0x25 (FPO: [Non-Fpo])<BR>10 f901fa58 
      8054b35a 80087000 00000000 00000000 nt!IoInitSystem+0x644 (FPO: 
      [Non-Fpo])<BR>11 f901fda8 804524f6 80087000 00000000 00000000 
      nt!Phase1Initialization+0x71b (FPO: [Non-Fpo])<BR>12 f901fddc 80465b62 
      8054aca6 80087000 00000000 nt!PspSystemThreadStartup+0x69 (FPO: 
      [Non-Fpo])<BR>13 00000000 00000000 00000000 00000000 00000000 
      nt!KiThreadStartup+0x16<BR><BR>IO 管理器向键盘设备栈发 IRP_MJ_PNP 
      IRP_MN_QUERY_LEGACY_BUS_INFORMATION 的 IRP。<BR><BR>这将导致 
      kbdclass!KeyboardPnP 被执行,我们从 kbdclass!KeyboardPnP 的传入参数 Irp 可以知道,这个 IRP 
      是哪种 IRP。<BR><BR>kbdclass 和 i8042prt 对 IRP_MJ_PNP 
      IRP_MN_QUERY_LEGACY_BUS_INFORMATION 的 IRP 
      都没有处理,向下传。<BR><BR><BR>[IRP_MJ_PNP 
      IRP_MN_FILTER_RESOURCE_REQUIREMENTS]<BR><BR># ChildEBP RetAddr Args to 
      Child&nbsp;<BR>00 f901f6f4 8041f54b fe4f5df0 fe4fea08 fe4f5df0 
      kbdclass!KeyboardPnP(struct _DEVICE_OBJECT * DeviceObject = 0xfe4f5df0, 
      struct _IRP * Irp = 0xfe4fea08)+0x9 (CONV: stdcall)<BR>01 f901f708 
      8048f468 e12bf298 fe4fed68 f901f7c0 nt!IopfCallDriver+0x35 (FPO: 
      [0,0,2])<BR>02 f901f734 8048f2dc fe4f5df0 e12b4ee8 f901f794 
      nt!IopFilterResourceRequirementsCall+0xdb (FPO: [Non-Fpo])<BR>03 f901f79c 
      8048dff9 fe4dd730 e12b4ee8 e12bf201 nt!IopQueryDeviceResources+0x211 (FPO: 
      [Non-Fpo])<BR>04 f901f7d0 8048df26 e12bf288 e12bf5c4 f901f7f8 
      nt!IopGetResourceRequirementsForAssignTable+0xc6 (FPO: [Non-Fpo])<BR>05 
      f901f800 8048f0ac f901f84c f901f850 00000000 nt!IopAllocateResources+0xa0 
      (FPO: [Non-Fpo])<BR>06 f901f844 8048edf6 00000017 e12bf288 00000001 
      nt!IopAssignResourcesToDevices+0xd9 (FPO: [Non-Fpo])<BR>07 f901f86c 
      8054e005 fe51baa8 00000000 00000001 nt!IopProcessAssignResources+0xe8 
      (FPO: [Non-Fpo])<BR>08 f901f8c0 8054c5c9 00000000 00000032 00000000 
      nt!IopInitializeSystemDrivers+0x4b (FPO: [Non-Fpo])<BR>09 f901fa58 
      8054b35a 80087000 00000000 00000000 nt!IoInitSystem+0x644 (FPO: 
      [Non-Fpo])<BR>0a f901fda8 804524f6 80087000 00000000 00000000 
      nt!Phase1Initialization+0x71b (FPO: [Non-Fpo])<BR>0b f901fddc 80465b62 
      8054aca6 80087000 00000000 nt!PspSystemThreadStartup+0x69 (FPO: 
      [Non-Fpo])<BR>0c 00000000 00000000 00000000 00000000 00000000 
      nt!KiThreadStartup+0x16<BR><BR>IO 管理器向键盘设备栈发 IRP_MJ_PNP 
      IRP_MN_FILTER_RESOURCE_REQUIREMENTS 的 IRP。<BR><BR>kbdclass!KeyboardPnP 对 
      IRP_MJ_PNP IRP_MN_FILTER_RESOURCE_REQUIREMENTS 没处理,向下传。<BR>i8042prt!I8xPnP 
      处理 IRP_MJ_PNP IRP_MN_FILTER_RESOURCE_REQUIREMENTS 的部分中,首先把这个 IRP 
      向下传。之后会调用函数 
      i8042prt!I8xFilterResourceRequirements。i8042prt!I8xFilterResourceRequirements中会把传入的端口信息保存在 
      Globals.ControllerData-&gt;KnownPorts 中,除此之外,没有作什么值得注意的处理。<BR><BR>DDK 
      中说,pnp管理器发 IRP_MN_FILTER_RESOURCE_REQUIREMENTS IRP 
      ,是给驱动一个调整和修改资源的一个机会。<BR><BR>我们来看一看系统打算给键盘驱动分配的资源。<BR><BR>使用 WinDbg 的 !irp 
      命令来查看传入 IRP。<BR><BR>kd&gt; !irp fe4fea08<BR>Irp is active with 6 stacks 6 
      is current (= 0xfe4feb2c)<BR>No Mdl Thread fe4f47e0: Irp stack 
      trace.&nbsp;<BR>cmd flg cl Device File Completion-Context<BR>[ 0, 0] 0 0 
      00000000 00000000 00000000-00000000&nbsp;<BR><BR>Args: 00000000 00000000 
      00000000 00000000<BR>[ 0, 0] 0 0 00000000 00000000 
      00000000-00000000&nbsp;<BR><BR>Args: 00000000 00000000 00000000 
      00000000<BR>[ 0, 0] 0 0 00000000 00000000 
      00000000-00000000&nbsp;<BR><BR>Args: 00000000 00000000 00000000 
      00000000<BR>[ 0, 0] 0 0 00000000 00000000 
      00000000-00000000&nbsp;<BR><BR>Args: 00000000 00000000 00000000 
      00000000<BR>[ 0, 0] 0 0 00000000 00000000 
      00000000-00000000&nbsp;<BR><BR>Args: 00000000 00000000 00000000 
      00000000<BR>&gt;[ 1b, d] 0 0 fe4f5df0 00000000 
      00000000-00000000&nbsp;<BR>\Driver\Kbdclass<BR>Args: e12b4ee8 00000000 
      00000000 00000000<BR><BR>看到当前 IO_STACK_LOCATION 的 MajorFunction 为 
      0x1b,MinorFunction 为 0xd。即 MajorFunction 为 IRP_MJ_PNP,MinorFunction 为 
      IRP_MN_FILTER_RESOURCE_REQUIREMENTS。<BR><BR>详细的看看当前的 IO_STACK_LOCATION 
      ,<BR><BR>kd&gt; !strct io_stack_location fe4feb2c<BR>struct 
      _IO_STACK_LOCATION (sizeof=36)<BR>+00 byte MajorFunction = 1b .<BR>+01 
      byte MinorFunction = 0d .<BR>+02 byte Flags = 00 .<BR>+03 byte Control = 
      00 .<BR>+04 union __unnamed19 Parameters<BR>+04 struct __unnamed42 
      FilterResourceRequirements<BR>+04 struct _IO_RESOURCE_REQUIREMENTS_LIST 
      *IoResourceRequirementList = E12B4EE8<BR>+14 struct _DEVICE_OBJECT 
      *DeviceObject = FE4F5DF0<BR>+18 struct _FILE_OBJECT *FileObject = 
      00000000<BR>+1c function *CompletionRoutine = 00000000<BR>+20 void 
      *Context = 00000000<BR><BR>传入了一个指向 IO_RESOURCE_REQUIREMENTS_LIST 
      结构的指针。<BR>我们使用 WinDbg 的 !ioreslist 看看这个 IO_RESOURCE_REQUIREMENTS_LIST 
      中的资源<BR><BR>kd&gt; !ioreslist e12b4ee8<BR>IoResList at 0xe12b4ee8 : 
      Interface 0xf Bus 0 Slot 0<BR>Reserved Values = {0x00000030, 0x00000201, 
      0x05000000}<BR>Alternative 0 (Version 1.1)<BR>Preferred Descriptor 0 - 
      NonArbitrated/ConfigData (0x80) Shared (0x3)<BR>Flags (0000) 
      -&nbsp;<BR>Data: : 0x1 0x5 0x180200<BR>Preferred Descriptor 1 - Port (0x1) 
      Device Exclusive (0x1)<BR>Flags (0x11) - PORT_IO 
      16_BIT_DECODE&nbsp;<BR>0x000001 byte range with alignment 0x000001<BR>60 - 
      0x60<BR>Preferred Descriptor 2 - Port (0x1) Device Exclusive 
      (0x1)<BR>Flags (0x11) - PORT_IO 16_BIT_DECODE&nbsp;<BR>0x000001 byte range 
      with alignment 0x000001<BR>64 - 0x64<BR>Preferred Descriptor 3 - Interrupt 
      (0x2) Device Exclusive (0x1)<BR>Flags (0x01) - LATCHED&nbsp;<BR>0x1 - 
      0x1<BR><BR>可以看到,系统打算给键盘驱动分配的资源有,两个端口,一个 
      0x60,一个0x64。一个中断,IRQ为1。<BR><BR>[IRP_MJ_PNP IRP_MN_START_DEVICE]<BR><BR># 
      ChildEBP RetAddr Args to Child&nbsp;<BR>00 f901f6a4 8041f54b fe4f5df0 
      fe4fea08 fe4f5df0 kbdclass!KeyboardPnP(struct _DEVICE_OBJECT * 
      DeviceObject = 0xfe4f5df0, struct _IRP * Irp = 0xfe4fea08)+0x9 (CONV: 
      stdcall)<BR>01 f901f6b8 8049cb91 00020000 fe4fed68 00000000 
      nt!IopfCallDriver+0x35 (FPO: [0,0,2])<BR>02 f901f6e4 804289ce fe4f5df0 
      f901f704 f901f72c nt!IopSynchronousCall+0xca (FPO: [Non-Fpo])<BR>03 
      f901f730 8048e06a fe4dd730 00000000 fe4fed68 nt!IopStartDevice+0x127 (FPO: 
      [Non-Fpo])<BR>04 f901f764 8048e040 fe4fed68 f901f88c 00000000 
      nt!IopStartAndEnumerateDevice+0x22 (FPO: [Non-Fpo])<BR>05 f901f784 
      804e504e fe4fed68 f901f88c fe4d6368 nt!IopProcessStartDevicesWorker+0x72 
      (FPO: [Non-Fpo])<BR>06 f901f794 804a4670 fe4d6368 804a4618 f901f88c 
      nt!IopForAllChildDeviceNodes+0x1f (FPO: [3,0,1])<BR>07 f901f7b8 804e504e 
      fe4d6368 f901f88c fe4e7c28 nt!IopProcessStartDevicesWorker+0x55 (FPO: 
      [Non-Fpo])<BR>08 f901f7c8 804a4670 fe4e7c28 804a4618 f901f88c 
      nt!IopForAllChildDeviceNodes+0x1f (FPO: [3,0,1])<BR>09 f901f7ec 804e504e 
      fe4e7c28 f901f88c fe5181a8 nt!IopProcessStartDevicesWorker+0x55 (FPO: 
      [Non-Fpo])<BR>0a f901f7fc 804a4670 fe5181a8 804a4618 f901f88c 
      nt!IopForAllChildDeviceNodes+0x1f (FPO: [3,0,1])<BR>0b f901f820 804e504e 
      fe5181a8 f901f88c fe51b5e8 nt!IopProcessStartDevicesWorker+0x55 (FPO: 
      [Non-Fpo])<BR>0c f901f830 804a4670 fe51b5e8 804a4618 f901f88c 
      nt!IopForAllChildDeviceNodes+0x1f (FPO: [3,0,1])<BR>0d f901f854 804a4607 
      fe51b5e8 f901f88c 00000003 nt!IopProcessStartDevicesWorker+0x55 (FPO: 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -