资讯详情

HID.DLL导出函数HidD_GetInputReport探究

HidD_GetInputReport的功能

HidD_GetInputReport用于获取输入报告(input report)。

然而,微软对此函数有一个特殊的解释,即只能获得,无法连续获取,因为数据可能会丢失。因此,如果要连续获取输入报告,则需要使用它ReadFile函数。 同时,有些设备可能不支持HidD_GetInputReport,因此,使用此函数时可能没有响应。 更多详见:

  • https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/hidsdi/nf-hidsdi-hidd_getinputreport
  • https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/obtaining-hid-reports#obtaining-hid-reports-by-user-mode-applications

HidD_GetInputReport应用层

HidD_GetInputReport函数在ReactOS实现如下:

HIDAPI BOOLEAN WINAPI HidD_GetInputReport(IN HANDLE HidDeviceObject,                     IN OUT PVOID ReportBuffer,                     IN ULONG ReportBufferLength) {   DWORD RetLen;   return DeviceIoControl(HidDeviceObject, IOCTL_HID_GET_INPUT_REPORT,                          NULL, 0,                          ReportBuffer, ReportBufferLength,                          &RetLen, NULL) != 0; } 

源代码路径为:

E:\reactos\ReactOS-0.4.13-src-2020-0731\ReactOS-0.4.13\dll\win32\hid\hid.c 

可以看出,函数是通过的IOCTL_HID_GET_INPUT_REPORT实现了。因此,我们需要驱动核心hidclass检查驱动中内核的实现情况。

HidD_GetInputReport内核层

在最新的ReactOS其实这个IOCTL并未实现。

        case IOCTL_HID_GET_INPUT_REPORT:          {              DPRINT1("[HIDUSB] IOCTL_HID_GET_INPUT_REPORT not implemented \n");              ASSERT(FALSE);              Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;              IoCompleteRequest(Irp, IO_NO_INCREMENT);              return STATUS_NOT_IMPLEMENTED;          } 

不过,REACTOS未实现并不意味着windows因为reactos不是半成品工程。 所以既然已经知道这个函数是实现的hidclass.sys因此,需要一些特殊的方法。 这里结合IDA分析。 我们看过HidRegisterMinidriver了解原始源代码的源代码hidusb驱动的回调函数进行了HOOK,这应用层下发时IOCTL_HID_GET_INPUT_REPORT后,会进入HIDCLASS设置的回调函数名为:HidpMajorHandler。

#define IRP_MJ_DEVICE_CONTROL           0x0e ...       v20->MajorFunction[14] = (int (__fastcall *)(_DEVICE_OBJECT *, _IRP *))HidpMajorHandler; ... 

在其函数HidpMajorHandler继续跟踪内部

      case 14:         v15 = HidpIrpMajorDeviceControl(v8, v4, -1073741824, a4); 

所以HidpIrpMajorDeviceControl才是真实的IOCTL_HID_GET_INPUT_REPORT实现。 通过http://www.pnpon.com/import/ioctl.html 查询IOCTL_HID_GET_INPUT_REPORT的值为0xb01a2,故需要在HidpIrpMajorDeviceControl内部查找关于它的代码。 可见代码为:

         case 0xB0191u:  //IOCTL_HID_SET_FEATURE             case 0xB0192u:  //IOCTL_HID_GET_FEATURE             case 0xB0195u:  //IOCTL_HID_SET_OUTPUT_REPORT             case 0xB01A2u:  //IOCTL_HID_GET_INPUT_REPORT             case 0xB01A6u:  //               v12 = HidpGetSetReport(a1, v4, (unsigned int)v109[6], v108);               v105 = v12; 

在这个函数中,会做出一些必要的判断,然后调用hidusb中.

 v35 = HidpCallDriverSynchronous(*(_QWORD *)v8, v45); 

所以看,这还是进去了miniport设备中。 在hidusb其实就是下发IRP驱动到总线,然后获取输入报告的内容。当然,输入报告指针中的第一个字节是ReportID.

进入HIDUSB.SYS驱动后,它被执行HIDCLASS.SYS hook掉的ioctl对应的函数HumInternalIoctl。 在HumInternalIoctl找对应的IOCTL 0xB01A2u: 。。。

请查看后续部分:http://www.usbzh.com/article/detail-933.html

标签: 305v105kx2电容300v105jcbb电容

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台