HID 报告描述符(使用 iPhone)

发布于 2024-12-03 05:45:59 字数 3164 浏览 1 评论 0原文

我正在尝试通过蓝牙从 ubuntu 将击键发送到我的 iPhone4。 即开发一个非常原始的虚拟键盘。

问题 让我的应用程序与 iPhone 对话(即使用报告协议,这就是 iPhone 支持的所有协议)。事实上,我的 write(interruptChannelFD) 调用没有返回错误,但是 iPhone 端不显示任何文字。 l2cap 通道已使用 blueZ 库打开。

问题 1:鉴于不存在可以实现此功能的虚拟键盘,那么它有多难?

我正处于 iPhone 和我的 Linux 盒子连接并保持连接的阶段,没问题。 此外,所有 perror() 调用都告诉我控制和中断通道套接字连接得很好。 (我所做的是将我的加密狗 hciconfig 到键盘设备类并使用 Collin Mulliner 编写的著名代码,稍加修改 - 我必须输入一次密码,正如所有智能手机所要求的那样)。

问题 2:我应该能够直接 write() 写入中断套接字,而不必担心加密,对吧?我已输入密码并且手机信任键盘。 (Collin 正在考虑可能的 hid 攻击,但我诚实地连接)

另外,据我了解,在 HID 设备的启动协议中,确切的报告 描述符 SPD 中指定的内容几乎不相关——报告格式无论如何都是固定的。那么...

问题 3:我是否错过了有关报告协议的一些重要内容。 我所做的是修改Apple键盘报告描述符并写入 插入插座(见下文)。

