HID.DLL导出函数HidD_GetInputReport探究

本文解析了HidD_GetInputReport函数在ReactOS中的应用和内核实现过程,涉及IOCTL_HID_GET_INPUT_REPORT的底层操作,以及如何在hidclass.sys中追踪实际处理。重点介绍了HidpMajorHandler回调函数和hidusb驱动中的处理流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值