我需要确定是否有使用USB键盘插入PC的硬件键盘记录器。它需要通过软件方法,从用户土地完成。但是wiki说使用soft检测HKL是不可能的,有几种方法存在。最好的,我认为只有一个与网络相关的概念是#34;检测硬件键盘记录,由Fabian Mihailowitsch撰写 - youtube"。
使用此概述我正在开发一种检测USB硬件键盘记录器的工具。用于检测PS / 2键盘记录器的源已经由作者共享且可用here。所以我的任务是让它只适用于USB。
正如我所建议的那样,我使用libusb库来干扰系统中的USB设备。
所以,我选择了一些方法来检测HKL:
根据检测步骤,下面是我的代码。
1。查找USB键盘
libusb_device * UsbKeyboard::GetSpecifiedDevice(PredicateType pred)
{
if (_usbDevices == nullptr) return nullptr;
int i = 0;
libusb_device *dev = nullptr;
while ((dev = _usbDevices[i++]) != NULL)
{
struct libusb_device_descriptor desc;
int r = libusb_get_device_descriptor(dev, &desc);
if (r >= 0)
{
if (pred(desc))
return dev;
}
}
return nullptr;
}
libusb_device * UsbKeyboard::FindKeyboard()
{
return GetSpecifiedDevice([&](libusb_device_descriptor &desc) {
bool isKeyboard = false;
auto dev_handle = libusb_open_device_with_vid_pid(_context, desc.idVendor, desc.idProduct);
if (dev_handle != nullptr)
{
unsigned char buf[255] = "";
// product description contains 'Keyboard', usually string is 'USB Keyboard'
if (libusb_get_string_descriptor_ascii(dev_handle, desc.iProduct, buf, sizeof(buf)) >= 0)
isKeyboard = strstr((char*)buf, "Keyboard") != nullptr;
libusb_close(dev_handle);
}
return isKeyboard;
});
}
在这里,我们重复遍历系统中的所有USB设备并检查其产品字符串。在我的系统中,这个用于键盘的字符串是' USB键盘' (明显)。 通过Product string检测键盘是否稳定?还有其他方法吗?
2。使用中断读取检测Keyghost HKL
int UsbKeyboard::DetectKeyghost(libusb_device *kbdev)
{
int r, i;
int transferred;
unsigned char answer[PACKET_INT_LEN];
unsigned char question[PACKET_INT_LEN];
for (i = 0; i < PACKET_INT_LEN; i++) question[i] = 0x40 + i;
libusb_device_handle *devh = nullptr;
if ((r = libusb_open(kbdev, &devh)) < 0)
{
ShowError("Error open device", r);
return r;
}
r = libusb_set_configuration(devh, 1);
if (r < 0)
{
ShowError("libusb_set_configuration error ", r);
goto out;
}
printf("Successfully set usb configuration 1\n");
r = libusb_claim_interface(devh, 0);
if (r < 0)
{
ShowError("libusb_claim_interface error ", r);
goto out;
}
r = libusb_interrupt_transfer(devh, 0x81 , answer, PACKET_INT_LEN,
&transferred, TIMEOUT);
if (r < 0)
{
ShowError("Interrupt read error ", r);
goto out;
}
if (transferred < PACKET_INT_LEN)
{
ShowError("Interrupt transfer short read %", r);
goto out;
}
for (i = 0; i < PACKET_INT_LEN; i++) {
if (i % 8 == 0)
printf("\n");
printf("%02x, %02x; ", question[i], answer[i]);
}
printf("\n");
out:
libusb_close(devh);
return 0;
}
我在libusb_interrupt_transfer上遇到了这样的错误:
libusb: error [hid_submit_bulk_transfer] HID transfer failed: [5] Access denied
Interrupt read error - Input/Output Error (LIBUSB_ERROR_IO) (GetLastError() - 1168)
不知道为什么&#39;访问被拒绝&#39;,然后IO错误,GetLastError()返回1168,这意味着 - 找不到元素(什么元素?)。在这里寻求帮助。
时间测量。发送输出报告并等待ACK数据包。
int UsbKeyboard :: SendOutputReport(libusb_device * kbdev) { const int PACKET_INT_LEN = 1; int r,i; unsigned char answer [PACKET_INT_LEN]; unsigned char question [PACKET_INT_LEN]; for(i = 0; i&lt; PACKET_INT_LEN; i ++)question [i] = 0x30 + i; for(i = 1; i&lt; PACKET_INT_LEN; i ++)answer [i] = 0;
libusb_device_handle *devh = nullptr;
if ((r = libusb_open(kbdev, &devh)) < 0)
{
ShowError("Error open device", r);
return r;
}
r = libusb_set_configuration(devh, 1);
if (r < 0)
{
ShowError("libusb_set_configuration error ", r);
goto out;
}
printf("Successfully set usb configuration 1\n");
r = libusb_claim_interface(devh, 0);
if (r < 0)
{
ShowError("libusb_claim_interface error ", r);
goto out;
}
printf("Successfully claim interface\n");
r = libusb_control_transfer(devh, CTRL_OUT, HID_SET_REPORT, (HID_REPORT_TYPE_OUTPUT << 8) | 0x00, 0, question, PACKET_INT_LEN, TIMEOUT);
if (r < 0) {
ShowError("Control Out error ", r);
goto out;
}
r = libusb_control_transfer(devh, CTRL_IN, HID_GET_REPORT, (HID_REPORT_TYPE_INPUT << 8) | 0x00, 0, answer, PACKET_INT_LEN, TIMEOUT);
if (r < 0) {
ShowError("Control In error ", r);
goto out;
}
出: libusb_close(devh); 返回0; }
与读取中断相同的错误: 控制输出错误 - 输入/输出错误(LIBUSB_ERROR_IO)(GetLastError() - 1168 )
如何解决?如何等待ACK数据包?
谢谢。
更新
我花了一天时间进行搜索和重新调整。所以目前我的问题只是
通过libusb_control_transfer发送输出报告。由于Windows拒绝使用ReadFile从USB设备读取访问权限,因此无需实现具有中断读取的第二种方法。
它只剩下libusb的东西,这是我想要编写的代码(来自第3个例子):
// sending Output report (LED)
// ...
unsigned char buf[65];
buf[0] = 1; // First byte is report number
buf[1] = 0x80;
r = libusb_control_transfer(devh, CTRL_OUT,
HID_SET_REPORT/*0x9*/, (HID_REPORT_TYPE_OUTPUT/*0x2*/ << 8) | 0x00,
0, buf, (uint16_t)2, 1000);
...
我遇到的错误:
[ 0.309018] [00001c0c] libusb: debug [_hid_set_report] Failed to Write HID Output Report: [1] Incorrect function
Control Out error - Input/Output Error (LIBUSB_ERROR_IO) (GetLastError() - 1168)
在libusb内部中 DeviceIoControl 调用后立即发生此错误。 什么意思&#34;不正确的功能&#34;那里?