const uint8_t hid_spec[] = { 
    0x05, 0x01, // usage page
    0x09, 0x06, // keyboard
    0xa1, 0x01, // collection (Application)
    0x85, 0x01, // report id (0x01)
    0x05, 0x07, // usage page(keyboard)
    0x19, 0xe0, // usage min
    0x29, 0xe7, // usage max
    0x15, 0x00, // logical min
    0x25, 0x01, // logical max
    0x75, 0x01, // report size
    0x95, 0x08, // report count
    0x81, 0x02, // input (dat var abs)

    0x75, 0x08, // report size 
    0x95, 0x01, // report count 
    0x81, 0x01, // input (const)

            // The following two outputs I don't seem to receive
    0x75, 0x01, // report size
    0x95, 0x05, // report count
    0x05, 0x08, // usage page (LEDs)
    0x19, 0x01, // usage min
    0x29, 0x05, // usage max 
    0x91, 0x02, // OUTPUT1 (dat var abs) 

    0x75, 0x03,
    0x95, 0x01,
    0x91, 0x01, // OUTPUT2 (arr,const) 

    0x75, 0x08, // report size
    0x95, 0x06, // report count
    0x15, 0x00, // logical min
    0x26, 0xff, 0x00 // logical max

    0x05, 0x07
    0x19, 0x00
    0x2a, 0xff, 0x00,
    0x81, 0x00,

            // A total of 9 bits sent by now
            // I tried remove the following fields
            /********** BEGIN SNIP
    0x75, 0x01,
    0x95, 0x01,
    0x15, 0x00,
    0x25, 0x01,

    0x05, 0x0c,
    0x09, 0xb8,
    0x81, 0x06,


    0x09, 0xe2,
    0x81, 0x06,


    0x09, 0xe9,
    0x81, 0x02,
    0x09, 0xea,
    0x81, 0x02,
    0x75, 0x01,
    0x95, 0x04,
    0x81, 0x01,
            **** END SNIP/

    0xc0         // end coll

};

之后,我将以下 10 个字节写入中断通道:

                    pkg[0] = 0xa1;   // BT HDR (DATA)
                    pkg[1] = 0x01;   // REPORT ID 0x1 == kbd
                    pkg[2] = modifiers; // Ctrl, Shift, etc
                    pkg[3] = 0x00;    // constant 0 (see descr)
                    // pkg[4] = 0x00; // the key code - entered before this point, according to HID usage tables.
                    pkg[5] = 0x00;
                    pkg[6] = 0x00;
                    pkg[7] = 0x00;
                    pkg[8] = 0x00;
                    pkg[9] = 0x00;

                    if (write(is, pkg, 10) <= 0) {
                        perror("write");
                        exit(-1);
                    }

I am trying to send keystrokes via bluetooth to my iPhone4 from ubuntu.
I.e., developing a very primitive virtual keyboard.

Problem Have my application talk to iPhone (i.e. using report protocol, that's all iPhone supports). As it is, my write(interruptChannelFD) calls return no errors, but
no text appears on iPhone side. The l2cap channels have been opened using blueZ library.

Question 1: Given that no virtual keyboard exists that does that, just how hard is it?

I am at the stage where iPhone and my linux box connect and stay connected, no problem.
Also, all the perror() calls are telling me that control and interrupt channel sockets connect just fine. (What I do is hciconfig my dongle to Keyboard device class and use the
well-known code by Collin Mulliner with slight modification -- I had to enter a passcode once, as all smartphones require).

Question 2: I should be able to just write() into interrupt socket without worrying about encryption, right? I've entered the passcode and the phone trusts the keyboard. (Collin was pondering a possible hid attack, but I connect honestly)

Also, it is my understanding that in boot protocol of a HID device, the exact report
descriptor
specfied in SPD is hardly relevant -- the report format is fixed anyway. So...

Question 3: Do I miss something major about the report protocol.
What I do is modify the Apple keyboard report descriptor and write
into the socket (see below).

const uint8_t hid_spec[] = { 
    0x05, 0x01, // usage page
    0x09, 0x06, // keyboard
    0xa1, 0x01, // collection (Application)
    0x85, 0x01, // report id (0x01)
    0x05, 0x07, // usage page(keyboard)
    0x19, 0xe0, // usage min
    0x29, 0xe7, // usage max
    0x15, 0x00, // logical min
    0x25, 0x01, // logical max
    0x75, 0x01, // report size
    0x95, 0x08, // report count
    0x81, 0x02, // input (dat var abs)

    0x75, 0x08, // report size 
    0x95, 0x01, // report count 
    0x81, 0x01, // input (const)

            // The following two outputs I don't seem to receive
    0x75, 0x01, // report size
    0x95, 0x05, // report count
    0x05, 0x08, // usage page (LEDs)
    0x19, 0x01, // usage min
    0x29, 0x05, // usage max 
    0x91, 0x02, // OUTPUT1 (dat var abs) 

    0x75, 0x03,
    0x95, 0x01,
    0x91, 0x01, // OUTPUT2 (arr,const) 

    0x75, 0x08, // report size
    0x95, 0x06, // report count
    0x15, 0x00, // logical min
    0x26, 0xff, 0x00 // logical max

    0x05, 0x07
    0x19, 0x00
    0x2a, 0xff, 0x00,
    0x81, 0x00,

            // A total of 9 bits sent by now
            // I tried remove the following fields
            /********** BEGIN SNIP
    0x75, 0x01,
    0x95, 0x01,
    0x15, 0x00,
    0x25, 0x01,

    0x05, 0x0c,
    0x09, 0xb8,
    0x81, 0x06,


    0x09, 0xe2,
    0x81, 0x06,


    0x09, 0xe9,
    0x81, 0x02,
    0x09, 0xea,
    0x81, 0x02,
    0x75, 0x01,
    0x95, 0x04,
    0x81, 0x01,
            **** END SNIP/

    0xc0         // end coll

};

After this, I write the following 10 bytes into the interrupt channel:

                    pkg[0] = 0xa1;   // BT HDR (DATA)
                    pkg[1] = 0x01;   // REPORT ID 0x1 == kbd
                    pkg[2] = modifiers; // Ctrl, Shift, etc
                    pkg[3] = 0x00;    // constant 0 (see descr)
                    // pkg[4] = 0x00; // the key code - entered before this point, according to HID usage tables.
                    pkg[5] = 0x00;
                    pkg[6] = 0x00;
                    pkg[7] = 0x00;
                    pkg[8] = 0x00;
                    pkg[9] = 0x00;

                    if (write(is, pkg, 10) <= 0) {
                        perror("write");
                        exit(-1);
                    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦年海沫深 2024-12-10 05:45:59

美好的一天,先生。

让我向您介绍我的一个不起眼的假期浪费程序,它实际上可以与一个名为 iPad 的垃圾一起使用,其软件堆栈应该与您的 iPhone 相当接近: https://github.com/lkundrak/virtkbd

除了实际实现之外,我将尝试回答您的问题。

问题 1:

鉴于蓝牙 HID 配置文件规范、USB HID 配置文件规范和可用工具以及实际设备的具体情况的质量和长度,我想尝试和错误会让您走得更远。拥有一个实际的蓝牙键盘,并编写一个简单的协议中继器和转储器,让您观察它们的作用 - 请参阅文档来解密正在发生的事情。

问题2:

对。对于我的 iPad,我首先需要将设备与不属于键盘类别的计算机配对(我的猜测是 iPad 会尝试让我输入 PIN,而 Bluez 无法做到这一点) 。然后我需要将类更改为 Keyboard(通过运行我的 bithdd 程序)并强制 iPad 重新连接,以便它从 SDP 获取协议描述符并尝试连接到 L2CAP 端口 17 和 19。

问题 3:

是的,几乎就是这样——我认为你不会错过任何重要的事情。

祝你今天过得愉快!

Good day, sir.

Let me kindly point to you to a humble holiday timewaster of mine that actually is able to be used with a piece of junk called iPad, whose software stack should be reasonable close to iPhone of yours: https://github.com/lkundrak/virtkbd

Aside from the actual implementation, I'll try to answer your questions.

Question 1:

Given the quality and length of Bluetooth HID profile specification, USB HID one and tooling available and actual device specifics, I guess trial and error will take you further. Have an actual Bluetooth keyboard, and write a simple protocol repeater and dumper to let you observe what do they do -- refer to documentation to decrypt what's going on.

Question 2:

Right. For my iPad, I first need to pair the devices with my computer not being of a Keyboard class (my guess is that iPad otherwise attempts to make me enter a PIN, which can not be done with Bluez). Then I need to change the class to Keyboard (by running my bithdd program) and force iPad to reconnect, so that it grabs the protocol descriptor from SDP and attempts to connect to L2CAP ports 17 and 19.

Question 3:

Yes, it's pretty much like that -- I don't think you miss anything important.

Have a nice day!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文