Tryanks / go-accessoryhid

Emulate any hid device for Android.
MIT License
12 stars 1 forks source link

Question regarding receiving events from Android device #3

Closed jeanbritz closed 6 months ago

jeanbritz commented 8 months ago

Good day @Tryanks !

Thanks to your code I was able to send touchscreen HID events to my old Sony Xperia Z1 Compact Android phone. The phone is currently locked and cannot use ADB to interact with the phone. I am trying to unlock my phone using PIN combinations, as I forgot what the PIN was.

This is the report descriptor I have used

var Touchscreen5 = []byte{
    0x05, 0x0D,        // Usage Page (Digitizer)
    0x09, 0x02,        // Usage (Pen)
    0xA1, 0x01,        // Collection (Application)
    0x09, 0x20,        //   Usage (Stylus)
    0xA1, 0x00,        //   Collection (Physical)
    0x09, 0x42,        //     Usage (Tip Switch)
    0x09, 0x32,        //     Usage (In Range)
    0x15, 0x00,        //     Logical Minimum (0)
    0x25, 0x01,        //     Logical Maximum (1)
    0x75, 0x01,        //     Report Size (1)
    0x95, 0x02,        //     Report Count (2)
    0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x75, 0x01,        //     Report Size (1)
    0x95, 0x06,        //     Report Count (6)
    0x81, 0x01,        //     Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
    0x09, 0x01,        //     Usage (Pointer)
    0xA1, 0x00,        //     Collection (Physical)
    0x09, 0x30,        //       Usage (X)
    0x09, 0x31,        //       Usage (Y)
    0x16, 0x00, 0x00,  //       Logical Minimum (0)
    0x26, 0x10, 0x27,  //       Logical Maximum (10000)
    0x36, 0x00, 0x00,  //       Physical Minimum (0)
    0x46, 0x10, 0x27,  //       Physical Maximum (10000)
    0x66, 0x00, 0x00,  //       Unit (None)
    0x75, 0x10,        //       Report Size (16)
    0x95, 0x02,        //       Report Count (2)
    0x81, 0x02,        //       Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x91, 0x02,        //       Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
    0x95, 0x03,        //       Report Count (3)
    0x91, 0x02,        //       Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
    0xC0,              //     End Collection
    0xC0,              //   End Collection
    0xC0,              // End Collection

    // 70 bytes

}

This is a long shot as there are not much documentation out there. Question to you is if there are any way to receive HID report events in case there were incorrect/correct PIN entered or HID event did not emulate a key press correctly?

Currently my implementation works 80% of the time and have cases where a key press does not happen and difficult to implement some error handling when a key press does not happen.

Tryanks commented 8 months ago

Hello! In my use cases over the past few months, I have not encountered a situation where a HID event did not occur. Sometimes, this is accompanied by console output libusb: pipe error, but this does not result in failure to send this event. I can update the code to trap and callback for pipe error from libusb, but as a validation, some information is needed: are you getting pipe error in the console when the HID event send fails?

jeanbritz commented 8 months ago

Hi,

I don't get any pipe error while executing my script.

I can confirm that handle_events: error: libusb: interrupted [code -10] does not have any effect on the HID event being sent.

I have uploaded my code here https://github.com/jeanbritz/go-android-bruteforce-pin

I will reply with a video clip soon to illustrate the problem I have.

Tryanks commented 8 months ago

I've checked your code implementation. It looks like you are using a stylus or an absolutely positioned mouse rather than a touchscreen implementation. For your question, there is no way to get HID Report or PIN Report from USB, because in AOAv2, HID is a one-way protocol. You can try the built-in descriptor accessory.TouchscreenReportDesc, the protocol format is as follows:

The length of a touch event is 6 bytes.
- `byte 0`: 0x01 | 0x00 (Press | Release)
- `byte 1`: Reserved (0x00)
- `byte 2-3`: The abscissa of the touch point (0-32767)
- `byte 4-5`: The ordinate of the touch point (0-32767)

In my use case it works 100% of the time. If you have any more questions, please feel free to let me know :)

jeanbritz commented 8 months ago

Hi @Tryanks,

Thanks for your feedback on HID and AOAv2! Appreciate it.

I did not use the accessory.TouchscreenReportDesc because I did not understand how to calculate the touch point positions. I have found using a mouse pointer easier as it allows you to give absolute positions on the screen and then use the stylus to do the pressing for me.

Currently my implementation works for me now 👍