greatscottgadgets / facedancer Goto Github PK
View Code? Open in Web Editor NEWImplement your own USB device in Python, supported by a hardware peripheral such as Cynthion or GreatFET
License: BSD 3-Clause "New" or "Revised" License
Implement your own USB device in Python, supported by a hardware peripheral such as Cynthion or GreatFET
License: BSD 3-Clause "New" or "Revised" License
Support LUNA as a backend: greatscottgadgets/luna#151
Hi
not sure if this classifies as issue, probably more like an enquiry or feature request.... anyway
Some usb devices when plugged-in enumerates as vendor:product, however as some points they will reset connection and switch to a different vendor:product...
Is there a way to follow a device throughout those changes? i.e. modify the proxy vendor:product as indicated from the data exchange between the devices?
Alternatively, would it be possible to proxy a physical usb port and not a specific vendor:product?
TIA
Alon
Hi,
I got a beagle bone black to run USB Proxy on a device I am trying to understand. Eventually I got USB Proxy-Legacy to run, and the host device fails to run the software... Some packets are exchanged and program stops. I believe I saw something about too much latency (100ms)..
So I buy GreatFET, Amazon delivery, here the next day, cool. Gave up on Windows, moved to Raspberry Pi, used Ubuntu, has some issues, third try use Raspian .. Works right off the bat! Nice.
The paragraph I find for help (read.me) for Facedancer says export BACKEND = greatfet ./facedancer-serial.py (which runs). Looking in the directory, I see some other facedancer-usb* files, what do I run to put it in MITM mode? Is there a wiki page somewhere?
facedancer-usbproxy.py wants -v and -p. Do I have to know this? I did not have to pass that on the legacy version.
Also, does anyone else think facesitter instead of facedancer? Does that make me a bad person?
Hi,
I am using a GreatFet One.
(1) I would like to try out fuzzing with Facedancer. I am able to start facedancer-keyboard.py with the help of this link: #8.
Using this same script, how should I begin to fuzz? Are there any sample scripts or documented functions that I could use?
(2) Have another question which is similar to this post, #20. I would like to perform a proxy using a USB 2.0 mass storage device. At this moment, I got a "unable to enumerate USB device" error when I inserted a thumb drive. May I know will USB 2.0 mass storage devices be supported in Facedancer in the near future?
Thanks very much!
Regards,
Tzewan
Hello,
I'm trying to use the proxy-script and a GreatFET to proxy and sniff an RME BabyFace Pro usb audio device in class compliant mode like this
(babyface pro) - (host computer) - (greatFETOne) - (ipad with camera connection kit)
lsusb:
Bus 001 Device 015: ID 2a39:3fb0
so I call:
./facedancer-usbproxy.py -v 2a39 -p 3fb0
resulting in:
Using GreatDancer backend. GreatDancer initialized [14:19:06] <, standard request to device (GET_DESCRIPTOR: value=DEVICE descriptor (index=0x00), index=0, length=64) [14:19:06] <: b'\x12\x01\x00\x02\xef\x02\x01@9*\xb0?\x01\x00\x01\x02\x03\x01' -- Patched device descriptor. -- [14:19:06] <, standard request to device (GET_DESCRIPTOR: value=DEVICE descriptor (index=0x00), index=0, length=18) [14:19:06] <: b'\x12\x01\x00\x02\xef\x02\x01@9*\xb0?\x01\x00\x01\x02\x03\x01' -- Patched device descriptor. -- [14:19:06] <, standard request to device (GET_DESCRIPTOR: value=DEVICE_QUALIFIER descriptor (index=0x00), index=0, length=10) [14:19:06] <: b'\n\x06\x00\x02\xef\x02\x01@\x00\x00' [14:19:06] <, standard request to device (GET_DESCRIPTOR: value=CONFIGURATION descriptor (index=0x00), index=0, length=9) [14:19:06] <: b'\t\x02\xa7\x01\x04\x01\x00\x802' [14:19:06] <, standard request to device (GET_DESCRIPTOR: value=CONFIGURATION descriptor (index=0x00), index=0, length=423) [14:19:06] <: b'\t\x02\xa7\x01\x04\x01\x00\x802\x08\x0b\x00\x04\x01\x00 \x00\t\x04\x00\x00\x00\x01\x01 \x00\t$\x01\x00\x02\x08U\x00\x00\x08$\n\x01\x03\x03\x00\x00\x11$\x02\x03\x01\x01\x00\x01\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x11$\x02\x05\x01\x02\x00\x01\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x0c$\x03\x04\x01\x03\x00\x02\x01\x00\x00\x00\x0c$\x03\x06\x01\x01\x00\x05\x01\x00\x00\x00\t\x04\x01\x00\x00\x01\x02 \x00\t\x04\x01\x01\x02\x01\x02 \x00\x10$\x01\x03\x00\x01\x01\x00\x00\x00\x02\x03\x00\x00\x00\x00\x06$\x02\x01\x03\x18\x07\x05\x03\x05\x96\x00\x01\x08%\x01\x00\x00\x00\x00\x00\x07\x05\x83\x11\x04\x00\x04\t\x04\x01\x02\x02\x01\x02 \x00\x10$\x01\x03\x00\x01\x01\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x06$\x02\x01\x03\x18\x07\x05\x03\x05\x84\x03\x01\x08%\x01\x00\x00\x00\x00\x00\x07\x05\x83\x11\x04\x00\x04\t\x04\x02\x00\x00\x01\x02 \x00\t\x04\x02\x01\x01\x01\x02 \x00\x10$\x01\x06\x00\x01\x01\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x06$\x02\x01\x03\x18\x07\x05\x84\x05\x84\x03\x01\x08%\x01\x00\x00\x00\x00\x00\t\x04\x02\x02\x01\x01\x02 \x00\x10$\x01\x06\x00\x01\x01\x00\x00\x00\x02\x03\x00\x00\x00\x00\x06$\x02\x01\x03\x18\x07\x05\x84\x05\x96\x00\x01\x08%\x01\x00\x00\x00\x00\x00\t\x04\x03\x00\x02\x01\x03\x00\x02\x07$\x01\x00\x01a\x00\t$\x03\x01\x03\x01\x02\x01\x04\x06$\x02\x02\x02\x04\t$\x03\x01\x07\x01\x06\x01\x05\x06$\x02\x02\x06\x05\x06$\x02\x01\x01\x04\t$\x03\x02\x04\x01\x01\x01\x04\x06$\x02\x01\x05\x05\t$\x03\x02\x08\x01\x05\x01\x05\t\x05\x07\x02\x00\x02\x00\x00\x00\x06%\x01\x02\x01\x05\t\x05\x86\x02\x00\x02\x00\x00\x00\x06%\x01\x02\x03\x07' -- Storing configuration <USBConfiguration index=1 num_interfaces=4 attributes=0x80 max_power=100mA> -- [14:19:06] <, standard request to device (GET_DESCRIPTOR: value=STRING descriptor (index=0x00), index=0, length=255) [14:19:06] <: ̄Љ [14:19:06] <, standard request to device (GET_DESCRIPTOR: value=STRING descriptor (index=0x02), index=409, length=255) [14:19:06] <: ̰Babyface Pro (72993879) [14:19:06] <, standard request to device (GET_DESCRIPTOR: value=STRING descriptor (index=0x01), index=409, length=255) [14:19:06] <: ̈RME [14:19:06] <, standard request to device (GET_DESCRIPTOR: value=STRING descriptor (index=0x03), index=409, length=255) [14:19:06] <: ̠0950E421106A7C8 [14:19:06] >, standard request to device (SET_CONFIGURATION: value=1, index=0, length=0) -- Applying configuration <USBConfiguration index=1 num_interfaces=4 attributes=0x80 max_power=100mA> -- Traceback (most recent call last): File "./facedancer-usbproxy.py", line 50, in <module> main() File "./facedancer-usbproxy.py", line 44, in main d.run() File "/home/bollie/PycharmProjects/Facedancer/facedancer/USBDevice.py", line 165, in run self.scheduler.run() File "/home/bollie/PycharmProjects/Facedancer/facedancer/core.py", line 509, in run task() File "/home/bollie/PycharmProjects/Facedancer/facedancer/USBDevice.py", line 83, in <lambda> self.scheduler.add_task(lambda : self.maxusb_app.service_irqs()) File "/home/bollie/PycharmProjects/Facedancer/facedancer/backends/greatdancer.py", line 765, in service_irqs self._handle_setup_events() File "/home/bollie/PycharmProjects/Facedancer/facedancer/backends/greatdancer.py", line 368, in _handle_setup_events self._handle_setup_event_on_endpoint(i) File "/home/bollie/PycharmProjects/Facedancer/facedancer/backends/greatdancer.py", line 402, in _handle_setup_event_on_endpoint self.connected_device.handle_request(request) File "/home/bollie/PycharmProjects/Facedancer/facedancer/USBProxy.py", line 241, in handle_request self._proxy_out_request(req) File "/home/bollie/PycharmProjects/Facedancer/facedancer/USBProxy.py", line 296, in _proxy_out_request req, data = f.filter_control_out(req, data) File "/home/bollie/PycharmProjects/Facedancer/facedancer/filters/standard.py", line 95, in filter_control_out self.device.configured(configuration) File "/home/bollie/PycharmProjects/Facedancer/facedancer/USBProxy.py", line 220, in configured self.maxusb_app.configured(configuration) File "/home/bollie/PycharmProjects/Facedancer/facedancer/backends/greatdancer.py", line 740, in configured self._configure_endpoints(configuration) File "/home/bollie/PycharmProjects/Facedancer/facedancer/backends/greatdancer.py", line 730, in _configure_endpoints self.api.set_up_endpoints(*endpoint_triplets) File "/home/bollie/PycharmProjects/Facedancer/venv/lib/python3.8/site-packages/pygreat/comms.py", line 1108, in method return self.execute_command(verb_number, in_format, out_format, name=name, class_name=class_name, File "/home/bollie/PycharmProjects/Facedancer/venv/lib/python3.8/site-packages/pygreat/comms.py", line 1263, in execute_command return self.comms_backend.execute_command(self.CLASS_NUMBER, verb, in_format, File "/home/bollie/PycharmProjects/Facedancer/venv/lib/python3.8/site-packages/pygreat/comms.py", line 770, in execute_command raw_result = self.execute_raw_command(class_number, verb, payload, timeout, File "/home/bollie/PycharmProjects/Facedancer/venv/lib/python3.8/site-packages/pygreat/comms_backends/usb.py", line 391, in execute_raw_command future_utils.raise_from(self._exception_for_command_failure(error_number, pretty_name), None) File "/home/bollie/PycharmProjects/Facedancer/venv/lib/python3.8/site-packages/future/utils/__init__.py", line 403, in raise_from exec(execstr, myglobals, mylocals) File "<string>", line 1, in <module> pygreat.comms.CommandFailureError: greatdancer.set_up_endpoints: greatdancer: failing to set up endpoint with packet size 900; larger than max (512)! [EINVAL]
FreeDancer is checked out from master, GreatFET is 2020.1.2
Any ideas, why this is failing?
This is the tracking issue for the facedancer
3.0.2
release.
C:\Users\Silica\Desktop\greatfet\Facedancer>py facedancer-usbproxy.py -v 054C -p 04E4
Using GreatDancer backend.
GreatDancer initialized
Traceback (most recent call last):
File "C:\Users\Silica\Desktop\greatfet\Facedancer\facedancer-usbproxy.py", line 50, in
main()
File "C:\Users\Silica\Desktop\greatfet\Facedancer\facedancer-usbproxy.py", line 33, in main
d = USBProxyDevice(u, idVendor=args.vendorid, idProduct=args.productid, verbose=2, quirks=quirks)
File "C:\Users\Silica\Desktop\greatfet\Facedancer\facedancer\USBProxy.py", line 173, in init
self.libusb_device.detach_kernel_driver(interface.bInterfaceNumber)
File "C:\Users\Silica\AppData\Local\Programs\Python\Python39\lib\site-packages\usb\core.py", line 1121, in detach_kernel_driver
self._ctx.backend.detach_kernel_driver(
File "C:\Users\Silica\AppData\Local\Programs\Python\Python39\lib\site-packages\usb\backend\libusb0.py", line 662, in detach_kernel_driver
raise NotImplementedError(self.detach_kernel_driver.name)
NotImplementedError: detach_kernel_driver
Commit 5942533 broke facedancer-keyboard.py
. Reverting the commit fixes the issue.
# ./facedancer-keyboard.py
Using GreatDancer backend.
GreatDancer initialized
GreatDancer connected device USB keyboard device
-- Reset requested! --
USB keyboard device received request <, standard request to device (GET_DESCRIPTOR: value=DEVICE descriptor (index=0x00), index=0, length=64)
USB keyboard device received GET_DESCRIPTOR req 1, index 0, language 0x0000, length 64
-- Reset requested! --
USB keyboard device received request <, standard request to device (GET_DESCRIPTOR: value=DEVICE descriptor (index=0x00), index=0, length=18)
USB keyboard device received GET_DESCRIPTOR req 1, index 0, language 0x0000, length 18
USB keyboard device received request <, standard request to device (GET_DESCRIPTOR: value=CONFIGURATION descriptor (index=0x00), index=0, length=34)
USB keyboard device received GET_DESCRIPTOR req 2, index 0, language 0x0000, length 34
USB keyboard device received request <, standard request to device (GET_DESCRIPTOR: value=STRING descriptor (index=0x03), index=409, length=255)
USB keyboard device received GET_DESCRIPTOR req 3, index 3, language 0x0409, length 255
USB keyboard device received request >, standard request to device (SET_CONFIGURATION: value=1, index=0, length=0)
USB keyboard device received SET_CONFIGURATION request
Setting up endpoint 3 (direction=1, transfer_type=3, max_packet_size=512)
USB keyboard interface sending keypress 0x00
USB keyboard device received request <, standard request to interface (GET_DESCRIPTOR: value=REPORT descriptor (index=0x00), index=0, length=43)
USB keyboard interface received GET_DESCRIPTOR at interface req 34, index 0, language 0x0000, length 43
USB keyboard device received request >, class request to interface (class request 10: value=0, index=0, length=0)
Traceback (most recent call last):
File "./facedancer-keyboard.py", line 14, in <module>
d.run()
File "/home/user/Tools/usb/Facedancer/facedancer/USBDevice.py", line 166, in run
self.scheduler.run()
File "/home/user/Tools/usb/Facedancer/facedancer/core.py", line 506, in run
task()
File "/home/user/Tools/usb/Facedancer/facedancer/USBDevice.py", line 84, in <lambda>
self.scheduler.add_task(lambda : self.maxusb_app.service_irqs())
File "/home/user/Tools/usb/Facedancer/facedancer/backends/GreatDancerApp.py", line 760, in service_irqs
self._handle_setup_events()
File "/home/user/Tools/usb/Facedancer/facedancer/backends/GreatDancerApp.py", line 367, in _handle_setup_events
self._handle_setup_event_on_endpoint(i)
File "/home/user/Tools/usb/Facedancer/facedancer/backends/GreatDancerApp.py", line 401, in _handle_setup_event_on_endpoint
self.connected_device.handle_request(request)
File "/home/user/Tools/usb/Facedancer/facedancer/USBDevice.py", line 236, in handle_request
handler_entity = recipient.interface
AttributeError: 'USBKeyboardInterface' object has no attribute 'interface'
The USB/IP protocol is used in a number of locations such as;
Would be awesome to have a backend for this protocol.
Hi,
I am using the GreatFet One on Windows 10 with the Firmware version: v2021.2.1.
I have been trying to run the facedancer's script [USBKeyboard.py]
from (https://github.com/greatscottgadgets/Facedancer/blob/master/legacy-applets/USBKeyboard.py)
.
However, I have been encountering the following problem when I connect USB1:
Kindly advise on how to resolve it. Thank you.
This is the tracking issue for the Facedancer 3.0.0 release.
Hi, I am having trouble while I am proxying a Flight Joystick controller. I run Facedancer.py and I get the controller to be recognized by both the host and target computer, but that is as far as I get. I am unable to actually play a game or move any controls through the full setup. Any help is appreciated and let me know if I need to provide any additional information.
Hi!
I saw in the readme and on youtube that this library can be ported to any embedded linux devices that has gadget api as well as usb device and host controller. I wonder if you are working on that, and if not how can I do this and contribute :)
Wasn't sure where to post this. Is this library capable of having a linux machine support a man in the middle between my controller and the xbox where it records all of my actions, but allows the xbox to make and replay its own actions?
I wrote a simple HID mouse class for Facedancer. The basic functionality works as expected.
Issue:
Regardless of the devices bInterval
setting, the device (Great FET) seems to be stuck at a max of 125 Hz (60 Hz on average)
Tested using https://devicetests.com/mouse-rate-test
Any interval below 4ms will cause an error shortly after EP1 is configured.
What is my best strategy for debugging this?
Is my device configuration causing the issue, such as a missing IN or OUT handler?
The Great FET backend should easily be able to handle a 32 bit report @ 1000 Hz.
Any help or tips would be appreciated.
Here is my HID class and the stack trace for reference:
from . import default_main
from ..future import *
from ..classes.hid.usage import *
from ..classes.hid.descriptor import *
from ..classes.hid.mouse import *
from ..classes import USBDeviceClass
@use_inner_classes_automatically
class USBMouseDevice(USBDevice):
""" Simple USB mouse device. """
name : str = "Wired Mouse"
device_class : int = 0
device_subclass : int = 0
protocol_revision_number : int = 0
max_packet_size_ep0 : int = 64
vendor_id : int = 0x1234
product_id : int = 0x5678
manufacturer_string : str = "Company, Inc."
product_string : str = "ABC Mouse"
serial_number_string : str = "12345678"
supported_languages : tuple = (LanguageIDs.ENGLISH_US,)
device_revision : int = 0
usb_spec_version : int = 0x0002
class MouseConfiguration(USBConfiguration):
""" Primary USB configuration: act as a mouse. """
number : int = 1
configuration_string : str = None
max_power : int = 500
self_powered : bool = True
supports_remote_wakeup : bool = True
class MouseInterface(USBInterface):
""" Core HID interface for our mouse. """
name : str = "USB mouse interface"
number : int = 0
alternate : int = 0
class_number : int = USBDeviceClass.HID
subclass_number : int = 0
protocol_number : int = 0
interface_string : str = None
class MouseEventEndpoint(USBEndpoint):
number : int = 1
direction : USBDirection = USBDirection.IN
transfer_type : USBTransferType = USBTransferType.INTERRUPT
synchronization_type : USBSynchronizationType = USBSynchronizationType.NONE
usage_type : USBUsageType = USBUsageType.DATA
max_packet_size : int = 64
interval : int = 4
class USBClassDescriptor(USBClassDescriptor):
number : int = USBDescriptorTypeNumber.HID
raw : bytes = b'\x09\x21\x10\x01\x00\x01\x22\x3A\x00'
# bLength = 0x09 = 9 bytes
# bDescriptorType = 0x21 = 33 = HID
# bcdHID = 0x0110 = 1.1 HID spec release version (little endian)
# bCountryCode = 0x00 = Not Supported
# bNumDescriptors = 0x01
# bDescriptorType = 0x22 = 34 = REPORT
# wDescriptorLength = 0x003A = 58 = total size (bytes) of the Report descriptor (little endian)
class ReportDescriptor(HIDReportDescriptor):
number : int = USBDescriptorTypeNumber.REPORT
fields : tuple = (
USAGE_PAGE (HIDUsagePage.GENERIC_DESKTOP),
USAGE (HIDGenericDesktopUsage.MOUSE),
COLLECTION (HIDCollection.APPLICATION),
USAGE (HIDGenericDesktopUsage.POINTER),
COLLECTION (HIDCollection.PHYSICAL),
USAGE_PAGE (HIDUsagePage.BUTTONS),
USAGE_MINIMUM (0x01),
USAGE_MAXIMUM (0x03),
LOGICAL_MINIMUM (0x00),
LOGICAL_MAXIMUM (0x01),
REPORT_COUNT (0x03),
REPORT_SIZE (0x01),
INPUT (variable=True),
REPORT_COUNT (0x01),
REPORT_SIZE (0x05),
INPUT (constant=True, variable=True),
# One byte of constant zero-padding.
# This is required for compliance; and Windows will ignore this report
# if the zero byte isn't present.
REPORT_COUNT (0x01),
REPORT_SIZE (0x08),
INPUT (constant=True, variable=True),
USAGE_PAGE (HIDUsagePage.GENERIC_DESKTOP),
USAGE (HIDGenericDesktopUsage.X),
USAGE (HIDGenericDesktopUsage.Y),
LOGICAL_MINIMUM (0x00, 0x80), # logic min (-32768)
LOGICAL_MAXIMUM (0xff, 0x7f), # logic max (32767)
REPORT_SIZE (0x10),
REPORT_COUNT (0x02),
INPUT (variable=True, relative=True),
END_COLLECTION (),
END_COLLECTION (),
)
@class_request_handler(number=USBStandardRequests.GET_INTERFACE)
@to_this_interface
def handle_get_interface_request(self, request):
# Silently stall GET_INTERFACE class requests.
request.stall()
def __post_init__(self):
super().__post_init__()
self.buttons = MouseButtons.NONE
self.dx = 0
self.dy = 0
def getUnsigned(self, val):
return val + MouseLogicalRange.UNSIGNED_MAX if val < 0 else val
def getPendingMove(self):
x, y = self.getUnsigned(self.dx), self.getUnsigned(self.dy)
self.dx = 0
self.dy = 0
return x, y
def _generate_hid_report(self) -> bytes:
""" Generates a single HID report for the given mouse state. """
dx, dy = self.getPendingMove()
dx_upper = (dx >> 8) & 0xFF
dx_lower = (dx) & 0xFF
dy_upper = (dy >> 8) & 0xFF
dy_lower = (dy) & 0xFF
return bytes([self.buttons, 0x00, dx_lower, dx_upper, dy_lower, dy_upper])
def handle_data_requested(self, endpoint: USBEndpoint):
""" Provide data once per host request. """
report = self._generate_hid_report()
endpoint.send(report)
#
# User-facing API.
#
def button_down(self, code: MouseButtons):
""" Marks a given button as pressed """
self.buttons |= code
def button_up(self, code: MouseButtons):
""" Marks a given button as released """
self.buttons &= ~code
def addToPendingMove(self, dx: int = 0, dy: int = 0):
self.dx += dx
self.dy += dy
def all_buttons_up(self):
""" Releases all buttons currently pressed. """
self.buttons = MouseButtons.NONE
if __name__ == "__main__":
default_main(USBMouseDevice)
Stack trace when running a basic example with EP1 at 1ms bInterval
python .\Facedancer\examples\rubber-jerry.py
INFO | goodfet | Skipping GoodFET-based devices, as pyserial isn't installed.
INFO | greatdancer | Connecting to host.
INFO | rubber-jerry | Beginning mouse demo...
INFO | device | Host issued a bus reset; resetting our connection.
INFO | device | Host issued a bus reset; resetting our connection.
INFO | greatdancer | Configuring endpoint 01/IN: INTERRUPT transfers every 1ms.
INFO | greatdancer | Disconnecting from host.
Traceback (most recent call last):
File ".\Facedancer\examples\rubber-jerry.py", line 78, in <module>
main(device, testMouse())
File "D:\Anaconda3\lib\site-packages\facedancer\devices\__init__.py", line 51, in default_main
device.emulate(*coroutines)
File "D:\Anaconda3\lib\site-packages\facedancer\future\device.py", line 175, in emulate
self.run_with(*coroutines)
File "D:\Anaconda3\lib\site-packages\facedancer\future\device.py", line 160, in run_with
asyncio.run(inner())
File "D:\Anaconda3\lib\asyncio\runners.py", line 43, in run
return loop.run_until_complete(main)
File "D:\Anaconda3\lib\asyncio\base_events.py", line 584, in run_until_complete
return future.result()
File "D:\Anaconda3\lib\site-packages\facedancer\future\device.py", line 158, in inner
await asyncio.gather(self.run(), *coroutines)
File "D:\Anaconda3\lib\site-packages\facedancer\future\device.py", line 147, in run
self.backend.service_irqs()
File "D:\Anaconda3\lib\site-packages\facedancer\backends\greatdancer.py", line 772, in service_irqs
self._handle_nak_events()
File "D:\Anaconda3\lib\site-packages\facedancer\backends\greatdancer.py", line 714, in _handle_nak_events
self.connected_device.handle_nak(endpoint.number)
File "D:\Anaconda3\lib\site-packages\facedancer\future\device.py", line 291, in handle_nak
self.handle_data_requested(endpoint)
File "D:\Anaconda3\lib\site-packages\facedancer\devices\mouse.py", line 167, in handle_data_requested
endpoint.send(report)
File "D:\Anaconda3\lib\site-packages\facedancer\future\endpoint.py", line 78, in send
packet_size=self.max_packet_size, blocking=blocking)
File "D:\Anaconda3\lib\site-packages\facedancer\future\device.py", line 251, in _send_in_packets
self.backend.send_on_endpoint(endpoint_number, packet, blocking=blocking)
File "D:\Anaconda3\lib\site-packages\facedancer\backends\greatdancer.py", line 246, in send_on_endpoint
self.api.send_on_endpoint(ep_num, bytes(data))
File "D:\Anaconda3\lib\site-packages\pygreat\comms.py", line 1109, in method
timeout=timeout, max_response_length=max_response_length, encoding=encoding, *arguments)
File "D:\Anaconda3\lib\site-packages\pygreat\comms.py", line 1264, in execute_command
out_format, *arguments, **kwargs)
File "D:\Anaconda3\lib\site-packages\pygreat\comms.py", line 771, in execute_command
None, max_response_length, comms_timeout, pretty_name, rephrase_errors)
File "D:\Anaconda3\lib\site-packages\pygreat\comms_backends\usb.py", line 353, in execute_raw_command
self.LIBGREAT_REQUEST_NUMBER, self.LIBGREAT_VALUE_EXECUTE, flags, to_send, timeout)
File "D:\Anaconda3\lib\site-packages\usb\core.py", line 1089, in ctrl_transfer
self.__get_timeout(timeout))
File "D:\Anaconda3\lib\site-packages\usb\backend\libusb0.py", line 609, in ctrl_transfer
timeout
File "D:\Anaconda3\lib\site-packages\usb\backend\libusb0.py", line 447, in _check
raise USBError(errmsg, ret)
usb.core.USBError: [Errno None] b'libusb0-dll:err [control_msg] sending control message failed, win error: A device attached to the system is not functioning.\r\n\n'
I'm encountering a hang in situations when I send bad data to a host with a GreatFET configured as a USB device. I seem to be able to reliably reproduce this issue when the host issues a standard GET_DESCRIPTOR and I generate a random response of request length. As can be seen in the output below, the code will appear to send the response and the host will typically either reset the bus or reissue the request again. Eventually after a few responses like this, greatdancer will hang forever within read_from_endpoint
when attempting to check if _transfer_is_complete
returned successfully until I finally interrupt it.
If I understand the spec correctly (rev2 8.5.2), it appears that on an error to a IN request, the host doesn't necessarily have to ACK or even NAK. I believe the issue is that the greatdancer backend always expects an ACK and will wait forever attempting to receive one.
This may be an issue within the greatdancer firmware? I would expect that the GET_ENDPTCOMPLETE status should have been set as long as the response was actually sent. The exact wording in the LPC4330 datasheet is:
"ENDPTCOMPLETE
ETCE: Endpoint transmit complete event for physical IN endpoints. This bit is set to 1 by hardware when a transmit event (IN/INTERRUPT) occurred."
Does a "transmit complete" event only occur once the host acks?
Below is an example case and a backtrace when I interrupt the hang. If I can get some input on the issue I can open a pull request with a proposed fix.
INFO | greatdancer | Connecting to host.
DEBUG | selector_events| Using selector: EpollSelector
DEBUG | greatdancer | Host issued bus reset.
INFO | device | Host issued a bus reset; resetting our connection.
DEBUG | greatdancer | Host issued bus reset.
INFO | device | Host issued a bus reset; resetting our connection.
DEBUG | device | generic device received request: IN STANDARD request GET_DESCRIPTOR (0x06) to DEVICE [value=0x0100, index=0x0000, length=64]
TRACE | greatdancer | EP0/IN: <- b'p\x0f\x1fW\xd6\x1b\xea]\xdf%\xc4\xae\x07%\x9a\x17q\xcaAb:\xf2\x94W\xfa\x00O0`\x00\xf1C\x16\xa8\xcc\xfd\x9a&\x89\x9f#\x8aZ\xbey\xf6o\xa3x\xb7\x13s\x19\x17#4\xc0X,)\xa4JM3'
DEBUG | device | generic device received request: IN STANDARD request GET_DESCRIPTOR (0x06) to DEVICE [value=0x0100, index=0x0000, length=64]
TRACE | greatdancer | EP0/IN: <- b'%\xd7\xb3\x9d\xe9\xc1f\xdf\xca\xb6S\xf6_\xad\xcf,t\x12\xed\x04\xde\xb82\xe2\x15\x16f3igV\xc5\x94\xfe\xa4\xd78L\xde\x97\x11\x8c\x08^\xfaM\x93.\rT\x9d\x90\xfcL\t\xfe\x81\x95\x83\xc5w\xed_\xa3'
DEBUG | device | generic device received request: IN STANDARD request GET_DESCRIPTOR (0x06) to DEVICE [value=0x0100, index=0x0000, length=64]
TRACE | greatdancer | EP0/IN: <- b'~\x15*\x90;;\xd1\x88\xbc\x1d\x01\xe7 \xce\x1d\x14\x97$\xdc\x8bM\xd8\x0b62\xe8>@\x0c\xcbG\xf5P\xca\r\x9d4;\x91\x00c\xee\x95\xfa(f\xfb\x1fQ\xeb\x96\xa3K\xb5d\x00\xc2p\x18\xb2\x14$\x98F'
DEBUG | greatdancer | Host issued bus reset.
INFO | device | Host issued a bus reset; resetting our connection.
DEBUG | device | generic device received request: IN STANDARD request GET_DESCRIPTOR (0x06) to DEVICE [value=0x0100, index=0x0000, length=64]
TRACE | greatdancer | EP0/IN: <- b'R\x87\x8f\xce\xbe>m\xf5;\x04\xa0\x96\xa0\x8a\xb0k\xa2\xa8\xbc\x84\n\xcaJ\xb5\xd7\xc6\xd0\xc3n\x87\xfc\x9b\x03\xc3n\x81\x8c\xb1\x84\xbe\x94<\xb9g9\xdd\x9f2\x9ap\xaa\x1e2\xf2\x13\x8c\x85\xa0F\xad9\xde\xd4\x95'
DEBUG | device | generic device received request: IN STANDARD request GET_DESCRIPTOR (0x06) to DEVICE [value=0x0100, index=0x0000, length=64]
TRACE | greatdancer | EP0/IN: <- b'l\x8e\x1bZ\xd5\xfbxz\xfd\xe9rJ9\xf8\xcf\x00D\xc0i\xdd\xcc\x14I\x82\xa8\xc6W\x80\xe60\xeb\xaa\xda\xbd\xb91\x10\x84\x1d\x8c%\x906&\xc2\xcd\xb7\xf1}\xe3h\xb7\xc7#<\x18\xb1PM\x85\x8a\xe7\x98+'
^CINFO | greatdancer | Disconnecting from host.
...
File "/usr/local/lib/python3.8/dist-packages/facedancer-2.9+dirty-py3.8.egg/facedancer/backends/greatdancer.py", line 370, in _handle_setup_events
self._handle_setup_event_on_endpoint(i)
File "/usr/local/lib/python3.8/dist-packages/facedancer-2.9+dirty-py3.8.egg/facedancer/backends/greatdancer.py", line 408, in _handle_setup_event_on_endpoint
self.ack_status_stage(direction=self.DEVICE_TO_HOST)
File "/usr/local/lib/python3.8/dist-packages/facedancer-2.9+dirty-py3.8.egg/facedancer/backends/greatdancer.py", line 161, in ack_status_stage
self.read_from_endpoint(endpoint_number)
File "/usr/local/lib/python3.8/dist-packages/facedancer-2.9+dirty-py3.8.egg/facedancer/backends/greatdancer.py", line 268, in read_from_endpoint
while not self._transfer_is_complete(ep_num, self.HOST_TO_DEVICE):
File "/usr/local/lib/python3.8/dist-packages/facedancer-2.9+dirty-py3.8.egg/facedancer/backends/greatdancer.py", line 431, in _transfer_is_complete
status = self._fetch_transfer_status()
File "/usr/local/lib/python3.8/dist-packages/facedancer-2.9+dirty-py3.8.egg/facedancer/backends/greatdancer.py", line 418, in _fetch_transfer_status
return self.api.get_status(self.GET_ENDPTCOMPLETE)
File "/home/dev/.local/lib/python3.8/site-packages/pygreat/comms.py", line 1108, in method
return self.execute_command(verb_number, in_format, out_format, name=name, class_name=class_name,
...
KeyboardInterrupt
Since the logging mechanism being used changes the log level of the root python logger, changing the level can enable/disable logging of libraries.
I recommend adding a Facedancer logger under the root logger so that this issue does not occur.
Let me know if you would like me to submit a PR with this change.
Should probably add a license to this repo. I wrote some device implementations using Facedancer but technically it's not legal for me to use them with no license.
An USB device emulated with Facedancer and GreatFET One will not be listed by libusb or IOKit on macOS even though is shown by CLI commands lsusb / system_profiler SPUSBDataType
STEPS TO REPRODUCE
Connect a GreatFET One to both ports on a MacBook.
Run python3 ./facedancer-keyboard.py
Run lsusb
or system_profiler SPUSBDataType
and you should see listed both the GreatFET One and the emulated USB keyboard:
Bus 020 Device 004: ID 05ac:0274 Apple Inc. Apple Internal Keyboard / Trackpad Serial: D3H54562C61FTV4AX1FS
Bus 020 Device 005: ID 05ac:8290 Apple Inc. Bluetooth USB Host Controller
Bus 020 Device 000: ID 610b:4653 610b MAX3420E Enum Code Serial: S/N3420E
Bus 020 Device 021: ID 1d50:60e6 1d50 GreatFET Serial: 000000000000000057cc67e631923157
List of USB devices programmatically using either libusb, pyusb or IOKit:
import usb.core
devices = usb.core.find(find_all=True)
for device in devices:
print("device", hex(device.idVendor), ":", hex(device.idProduct))
the emulated usb device will not be detected even though the GreatFET One is detected.
device 0x1d50 : 0x60e6 // GreatFET
device 0x5ac : 0x8290 // Apple Inc. Bluetooth USB Host Controller
device 0x5ac : 0x274 // Apple Inc. Apple Internal Keyboard / Trackpad
device 0x5ac : 0x8007 // ???
mrstock said on Discord that he also couldn't list an emulated USB device programmatically on macOS but it could do so on Ubuntu.
mrstock said that on macOS the descriptor reading phase is not performed and the endpoints are not set. It remains in an infinite loop waiting for a transfer to complete on line 243 of GreatDancerApp.py
USB keyboard device received request <, standard request to device (GET_DESCRIPTOR: value=STRING descriptor (index=0x03), index=409, length=18)
USB keyboard device received GET_DESCRIPTOR req 3, index 3, language 0x0409, length 18
[18, 3, 83, 0, 47, 0, 78, 0, 51, 0, 52, 0, 50, 0, 48, 0, 69, 0]
sending on 0: bytearray(b'\x12\x03S\x00/\x00N\x003\x004\x002\x000\x00E\x00')
Cleaning up transfers on 0
Out status: 0b1
IN status: 0b0
Cleaning up transfers on 0
USB keyboard device received request <, standard request to device (GET_DESCRIPTOR: value=CONFIGURATION descriptor (index=0x00), index=0, length=9)
USB keyboard device received GET_DESCRIPTOR req 2, index 0, language 0x0000, length 9
[9, 2, 34, 0, 1, 1, 4, 224, 250]
sending on 0: b'\t\x02"\x00\x01\x01\x04\xe0\xfa'
it stops alway at this point
System Info
OS: macOS High Sierra 10.13.6
Hardware: MacBook Pro (Retina, 15-inch, Mid 2015)
GreatFET One:
Board ID: 0
Firmware version: v2019.9.1
Part ID: a0000a30624362
Serial number: 000057cc67e631923157
Python 3.7.4
pyusb 1.0.2
Hello,
I'm hoping you can help me out. I'm currently not able to build the firmware for the NXP LPC4330 Xplorer board. I've read up on the issue here: #1 and followed the instructions here: https://github.com/greatscottgadgets/greatfet/wiki/Getting-Started-with-Firmware-Development
libopencm3
built fine, but with greatfet_usb
I get all the way here and get some errors about undeclared identifiers:
dg@iot:/opt/greatfet/firmware/greatfet_usb/build$ cmake -DBOARD=NXP_XPLORER ..
-- Fetching git submodules.
-- Building for NXP LPC4330 Xplorer.
-- Cross-compiling with the gcc-arm-embedded toolchain
-- Toolchain prefix: /usr/lib/arm-none-eabi
-- Configuring done
-- Generating done
-- Build files have been written to: /opt/greatfet/firmware/greatfet_usb/build
dg@iot:/opt/greatfet/firmware/greatfet_usb/build$ make
[ 6%] Built target libopencm3
[ 7%] Built target libgreat_module_dac
[ 9%] Built target libgreat_module_allocator
[ 12%] Built target libgreat_module_comms
[ 13%] Built target libgreat_module_ringbuffer
[ 13%] Built target libgreat_module_ad970x
[ 13%] Built target libgreat_module_scheduler
[ 14%] Built target libgreat_module_debug-backtrace
[ 19%] Built target libgreat_module_usb
[ 20%] Built target libgreat_module_gpio
[ 20%] Built target libgreat_module_usb_comms
[ 23%] Built target libgreat_module_sgpio
[ 24%] Built target libgreat_module_uart
[ 69%] Built target greatfet_usb
[ 75%] Built target libgreat_module_bsp
[ 84%] Built target libgreat
[ 85%] Building C object common/CMakeFiles/libgreatfet.dir/greatfet_core.c.obj
/opt/greatfet/firmware/common/greatfet_core.c: In function 'pin_setup':
/opt/greatfet/firmware/common/greatfet_core.c:118:41: error: 'SCU_SSP1_SCK_FUNC' undeclared (first use in this function)
scu_pinmux(SCU_SSP1_SCK, SCU_SSP_IO | SCU_SSP1_SCK_FUNC);
^~~~~~~~~~~~~~~~~
/opt/greatfet/firmware/common/greatfet_core.c:118:41: note: each undeclared identifier is reported only once for each function it appears in
/opt/greatfet/firmware/common/greatfet_core.c:119:41: error: 'SCU_SSP1_MISO_FUNC' undeclared (first use in this function)
scu_pinmux(SCU_SSP1_MISO, SCU_SSP_IO | SCU_SSP1_MISO_FUNC);
^~~~~~~~~~~~~~~~~~
/opt/greatfet/firmware/common/greatfet_core.c:120:41: error: 'SCU_SSP1_MOSI_FUNC' undeclared (first use in this function)
scu_pinmux(SCU_SSP1_MOSI, SCU_SSP_IO | SCU_SSP1_MOSI_FUNC);
^~~~~~~~~~~~~~~~~~
/opt/greatfet/firmware/common/greatfet_core.c:121:41: error: 'SCU_SSP1_SSEL_FUNC' undeclared (first use in this function)
scu_pinmux(SCU_SSP1_SSEL, SCU_SSP_IO | SCU_SSP1_SSEL_FUNC);
^~~~~~~~~~~~~~~~~~
common/CMakeFiles/libgreatfet.dir/build.make:302: recipe for target 'common/CMakeFiles/libgreatfet.dir/greatfet_core.c.obj' failed
make[2]: *** [common/CMakeFiles/libgreatfet.dir/greatfet_core.c.obj] Error 1
CMakeFiles/Makefile2:311: recipe for target 'common/CMakeFiles/libgreatfet.dir/all' failed
make[1]: *** [common/CMakeFiles/libgreatfet.dir/all] Error 2
Makefile:129: recipe for target 'all' failed
make: *** [all] Error 2
dg@iot:/opt/greatfet/firmware/greatfet_usb/build$
Is there a way to open a specific board (e.g. by serial number)? I would like to do something like:
u = facedancer.FacedancerUSBApp(serial_number=foo)
or even better:
gf = greatfet.GreatFET(serial_number=foo)
u = facedancer.FacedancerUSBApp(device=gf)
I looked through the code but didn't find a way to do this. There are some comments that mention a BOARD environment variable, but I didn't see any actual use of it.
Could you point me to the firmware needed by the NXP LPC4330 Xplorer in order to use the facedancer
I'm running into parsing issues with a descriptor blob longer than specification says:
This is from a USB headset (Plantronics C5220T). The above snapshot is from wireshark capture of the device's CONFIGURATION descriptor. As it shows, the device is reporting a 9-byte endpoint descriptor, rather than a 7-byte according to the USB specification.
I was trying to parse it using facedancer's USBEndpoint.from_binary_descriptor class and it fails at "struct.unpack" call.
Hi,
Since about a year I've been working on a new Facedancer backend for boards made by Benjamin Vernoux @bvernoux. This is a R&D project I'm doing at my company @quarkslab in direct collaboration with Benjamin.
The backend is for boards based on the WCH569 chip from WCH, a RISC-V chip which supports both USB3 and USB2. The project started with two HydraUSB3 boards connected through HSPI, but we moved to a new single board that splits the USB3/USB2 on a single chip as shown in the image below (currently in prod, nearly finished). The goal is to propose a faster backend than the current Facedancer21 and GreatFET One, support USB2 High-speed and more endpoints.
Here are some characteristics and results of this backend, which I think would make it a good addition to this project:
handle_buffer_empty
We published a blogpost a few weeks ago, but there have been quite a few changes to make the stress test work.
I'm proposing the following PRs from high to low priority :
Best,
BACKEND: greatfet
Facedancer commit: e688fe6
GreatFET firmware: Firmware version: v2021.2.1
Trying to proxy a XBox One Game-controller via FaceDancer, error received is:
greatdancer.set_up_endpoints: greatdancer: failed to configure impossible endpoint with address 4 [EINVAL]
Also tried older Facedancer repo states (end 2019)...
Any hints?
$ sudo -E python3 facedancer-usbproxy.py -v 045e -p 0b12
Using GreatDancer backend.
GreatDancer initialized
[20:55:50] <, standard request to device (GET_DESCRIPTOR: value=DEVICE descriptor (index=0x00), index=0, length=64)
[20:55:50] <: b'\x12\x01\x00\x02\xffG\xd0@^\x04\x12\x0b\x07\x05\x01\x02\x03\x01'
-- Patched device descriptor. --
[20:55:51] <, standard request to device (GET_DESCRIPTOR: value=DEVICE descriptor (index=0x00), index=0, length=18)
[20:55:51] <: b'\x12\x01\x00\x02\xffG\xd0@^\x04\x12\x0b\x07\x05\x01\x02\x03\x01'
-- Patched device descriptor. --
[20:55:51] <, standard request to device (GET_DESCRIPTOR: value=CONFIGURATION descriptor (index=0x00), index=0, length=255)
[20:55:51] <: b'\t\x02w\x00\x03\x01\x00\xa0\xfa\t\x04\x00\x00\x02\xffG\xd0\x00\x07\x05\x02\x03@\x00\x04\x07\x05\x82\x03@\x00\x04\t\x04\x00\x01\x02\xffG\xd0\x00\x07\x05\x02\x03@\x00\x04\x07\x05\x82\x03@\x00\x02\t\x04\x01\x00\x00\xffG\xd0\x00\t\x04\x01\x01\x02\xffG\xd0\x00\x07\x05\x03\x01\xe4\x00\x01\x07\x05\x83\x01@\x00\x01\t\x04\x02\x00\x00\xffG\xd0\x00\t\x04\x02\x01\x02\xffG\xd0\x00\x07\x05\x04\x02@\x00\x00\x07\x05\x84\x02@\x00\x00'
-- Storing configuration <USBConfiguration index=1 num_interfaces=3 attributes=0xA0 max_power=500mA> --
[20:55:51] <, standard request to device (GET_DESCRIPTOR: value=STRING descriptor (index=0x03), index=409, length=255)
[20:55:51] <: ̺30393731323236373333423524525
[20:55:51] <, vendor request to device (vendor request 144: value=0, index=4, length=16)
[20:55:51] <: b'(\x00\x00\x00\x00\x01\x04\x00\x01\x00\x00\x00\x00\x00\x00\x00'
[20:55:51] <, vendor request to device (vendor request 144: value=0, index=4, length=40)
[20:55:51] <: b'(\x00\x00\x00\x00\x01\x04\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01XGIP10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
[20:55:51] <, standard request to device (GET_DESCRIPTOR: value=STRING descriptor (index=0x00), index=0, length=255)
[20:55:51] <: ̄Љ
[20:55:51] <, standard request to device (GET_DESCRIPTOR: value=STRING descriptor (index=0x02), index=409, length=255)
[20:55:51] <: ̖Controller
[20:55:51] <, standard request to device (GET_DESCRIPTOR: value=DEVICE_QUALIFIER descriptor (index=0x00), index=0, length=10)
[20:55:51] < --STALLED--
[20:55:51] <, standard request to device (GET_DESCRIPTOR: value=DEVICE descriptor (index=0x00), index=0, length=18)
[20:55:51] <: b'\x12\x01\x00\x02\xffG\xd0@^\x04\x12\x0b\x07\x05\x01\x02\x03\x01'
-- Patched device descriptor. --
[20:55:51] <, standard request to device (GET_DESCRIPTOR: value=CONFIGURATION descriptor (index=0x00), index=0, length=9)
[20:55:51] <: b'\t\x02w\x00\x03\x01\x00\xa0\xfa'
[20:55:51] <, standard request to device (GET_DESCRIPTOR: value=CONFIGURATION descriptor (index=0x00), index=0, length=119)
[20:55:51] <: b'\t\x02w\x00\x03\x01\x00\xa0\xfa\t\x04\x00\x00\x02\xffG\xd0\x00\x07\x05\x02\x03@\x00\x04\x07\x05\x82\x03@\x00\x04\t\x04\x00\x01\x02\xffG\xd0\x00\x07\x05\x02\x03@\x00\x04\x07\x05\x82\x03@\x00\x02\t\x04\x01\x00\x00\xffG\xd0\x00\t\x04\x01\x01\x02\xffG\xd0\x00\x07\x05\x03\x01\xe4\x00\x01\x07\x05\x83\x01@\x00\x01\t\x04\x02\x00\x00\xffG\xd0\x00\t\x04\x02\x01\x02\xffG\xd0\x00\x07\x05\x04\x02@\x00\x00\x07\x05\x84\x02@\x00\x00'
-- Storing configuration <USBConfiguration index=1 num_interfaces=3 attributes=0xA0 max_power=500mA> --
[20:55:51] <, standard request to device (GET_STATUS: value=0, index=0, length=2)
[20:55:51] <: b'\x02\x00'
[20:55:51] >, standard request to device (SET_CONFIGURATION: value=1, index=0, length=0)
-- Applying configuration <USBConfiguration index=1 num_interfaces=3 attributes=0xA0 max_power=500mA> --
Traceback (most recent call last):
File "/home/userA/Desktop/Facedancer/facedancer-usbproxy.py", line 50, in <module>
main()
File "/home/userA/Desktop/Facedancer/facedancer-usbproxy.py", line 44, in main
d.run()
File "/home/userA/Desktop/Facedancer/facedancer/USBDevice.py", line 165, in run
self.scheduler.run()
File "/home/userA/Desktop/Facedancer/facedancer/core.py", line 509, in run
task()
File "/home/userA/Desktop/Facedancer/facedancer/USBDevice.py", line 83, in <lambda>
self.scheduler.add_task(lambda : self.maxusb_app.service_irqs())
File "/home/userA/Desktop/Facedancer/facedancer/backends/greatdancer.py", line 765, in service_irqs
self._handle_setup_events()
File "/home/userA/Desktop/Facedancer/facedancer/backends/greatdancer.py", line 368, in _handle_setup_events
self._handle_setup_event_on_endpoint(i)
File "/home/userA/Desktop/Facedancer/facedancer/backends/greatdancer.py", line 402, in _handle_setup_event_on_endpoint
self.connected_device.handle_request(request)
File "/home/userA/Desktop/Facedancer/facedancer/USBProxy.py", line 241, in handle_request
self._proxy_out_request(req)
File "/home/userA/Desktop/Facedancer/facedancer/USBProxy.py", line 296, in _proxy_out_request
req, data = f.filter_control_out(req, data)
File "/home/userA/Desktop/Facedancer/facedancer/filters/standard.py", line 95, in filter_control_out
self.device.configured(configuration)
File "/home/userA/Desktop/Facedancer/facedancer/USBProxy.py", line 220, in configured
self.maxusb_app.configured(configuration)
File "/home/userA/Desktop/Facedancer/facedancer/backends/greatdancer.py", line 740, in configured
self._configure_endpoints(configuration)
File "/home/userA/Desktop/Facedancer/facedancer/backends/greatdancer.py", line 730, in _configure_endpoints
self.api.set_up_endpoints(*endpoint_triplets)
File "/home/userA/.local/lib/python3.9/site-packages/pygreat/comms.py", line 1108, in method
return self.execute_command(verb_number, in_format, out_format, name=name, class_name=class_name,
File "/home/userA/.local/lib/python3.9/site-packages/pygreat/comms.py", line 1263, in execute_command
return self.comms_backend.execute_command(self.CLASS_NUMBER, verb, in_format,
File "/home/userA/.local/lib/python3.9/site-packages/pygreat/comms.py", line 770, in execute_command
raw_result = self.execute_raw_command(class_number, verb, payload, timeout,
File "/home/userA/.local/lib/python3.9/site-packages/pygreat/comms_backends/usb.py", line 391, in execute_raw_command
future_utils.raise_from(self._exception_for_command_failure(error_number, pretty_name), None)
File "/home/userA/.local/lib/python3.9/site-packages/future/utils/__init__.py", line 403, in raise_from
exec(execstr, myglobals, mylocals)
File "<string>", line 1, in <module>
pygreat.comms.CommandFailureError: greatdancer.set_up_endpoints: greatdancer: failed to configure impossible endpoint with address 4 [EINVAL]
$ sudo lsusb -vvv -d 045e:0b12
Bus 007 Device 003: ID 045e:0b12 Microsoft Corp. Controller
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 255 Vendor Specific Class
bDeviceSubClass 71
bDeviceProtocol 208
bMaxPacketSize0 64
idVendor 0x045e Microsoft Corp.
idProduct 0x0b12
bcdDevice 5.07
iManufacturer 1 Microsoft
iProduct 2 Controller
iSerial 3 30393731323236373333423524525
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x0077
bNumInterfaces 3
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 71
bInterfaceProtocol 208
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 4
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 4
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 1
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 71
bInterfaceProtocol 208
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 4
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 2
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 71
bInterfaceProtocol 208
iInterface 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 1
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 71
bInterfaceProtocol 208
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x03 EP 3 OUT
bmAttributes 1
Transfer Type Isochronous
Synch Type None
Usage Type Data
wMaxPacketSize 0x00e4 1x 228 bytes
bInterval 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 1
Transfer Type Isochronous
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 71
bInterfaceProtocol 208
iInterface 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 1
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 71
bInterfaceProtocol 208
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x04 EP 4 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x84 EP 4 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
can't get device qualifier: Resource temporarily unavailable
can't get debug descriptor: Resource temporarily unavailable
Device Status: 0x0002
(Bus Powered)
Remote Wakeup Enabled
While testing numap-scan
from nu-map's (https://github.com/sprout42/nu-map/tree/umap2_python3_updates) against facedancer's current master branch (2281b57), I encounter the following error:
[ERROR ] Traceback (most recent call last):
File "/usr/local/lib/python3.6/dist-packages/numap-2.0.2-py3.6.egg/numap/apps/scan.py", line 50, in run
device.run()
File "/usr/local/lib/python3.6/dist-packages/Facedancer-2019.3.2-py3.6.egg/facedancer/USBDevice.py", line 166, in run
self.scheduler.run()
File "/usr/local/lib/python3.6/dist-packages/Facedancer-2019.3.2-py3.6.egg/facedancer/core.py", line 506, in run
task()
File "/usr/local/lib/python3.6/dist-packages/Facedancer-2019.3.2-py3.6.egg/facedancer/USBDevice.py", line 84, in
self.scheduler.add_task(lambda : self.maxusb_app.service_irqs())
File "/usr/local/lib/python3.6/dist-packages/Facedancer-2019.3.2-py3.6.egg/facedancer/backends/GreatDancerApp.py", line 756, in service_irqs
self._handle_transfer_events()
File "/usr/local/lib/python3.6/dist-packages/Facedancer-2019.3.2-py3.6.egg/facedancer/backends/GreatDancerApp.py", line 470, in _handle_transfer_events
self._handle_transfer_complete_on_endpoint(i, self.HOST_TO_DEVICE)
File "/usr/local/lib/python3.6/dist-packages/Facedancer-2019.3.2-py3.6.egg/facedancer/backends/GreatDancerApp.py", line 556, in _handle_transfer_complete_on_endpoint
self.connected_device.handle_request(self.pending_control_request)
File "/usr/local/lib/python3.6/dist-packages/Facedancer-2019.3.2-py3.6.egg/facedancer/USBDevice.py", line 236, in handle_request
handler_entity = recipient.device_class
AttributeError: 'USBEndpoint' object has no attribute 'device_class'
I still need to investigate a bit further to see why USBEndpoint causes this.
This is the tracking issue for the Facedancer 3.1.0 release.
It's probably silly, but I just purchased the GreatFET One to try illuminating what the ALSA driver is missing, that windows isn't, to get the Roland Boutique D-05's USB digital audio working under GNU/Linux.
Since facedancer-usbproxy.py didn't work at all with the 2018 firmware the GreatFET One arrived with, I updated its firmware to the current git:
gf info
Found a GreatFET One!
Board ID: 0
Firmware version: git-v2020.1.2-18-g12efb0f
Part ID: a0000a30724f6e
Serial number: 000057cc67e631177857
With the current firmware I definitely have gotten a lot farther, as it waits for me to plug into the target (windows computer) before crashing. A USB keyboard, rather than the D-05, works perfectly, by the way.
This is what the Roland Boutique D-05 looks like to lsusb -v:
Bus 001 Device 005: ID 0582:01ff Roland Corp.
Couldn't open device, some information will be missing
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 255 Vendor Specific Class
bDeviceSubClass 0
bDeviceProtocol 255
bMaxPacketSize0 64
idVendor 0x0582 Roland Corp.
idProduct 0x01ff
bcdDevice 1.00
iManufacturer 1
iProduct 2
iSerial 3
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x010e
bNumInterfaces 4
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 0
iInterface 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 2
bInterfaceProtocol 2
iInterface 0
** UNRECOGNIZED: 06 24 f1 01 00 00
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 1
bNumEndpoints 1
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 2
bInterfaceProtocol 2
iInterface 0
** UNRECOGNIZED: 07 24 01 01 00 01 00
** UNRECOGNIZED: 0b 24 02 01 02 04 18 01 00 77 01
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x0d EP 13 OUT
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0070 1x 112 bytes
bInterval 1
INTERFACE CLASS: 06 24 f1 04 12 00
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 2
bNumEndpoints 1
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 2
bInterfaceProtocol 2
iInterface 0
** UNRECOGNIZED: 07 24 01 01 00 01 00
** UNRECOGNIZED: 0b 24 02 01 02 04 18 01 00 77 01
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x0d EP 13 OUT
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0070 1x 112 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 2
bInterfaceProtocol 1
iInterface 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 1
bNumEndpoints 1
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 2
bInterfaceProtocol 1
iInterface 0
** UNRECOGNIZED: 07 24 01 07 00 01 00
** UNRECOGNIZED: 0b 24 02 01 02 04 18 01 00 77 01
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x8e EP 14 IN
bmAttributes 37
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Implicit feedback Data
wMaxPacketSize 0x0070 1x 112 bytes
bInterval 1
INTERFACE CLASS: 06 24 f1 04 12 00
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 2
bNumEndpoints 1
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 2
bInterfaceProtocol 1
iInterface 0
** UNRECOGNIZED: 07 24 01 07 00 01 00
** UNRECOGNIZED: 0b 24 02 01 02 04 18 01 00 77 01
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x8e EP 14 IN
bmAttributes 37
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Implicit feedback Data
wMaxPacketSize 0x0070 1x 112 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 3
bInterfaceProtocol 0
iInterface 0
** UNRECOGNIZED: 06 24 f1 02 01 01
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x03 EP 3 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x84 EP 4 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 1
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 3
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x03 EP 3 OUT
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 4
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x85 EP 5 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 4
And here's how facedancer reacts to it:
#./facedancer-usbproxy.py -v 0582 -p 01ff
Using GreatDancer backend.
GreatDancer initialized
[23:41:01] <, standard request to device (GET_DESCRIPTOR: value=DEVICE descriptor (index=0x00), index=0, length=64)
[23:41:01] <: b'\x12\x01\x00\x02\xff\x00\xff@\x82\x05\xff\x01\x00\x01\x01\x02\x03\x01'
-- Patched device descriptor. --
[23:41:01] <, standard request to device (GET_DESCRIPTOR: value=DEVICE descriptor (index=0x00), index=0, length=18)
[23:41:01] <: b'\x12\x01\x00\x02\xff\x00\xff@\x82\x05\xff\x01\x00\x01\x01\x02\x03\x01'
-- Patched device descriptor. --
[23:41:01] <, standard request to device (GET_DESCRIPTOR: value=CONFIGURATION descriptor (index=0x00), index=0, length=255)
[23:41:01] <: b'\t\x02\x0e\x01\x04\x01\x00\x80\xfa\t\x04\x00\x00\x00\xff\xff\x00\x00\t\x04\x01\x00\x00\xff\x02\x02\x00\x06$\xf1\x01\x00\x00\t\x04\x01\x01\x01\xff\x02\x02\x00\x07$\x01\x01\x00\x01\x00\x0b$\x02\x01\x02\x04\x18\x01\x00w\x01\x07\x05\r\x05p\x00\x01\x07%\x01\x00\x00\x00\x00\x06$\xf1\x04\x12\x00\t\x04\x01\x02\x01\xff\x02\x02\x00\x07$\x01\x01\x00\x01\x00\x0b$\x02\x01\x02\x04\x18\x01\x00w\x01\x07\x05\r\x05p\x00\x01\x07%\x01\x00\x00\x00\x00\t\x04\x02\x00\x00\xff\x02\x01\x00\t\x04\x02\x01\x01\xff\x02\x01\x00\x07$\x01\x07\x00\x01\x00\x0b$\x02\x01\x02\x04\x18\x01\x00w\x01\x07\x05\x8e%p\x00\x01\x07%\x01\x00\x00\x00\x00\x06$\xf1\x04\x12\x00\t\x04\x02\x02\x01\xff\x02\x01\x00\x07$\x01\x07\x00\x01\x00\x0b$\x02\x01\x02\x04\x18\x01\x00w\x01\x07\x05\x8e%p\x00\x01\x07%\x01\x00\x00\x00\x00\t\x04\x03\x00\x02\xff\x03\x00\x00\x06$\xf1\x02\x01\x01\x07\x05\x03\x02\x00\x02\x01\x07\x05\x84\x02\x00\x02\x00\t\x04\x03\x01\x02\xff\x03\x00'
Traceback (most recent call last):
File "./facedancer-usbproxy.py", line 50, in <module>
main()
File "./facedancer-usbproxy.py", line 44, in main
d.run()
File "/usr/src/Facedancer/facedancer/USBDevice.py", line 165, in run
self.scheduler.run()
File "/usr/src/Facedancer/facedancer/core.py", line 509, in run
task()
File "/usr/src/Facedancer/facedancer/USBDevice.py", line 83, in <lambda>
self.scheduler.add_task(lambda : self.maxusb_app.service_irqs())
File "/usr/src/Facedancer/facedancer/backends/greatdancer.py", line 765, in service_irqs
self._handle_setup_events()
File "/usr/src/Facedancer/facedancer/backends/greatdancer.py", line 368, in _handle_setup_events
self._handle_setup_event_on_endpoint(i)
File "/usr/src/Facedancer/facedancer/backends/greatdancer.py", line 402, in _handle_setup_event_on_endpoint
self.connected_device.handle_request(request)
File "/usr/src/Facedancer/facedancer/USBProxy.py", line 239, in handle_request
self._proxy_in_request(req)
File "/usr/src/Facedancer/facedancer/USBProxy.py", line 277, in _proxy_in_request
req, data, stalled = f.filter_control_in(req, data, stalled)
File "/usr/src/Facedancer/facedancer/filters/standard.py", line 51, in filter_control_in
configuration = USBDescribable.from_binary_descriptor(data)
File "/usr/src/Facedancer/facedancer/USB.py", line 83, in from_binary_descriptor
return subclass.from_binary_descriptor(data)
File "/usr/src/Facedancer/facedancer/USBConfiguration.py", line 58, in from_binary_descriptor
interfaces = cls._parse_subordinate_descriptors(data[length:total_length])
File "/usr/src/Facedancer/facedancer/USBConfiguration.py", line 78, in _parse_subordinate_descriptors
descriptor = USBDescribable.from_binary_descriptor(data[:length])
File "/usr/src/Facedancer/facedancer/USB.py", line 83, in from_binary_descriptor
return subclass.from_binary_descriptor(data)
File "/usr/src/Facedancer/facedancer/USBInterface.py", line 82, in from_binary_descriptor
= struct.unpack_from("xxBBBBBBB", data)
struct.error: unpack_from requires a buffer of at least 9 bytes for unpacking 9 bytes at offset 0 (actual buffer size is 8)
I've tried editing facedancer here and there, but so far haven't found anything that keeps the device descriptor data and works. Aside from looking at python in the past, this is my first real attempt editing it, though. This problem looked different enough from what others have posted, so I hope there's an easy, straightforward solution.
Thanks for any ideas you can offer,
Luke
Hey,
I would like to purchase a Greatfet One board,
Does it support HS USB emulation already?
Or maybe is there another board which supports this?
It will ease so much on our project.
Thanks, really great work 👍
Because this board will not be produced anymore, is there another alternative available? I mean an existing evalutation kit.
Hi~
I want to use USBProxy to sniff a mass storage device traffic ,I connect device like this:
usb mass storage <---> Linux(run facedancer) <---> greatefet one <---> Windows machine
and I change the USBProxy usbfs's Mode to 666 and run "python3 facedancer-usbproxy.py -v 0951 -p 1666".
The Windows machine shows the device cannot be identified correctly, and script hangs:
Using GreatDancer backend.
GreatDancer initialized
[21:58:10] <, standard request to device (GET_DESCRIPTOR: value=DEVICE descriptor (index=0x00), index=0, length=64)
[21:58:10] <: b'\x12\x01\x10\x03\x00\x00\x00\tQ\tf\x16\x10\x01\x01\x02\x03\x01'
-- Patched device descriptor. --
[21:58:10] <, standard request to device (GET_DESCRIPTOR: value=DEVICE descriptor (index=0x00), index=0, length=18)
[21:58:10] <: b'\x12\x01\x10\x03\x00\x00\x00\tQ\tf\x16\x10\x01\x01\x02\x03\x01'
-- Patched device descriptor. --
[21:58:10] <, standard request to device (GET_DESCRIPTOR: value=CONFIGURATION descriptor (index=0x00), index=0, length=255)
[21:58:10] <: b'\t\x02,\x00\x01\x01\x00\x80?\t\x04\x00\x00\x02\x08\x06P\x00\x07\x05\x81\x02\x00\x04\x00\x060\x03\x00\x00\x00\x07\x05\x02\x02\x00\x04\x00\x060\x03\x00\x00\x00'
-- Storing configuration <USBConfiguration index=1 num_interfaces=1 attributes=0x80 max_power=126mA> --
[21:58:11] <, standard request to device (GET_DESCRIPTOR: value=DEVICE descriptor (index=0x00), index=0, length=64)
[21:58:11] <: b'\x12\x01\x10\x03\x00\x00\x00\tQ\tf\x16\x10\x01\x01\x02\x03\x01'
-- Patched device descriptor. --
[21:58:11] <, standard request to device (GET_DESCRIPTOR: value=DEVICE descriptor (index=0x00), index=0, length=18)
[21:58:11] <: b'\x12\x01\x10\x03\x00\x00\x00\tQ\tf\x16\x10\x01\x01\x02\x03\x01'
-- Patched device descriptor. --
[21:58:11] <, standard request to device (GET_DESCRIPTOR: value=CONFIGURATION descriptor (index=0x00), index=0, length=255)
[21:58:11] <: b'\t\x02,\x00\x01\x01\x00\x80?\t\x04\x00\x00\x02\x08\x06P\x00\x07\x05\x81\x02\x00\x04\x00\x060\x03\x00\x00\x00\x07\x05\x02\x02\x00\x04\x00\x060\x03\x00\x00\x00'
-- Storing configuration <USBConfiguration index=1 num_interfaces=1 attributes=0x80 max_power=126mA> --
[21:58:12] <, standard request to device (GET_DESCRIPTOR: value=DEVICE descriptor (index=0x00), index=0, length=64)
[21:58:12] <: b'\x12\x01\x10\x03\x00\x00\x00\tQ\tf\x16\x10\x01\x01\x02\x03\x01'
-- Patched device descriptor. --
[21:58:12] <, standard request to device (GET_DESCRIPTOR: value=DEVICE descriptor (index=0x00), index=0, length=18)
[21:58:12] <: b'\x12\x01\x10\x03\x00\x00\x00\tQ\tf\x16\x10\x01\x01\x02\x03\x01'
-- Patched device descriptor. --
[21:58:12] <, standard request to device (GET_DESCRIPTOR: value=CONFIGURATION descriptor (index=0x00), index=0, length=255)
[21:58:12] <: b'\t\x02,\x00\x01\x01\x00\x80?\t\x04\x00\x00\x02\x08\x06P\x00\x07\x05\x81\x02\x00\x04\x00\x060\x03\x00\x00\x00\x07\x05\x02\x02\x00\x04\x00\x060\x03\x00\x00\x00'
-- Storing configuration <USBConfiguration index=1 num_interfaces=1 attributes=0x80 max_power=126mA> --
All:
I've been working on a new major version of FaceDancer for the past few days in an effort to clean up a lot of the things that have been bothering me. It's not yet a complete rewrite (but it will be, soon!). There are going to be a bunch of new features -- in addition to a compatibility layer that should keep old code working.
I'm particularly interested in the community's thoughts regarding a new/alternate "declarative" syntax for defining USB devices. The intent of the alternate syntax is to:
An ultra-simple example (a device that only handles one vendor request) might look like:
@use_inner_classes_automatically
class VendorOnlyDevice(USBDevice):
name : str = "Proprietary Company"
product_string : str = "Very vendor device"
vendor_id : int = 0x3456
product_id : int = 0x1234
@vendor_request_handler(number=3)
def handle_silly_request(self, request):
# NOTE: these are the old names; this will be cleaned up
self.send_control_message(b"1234")
self.ack_status_stage()
You can see a more complex example, here:
https://github.com/usb-tools/Facedancer/blob/future/facedancer/devices/keyboard.py
I welcome everyone's thoughts!
Hi Kate, I'm trying to proxy a simple USB 2.0 flash drive. There is no error in the output of Facedancer but the device never shows up for mounting and in dmesg
there are some device descriptor read/64, error -71
entries. Any ideas?
I'm trying to use facedancer with the GreatFet One card as a MITM between an XBOX One and an XBOX ELITE controller.
I'm using the code as provided on github with the last merge # 22.
I made only "aesthetic" changes to make what happens (at least for me) more readable.
The XBOX One console needs some sort of authentication to communicate with the controller, if authentication does not take place in the early stages of communication, the console stops all communication with the controller. If authentication is successful, the controller is accepted and communications take place correctly until the controller is disconnected.
I'm doing tests on both Linux and MacOS.
On linux it works quite well:
authentication does not always happen ( I need to understand why not always ), but when it happens, communications continue in a perfect way indefinitely (until I disconnect the controller). So the controller and the console work just as if the controller were directly connected to the XBOX One's USB port ( transparently as it should be ).
Some screenshots from linux with a correct authentication ( 240 bytes packet length ) :
On MacOS:
communications seem to work correctly only up to the interface configuration, then after the first two or three packets, all communications on endpoints 1 ( 0x81 ) go into timeouts ( and aborted ) and the controller is turned off by the console or simply ignored.
Some screenshots from macOS using the same code producing a timeouts loop
The red warning lines are produced by the libusb library enabling the environment variable :
LIBUSB_DEBUG = 3
"my debug" is a change I made to get some other useful information
output of dmesg ring buffer from GreatFET board :
Ring buffer contained 4070 bytes of data:
[ 629512890] usb error:transaction reports transaction error! aborting.
[ 629527829] usb error:transaction reports transaction error! aborting.
[ 629542496] usb error:transaction reports transaction error! aborting.
[ 629557969] usb error:transaction reports transaction error! aborting.
[ 629573600] usb error:transaction reports transaction error! aborting.
[ 629588786] usb error:transaction reports transaction error! aborting.
[ 629604263] usb error:transaction reports transaction error! aborting.
[ 629619572] usb error:transaction reports transaction error! aborting.
[ 629634455] usb error:transaction reports transaction error! aborting.
[ 629648476] usb error:transaction reports transaction error! aborting.
[ 629662985] usb error:transaction reports transaction error! aborting.
[ 629678413] usb error:transaction reports transaction error! aborting.
[ 629693250] usb error:transaction reports transaction error! aborting.
[ 629707458] usb error:transaction reports transaction error! aborting.
[ 629721530] usb error:transaction reports transaction error! aborting.
[ 629735958] usb error:transaction reports transaction error! aborting.
[ 629750495] usb error:transaction reports transaction error! aborting.
[ 629764261] usb error:transaction reports transaction error! aborting.
[ 629778739] usb error:transaction reports transaction error! aborting.
[ 629793001] usb error:transaction reports transaction error! aborting.
[ 629807153] usb error:transaction reports transaction error! aborting.
[ 629821123] usb error:transaction reports transaction error! aborting.
[ 629835410] usb error:transaction reports transaction error! aborting.
[ 629850782] usb error:transaction reports transaction error! aborting.
[ 629865759] usb error:transaction reports transaction error! aborting.
[ 629880134] usb error:transaction reports transaction error! aborting.
[ 629893844] usb error:transaction reports transaction error! aborting.
[ 629907865] usb error:transaction reports transaction error! aborting.
[ 629922164] usb error:transaction reports transaction error! aborting.
[ 629937000] usb error:transaction reports transaction error! aborting.
[ 629951815] usb error:transaction reports transaction error! aborting.
[ 629966533] usb error:transaction reports transaction error! aborting.
[ 629980548] usb error:transaction reports transaction error! aborting.
[ 629995301] usb error:transaction reports transaction error! aborting.
[ 630010806] usb error:transaction reports transaction error! aborting.
[ 630026408] usb error:transaction reports transaction error! aborting.
[ 630041817] usb error:transaction reports transaction error! aborting.
[ 630056143] usb error:transaction reports transaction error! aborting.
[ 630070407] usb error:transaction reports transaction error! aborting.
[ 630084097] usb error:transaction reports transaction error! aborting.
[ 630097636] usb error:transaction reports transaction error! aborting.
[ 630112586] usb error:transaction reports transaction error! aborting.
[ 630127954] usb error:transaction reports transaction error! aborting.
[ 630143228] usb error:transaction reports transaction error! aborting.
[ 630157420] usb error:transaction reports transaction error! aborting.
[ 630172405] usb error:transaction reports transaction error! aborting.
[ 630188031] usb error:transaction reports transaction error! aborting.
[ 630203561] usb error:transaction reports transaction error! aborting.
[ 630219037] usb error:transaction reports transaction error! aborting.
[ 630234589] usb error:transaction reports transaction error! aborting.
[ 630250057] usb error:transaction reports transaction error! aborting.
[ 630265404] usb error:transaction reports transaction error! aborting.
[ 630280490] usb error:transaction reports transaction error! aborting.
[ 630295712] usb error:transaction reports transaction error! aborting.
[ 630311026] usb error:transaction reports transaction error! aborting.
Output of libusb -v
: libusb_controller elite.txt
It seems that this proxy is not really transparent and some packages are lost ... I have seen that there are some firmware changes in place to solve multiple 64 bytes packets. Do you think the problem can be linked?
Any suggestions are welcome, thanks !
Stock
Hello,
I bought a GreatFet and a total phase Beagle 480 a year or so ago to help try to emulate this usb device used on a closed system.
The USB protocol is new to me. I've read through 100 pages of the USB spec.. The information the Total Phase Data Center captures is nice but it I cannot really understand what I am looking at yet. From this screenshot, can someone extract the required information needed for FaceDancer and the template to get something communicating?
Attached is a screenshot of where I think the device descriptor and device configuration is displayed
There are examples in facedancer/backends/
, but they all seem to be doing different things. Ideally the documentation mentions which classes to inherit, which methods to implement, etc.
This causes autodetection failures for anyone with a USB serial device connected when they are trying to use a non-GoodFET platform for Facedancer.
Workaround (example for Cynthion):
export BACKEND=cynthion
Fix: We should probably disable autodetection for all platforms other than GreatFET and Cynthion. If it doesn't have a unique VID/PID, we shouldn't assume things are Facedancer devices. Example for goodfet.py
:
if backend_name is None or backend_name != "goodfet":
Hi!
I'm using the Facedancer21 from int3.cc and I'm trying to run facedancer-serial.py, but it only starts working after 10 or 11 failed attempts every time I plug the board in.
The first few commands (not sure if they even are commands) I'm getting don't seem to follow the structure in readcmd()
, so len(data) != n
is always true and raises a ValueError
.
The last command just before it works is identical with the one when it works, but in the first case the next command I'm reading is empty and I'm getting an Index Error
.
Could this be an issue with the board itself?
The only information I could find about this was someone having the same problem but with a completely different script (nccgroup/umap#11), but that didn't help much either.
Here are the errors I'm getting when it doesn't work:
(including what was read in read(self, n)
)
Using MAXUSB backend.
b'80bf8a80'
b'b4ba3a584de969f7f5d1c9c9e8aeb3b297b759bdf9'
Traceback (most recent call last):
File "./facedancer-serial.py", line 8, in <module>
u = FacedancerUSBApp(verbose=1)
File "/root/Desktop/Facedancer/facedancer/core.py", line 23, in FacedancerUSBApp
return FacedancerApp.autodetect(verbose, quirks)
File "/root/Desktop/Facedancer/facedancer/core.py", line 54, in autodetect
return subclass(verbose=verbose, quirks=quirks)
File "/root/Desktop/Facedancer/facedancer/backends/GoodFETMaxUSBApp.py", line 45, in __init__
device = Facedancer(serial, verbose=verbose)
File "/root/Desktop/Facedancer/facedancer/backends/GoodFETMaxUSBApp.py", line 146, in __init__
self.reset()
File "/root/Desktop/Facedancer/facedancer/backends/GoodFETMaxUSBApp.py", line 163, in reset
c = self.readcmd()
File "/root/Desktop/Facedancer/facedancer/backends/GoodFETMaxUSBApp.py", line 204, in readcmd
+ ' bytes but received only ' + str(len(data)))
ValueError: Facedancer expected 32906 bytes but received only 21
The last time it doesn't work I get this error:
Using MAXUSB backend.
b'007f1600'
b'687474703a2f2f676f6f646665742e73662e6e65742f'
Facedancer reset
GoodFET monitor initialized
b''
Traceback (most recent call last):
File "./facedancer-serial.py", line 8, in <module>
u = FacedancerUSBApp(verbose=1)
File "/root/Desktop/Facedancer/facedancer/core.py", line 23, in FacedancerUSBApp
return FacedancerApp.autodetect(verbose, quirks)
File "/root/Desktop/Facedancer/facedancer/core.py", line 54, in autodetect
return subclass(verbose=verbose, quirks=quirks)
File "/root/Desktop/Facedancer/facedancer/backends/GoodFETMaxUSBApp.py", line 45, in __init__
device = Facedancer(serial, verbose=verbose)
File "/root/Desktop/Facedancer/facedancer/backends/GoodFETMaxUSBApp.py", line 148, in __init__
self.monitor_app.announce_connected()
File "/root/Desktop/Facedancer/facedancer/backends/GoodFETMaxUSBApp.py", line 391, in announce_connected
resp = self.device.readcmd()
File "/root/Desktop/Facedancer/facedancer/backends/GoodFETMaxUSBApp.py", line 193, in readcmd
app = b[0]
IndexError: index out of range
The number of expected bytes changes for each time I run the script:
b'80bf8a80'
b'b4ba3a584de969f7f5d1c9c9e8aeb3b297b759bdf9'
...
ValueError: Facedancer expected 32906 bytes but received only 21
b'80bf8a80'
b'b4ba5a584ee979f5bdc1cda5b496aed6c953453dff'
...
ValueError: Facedancer expected 32906 bytes but received only 21
b'80bf8b80'
b'b45a5e5ce7e979f5fdc9cda5bc97aed6c953457dff'
...
ValueError: Facedancer expected 32907 bytes but received only 21
b'80bf4b40'
b'5a2d174bbabddddfbfb273292e29c95caeb27af9'
...
ValueError: Facedancer expected 16459 bytes but received only 20
b'80bf4b40'
b'2a87e19a9779f5ddb4b3292e39c95cbeb25af9'
...
ValueError: Facedancer expected 16459 bytes but received only 19
b'80298074'
b'5d2d8ed3f19addb7725929cf31c9967729e7f9'
...
ValueError: Facedancer expected 29824 bytes but received only 19
b'80298054'
b'5d2f96ba5db7f3c9b629cf31c9965729eff9'
...
ValueError: Facedancer expected 21632 bytes but received only 18
b'00feb104'
b'106dbbf4e0e9f2e9d1aed3132eaed9765ecd3171e22b2eddf1'
...
ValueError: Facedancer expected 1201 bytes but received only 25
b'00ff2600'
b'd8e4e4f07a4f5fc7dfcfc4c6c5e45ee3c65ecec5e44f'
...
ValueError: Facedancer expected 38 bytes but received only 22
b'007f1600'
b'687474703a2f2f676f6f646665742e73662e6e65742f'
Facedancer reset
GoodFET monitor initialized
b''
...
IndexError: index out of range
Using MAXUSB backend.
b'007f1600'
b'687474703a2f2f676f6f646665742e73662e6e65742f'
Facedancer reset
GoodFET monitor initialized
b'00b10000'
MAXUSB initialized
b'40100000'
b'40100000'
... // works
Hello, thank you for your awesome work!
For the life of me I can't seem to get this working. I've tried it on two different computers, one Ubuntu, one Windows and the script always breaks here:
E:\USBStuff\Facedancer>facedancer-host-enumeration.py
Using GreatDancer Host backend.
Traceback (most recent call last):
File "E:\USBStuff\Facedancer\facedancer-host-enumeration.py", line 9, in <module>
u.initialize_device(assign_address=1, apply_configuration=1)
File "E:\USBStuff\Facedancer\facedancer\core.py", line 374, in initialize_device
self.apply_configuration(apply_configuration)
File "E:\USBStuff\Facedancer\facedancer\core.py", line 451, in apply_configuration
configuration = self.get_configuration_descriptor(index - 1)
File "E:\USBStuff\Facedancer\facedancer\core.py", line 405, in get_configuration_descriptor
descriptor = USBConfiguration.from_binary_descriptor(raw_descriptor)
File "E:\USBStuff\Facedancer\facedancer\USBConfiguration.py", line 55, in from_binary_descriptor
attributes, max_power = struct.unpack('<xBHBBBBB', data[0:length])
struct.error: unpack requires a bytes object of length 9
I'm using the GreatFET One, and I get the same error on both operating systems.
Just to try and figure out what's going on, I printed the output of the data variable just before line 55 in USBConfiguration.py and this was the value:
b'\t\x02"\x00\x01\x01\x00\x80'
I've tried changing the fmt string in line 55 to "<xBBBBBBB" instead of "<xBHBBBBB" but that just temporarily fixes the issue because then I get another error:
E:\USBStuff\Facedancer>facedancer-host-enumeration.py
Using GreatDancer Host backend.
Device initialized:
Device is: Connected
Device speed: Low speed
Port is: Enabled
Port power is: On
Line state: J
Traceback (most recent call last):
File "E:\USBStuff\Facedancer\facedancer-host-enumeration.py", line 25, in <module>
print("Attached device: {}".format(u.get_device_descriptor()))
File "E:\USBStuff\Facedancer\facedancer\core.py", line 391, in get_device_descriptor
return USBDevice.from_binary_descriptor(raw_descriptor)
File "E:\USBStuff\Facedancer\facedancer\USBDevice.py", line 98, in from_binary_descriptor
data.extend([0] * padding_necessary)
AttributeError: 'bytes' object has no attribute 'extend'
I changed it back to the original "<xBHBBBBB" because I figure that there must be something wrong on my systems since no one else has had this issue.
Any help would be greatly appreciated!
I am trying to proxy a device using a GF one.
I validated this on 2 separate operating systems, Kali and Ubuntu, virtual and bare metal, respectively. The Ubuntu installation is using Python 3.6.9 and Kali is using Python 3.8.2
I have validated I can see the device using the sample code from the Greatfet issues, so the hardware appears to be working.
`import greatfet
gf = greatfet.GreatFET()
descriptor = gf.glitchkit.usb.capture_control_in(
request= gf.glitchkit.usb.GET_DESCRIPTOR,
value = gf.glitchkit.usb.GET_DEVICE_DESCRIPTOR,
length = 18
)
print(descriptor)
b'\x12\x01\x00\x02\x00\x00\x00@P\x1d\x89\x03\x01\x01\x02\x04\x01'
However using the function in Facedancer generates the error:
`
u = FacedancerUSBHostApp(verbose=3)
Using GreatDancer Host backend.
u.initialize_device(assign_address=1, apply_configuration=1)
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib/python3.8/dist-packages/facedancer-2.9-py3.8.egg/facedancer/core.py", line 365, in initialize_device
File "/usr/local/lib/python3.8/dist-packages/facedancer-2.9-py3.8.egg/facedancer/core.py", line 401, in read_ep0_max_packet_size
File "/usr/local/lib/python3.8/dist-packages/facedancer-2.9-py3.8.egg/facedancer/core.py", line 395, in get_device_descriptor
File "/usr/local/lib/python3.8/dist-packages/facedancer-2.9-py3.8.egg/facedancer/core.py", line 386, in get_descriptor
File "/usr/local/lib/python3.8/dist-packages/facedancer-2.9-py3.8.egg/facedancer/core.py", line 291, in control_request_in
File "/usr/local/lib/python3.8/dist-packages/facedancer-2.9-py3.8.egg/facedancer/backends/greathost.py", line 369, in send_on_endpoint
OSError: Stalled!
`
As of greatscottgadgets/libgreat@ee45e39, GreatDancer needs to be updated to explicitly claim the USB interface so that performance isn't terrible.
Currently, udev on Linux gets saturated by the repeated binds and unbinds.
Device: GreatFET One
Target device: Khadas VIM3 board in fastboot mode (any other device in fastboot mode will work)
Running code:
from facedancer import FacedancerUSBHostApp
# Enumerate and configure the attached device.
u = FacedancerUSBHostApp(verbose=3)
u.initialize_device(assign_address=1, apply_configuration=1)
# Print the device state.
print("Device initialized: ")
print("\tDevice is: {}".format("Connected" if u.device_is_connected() else "Disconnected"))
# Print information about the attached device...
print("Attached device: {}".format(u.get_device_descriptor()))
u.send_on_endpoint(1, b"getvar:version\x00")
u.read_from_endpoint(1, expected_read_size=64)
The execution stalls at u.read_from_endpoint(1, expected_read_size=64)
. Debug analysis indicates that self._get_read_status() doesn't return a 'complete' status.
USB Analyzer shows that the response was send:
Did I skip any setup actions, or is the problem caused by a different factor?
Due to several possible problems while detaching the kernel driver from a device, in some cases it is useful to use the usb hotplug event to actually wait for the device to be connected and directly opening it to prevent the system to take over before.
Implementation line might be:
facedancer/facedancer/proxy.py
Line 51 in ae60b53
For reference, this way worked perfectly fine for most of my problem cases:
https://github.com/Fehr-GmbH/blackleak/blob/master/main.c#L40
I have made a simple vfat32 disk image that i can separately mount and write to, however when i try to use it when on my greatfetOne using facedancer-umass.py it stops on the first write command in the sequence. It pauses at the performing WRITE command below in bold, before eventually trying to mount again i believe. I have changed the mmap to prot=PROT_WRITE but this has not helped.
I am using Ubuntu 20.04
thanks
<-- handling READ (IN) 512:[00 00 00 01 b1 00 00 01 00 00 00 00 00 00 00]
<-- performing READ (10), lba 433 + 1 block(s)
<-- reading sector 433 [all zeroes]
--> responded with 512 bytes
<-- handling READ (IN) 512:[00 00 00 01 b2 00 00 01 00 00 00 00 00 00 00]
<-- performing READ (10), lba 434 + 1 block(s)
<-- reading sector 434 [all zeroes]
--> responded with 512 bytes
<-- handling READ (IN) 512:[00 00 00 01 b3 00 00 01 00 00 00 00 00 00 00]
<-- performing READ (10), lba 435 + 1 block(s)
<-- reading sector 435 [all zeroes]
--> responded with 512 bytes
--> handling WRITE (10) (OUT) 512:[00 00 00 00 00 00 00 01 00 00 00 00 00 00 00]
--> performing WRITE (10), lba 0 + 1 block(**s)
USB mass storage device received request <, standard request to device (GET_DESCRIPTOR: value=DEVICE descriptor (index=0x00), index=0, length=64)
USB mass storage device received GET_DESCRIPTOR req 1, index 0, language 0x0000, length 64
USB mass storage device received request <, standard request to device (GET_DESCRIPTOR: value=DEVICE descriptor (index=0x00), index=0, length=18)
USB mass storage device received GET_DESCRIPTOR req 1, index 0, language 0x0000, length 18
USB mass storage device received request <, standard request to device (GET_DESCRIPTOR: value=CONFIGURATION descriptor (index=0x00), index=0, length=32)
USB mass storage device received GET_DESCRIPTOR req 2, index 0, language 0x0000, length 32
USB mass storage device received request <, standard request to device (GET_DESCRIPTOR: value=STRING descriptor (index=0x03), index=409, length=255)
USB mass storage device received GET_DESCRIPTOR req 3, index 3, language 0x0409, length 255
USB mass storage device received request >, standard request to device (SET_CONFIGURATION: value=1, index=0, length=0)
USB mass storage device received SET_CONFIGURATION request
--> continue write with 31 more bytes of data
I'm trying to proxy and read the HID packets from an iPhone 11 Pro (to a car stereo) when the iPhone has its configuration changed to the HID one, however it just ends up stalling and doesn't progress any further.
I'm using the following to start: sudo ./facedancer-usbproxy.py -v 05ac -p 12a8
and it does change the configuration to 2 (which is the HID one), and then it seems to request the descriptor for HID (which is in fact 208 bytes)
I'm using a raspberry pi 4b (on the latest raspbian) and a GreatFET One to do this. I tried it on macOS as well to the same issue. I'm not sure what I should try next…
My setup is like this:
[iPhone] -> [rpi host]
[rpi host] -> [GreatFET host]
[Car Stereo] -> [GreatFET target]
Here's what it prints out:
Using GreatDancer backend.
GreatDancer initialized
-- backend does not support setting device speed: HIGH --
[16:30:42] <, standard request to device (GET_DESCRIPTOR: value=DEVICE descriptor (index=0x00), index=0, length=8)
[16:30:42] <: b'\x12\x01\x00\x02\x00\x00\x00@'
-- Patched device descriptor. --
[16:30:42] <, standard request to device (GET_DESCRIPTOR: value=DEVICE descriptor (index=0x00), index=0, length=18)
[16:30:42] <: b'\x12\x01\x00\x02\x00\x00\x00@\xac\x05\xa8\x12\x05\x12\x01\x02\x03\x04'
-- Patched device descriptor. --
[16:30:42] <, standard request to device (GET_DESCRIPTOR: value=CONFIGURATION descriptor (index=0x00), index=0, length=9)
[16:30:42] <: b"\t\x02'\x00\x01\x01\x05\xc0\xfa"
[16:30:42] <, standard request to device (GET_DESCRIPTOR: value=CONFIGURATION descriptor (index=0x00), index=0, length=39)
[16:30:42] <: b"\t\x02'\x00\x01\x01\x05\xc0\xfa\t\x04\x00\x00\x03\x06\x01\x01\x0f\x07\x05\x02\x02\x00\x02\x00\x07\x05\x81\x02\x00\x02\x00\x07\x05\x83\x03@\x00\n"
-- Storing configuration <USBConfiguration index=1 num_interfaces=1 attributes=0xC0 max_power=500mA> --
[16:30:42] <, standard request to device (GET_DESCRIPTOR: value=CONFIGURATION descriptor (index=0x01), index=0, length=9)
[16:30:42] <: b'\t\x02\x95\x00\x03\x02\x06\xc0\xfa'
[16:30:42] <, standard request to device (GET_DESCRIPTOR: value=CONFIGURATION descriptor (index=0x01), index=0, length=149)
[16:30:42] <: b'\t\x02\x95\x00\x03\x02\x06\xc0\xfa\t\x04\x00\x00\x00\x01\x01\x00\x00\t$\x01\x00\x01\x1e\x00\x01\x01\x0c$\x02\x01\x01\x02\x02\x02\x03\x00\x00\x00\t$\x03\x02\x01\x01\x01\x01\x00\t\x04\x01\x00\x00\x01\x02\x00\x00\t\x04\x01\x01\x01\x01\x02\x00\x00\x07$\x01\x02\x01\x01\x00#$\x02\x01\x02\x02\x10\t@\x1f\x00\x11+\x00\xe0.\x00\x80>\x00"V\x00\xc0]\x00\x00}\x00D\xac\x00\x80\xbb\x00\t\x05\x81\x01\xc0\x00\x04\x00\x00\x07%\x01\x01\x00\x00\x00\t\x04\x02\x00\x01\x03\x00\x00\x00\t!\x11\x01\x00\x01"\xd0\x00\x07\x05\x83\x03@\x00\x01'
-- Storing configuration <USBConfiguration index=2 num_interfaces=3 attributes=0xC0 max_power=500mA> --
[16:30:42] <, standard request to device (GET_DESCRIPTOR: value=CONFIGURATION descriptor (index=0x02), index=0, length=9)
[16:30:42] <: b'\t\x02>\x00\x02\x03\x07\xc0\xfa'
[16:30:42] <, standard request to device (GET_DESCRIPTOR: value=CONFIGURATION descriptor (index=0x02), index=0, length=62)
[16:30:42] <: b'\t\x02>\x00\x02\x03\x07\xc0\xfa\t\x04\x00\x00\x03\x06\x01\x01\x0f\x07\x05\x02\x02\x00\x02\x00\x07\x05\x81\x02\x00\x02\x00\x07\x05\x83\x03@\x00\n\t\x04\x01\x00\x02\xff\xfe\x02\x11\x07\x05\x04\x02\x00\x02\x00\x07\x05\x85\x02\x00\x02\x00'
-- Storing configuration <USBConfiguration index=3 num_interfaces=2 attributes=0xC0 max_power=500mA> --
[16:30:42] <, standard request to device (GET_DESCRIPTOR: value=CONFIGURATION descriptor (index=0x03), index=0, length=9)
[16:30:42] <: b'\t\x02u\x00\x03\x04\x08\xc0\xfa'
[16:30:42] <, standard request to device (GET_DESCRIPTOR: value=CONFIGURATION descriptor (index=0x03), index=0, length=117)
[16:30:42] <: b'\t\x02u\x00\x03\x04\x08\xc0\xfa\t\x04\x00\x00\x03\x06\x01\x01\x0f\x07\x05\x02\x02\x00\x02\x00\x07\x05\x81\x02\x00\x02\x00\x07\x05\x83\x03@\x00\n\t\x04\x01\x00\x02\xff\xfe\x02\x11\x07\x05\x04\x02\x00\x02\x00\x07\x05\x85\x02\x00\x02\x00\t\x04\x02\x00\x00\xff\xfd\x01\x19\t\x04\x02\x01\x02\xff\xfd\x01\x19\x07\x05\x86\x02\x00\x02\x00\x07\x05\x05\x02\x00\x02\x00\t\x04\x02\x02\x02\xff\xfd\x01\x19\x07\x05\x86\x02\x00\x02\x00\x07\x05\x05\x02\x00\x02\x00'
-- Storing configuration <USBConfiguration index=4 num_interfaces=3 attributes=0xC0 max_power=500mA> --
[16:30:42] <, standard request to device (GET_DESCRIPTOR: value=DEVICE_QUALIFIER descriptor (index=0x00), index=0, length=10)
[16:30:42] <: b'\n\x06\x00\x02\x00\x00\x00@\x04\x00'
[16:30:42] <, standard request to device (GET_DESCRIPTOR: value=STRING descriptor (index=0x00), index=0, length=255)
[16:30:42] <: ̄Љ
[16:30:42] <, standard request to device (GET_DESCRIPTOR: value=STRING descriptor (index=0x02), index=409, length=255)
[16:30:42] <: ̎iPhone
[16:30:42] <, standard request to device (GET_DESCRIPTOR: value=STRING descriptor (index=0x03), index=409, length=255)
[16:30:42] <: ͒OMITTED
[16:30:42] >, standard request to device (SET_CONFIGURATION: value=2, index=0, length=0)
-- Applying configuration <USBConfiguration index=2 num_interfaces=3 attributes=0xC0 max_power=500mA> --
[16:30:42] <, standard request to device (GET_DESCRIPTOR: value=STRING descriptor (index=0x05), index=409, length=255)
[16:30:42] <: ̈PTP
[Errno 2] Entity not found
[16:30:42] <, standard request to interface (GET_DESCRIPTOR: value=REPORT descriptor (index=0x00), index=2, length=208)
[16:30:42] < --STALLED--
Here's lsusb:
Bus 001 Device 005: ID 05ac:12a8 Apple, Inc. iPhone 5/5C/5S/6/SE/7/8/X/XR
Couldn't open device, some information will be missing
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x05ac Apple, Inc.
idProduct 0x12a8 iPhone 5/5C/5S/6/SE/7/8/X/XR
bcdDevice 12.05
iManufacturer 1 Apple Inc.
iProduct 2 iPhone
iSerial 3
bNumConfigurations 4
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x0027
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 5
bmAttributes 0xc0
Self Powered
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 6 Imaging
bInterfaceSubClass 1 Still Image Capture
bInterfaceProtocol 1 Picture Transfer Protocol (PIMA 15470)
iInterface 15
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 10
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x0095
bNumInterfaces 3
bConfigurationValue 2
iConfiguration 6
bmAttributes 0xc0
Self Powered
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 1 Control Device
bInterfaceProtocol 0
iInterface 0
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdADC 1.00
wTotalLength 0x001e
bInCollection 1
baInterfaceNr(0) 1
AudioControl Interface Descriptor:
bLength 12
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 1
wTerminalType 0x0201 Microphone
bAssocTerminal 2
bNrChannels 2
wChannelConfig 0x0003
Left Front (L)
Right Front (R)
iChannelNames 0
iTerminal 0
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 2
wTerminalType 0x0101 USB Streaming
bAssocTerminal 1
bSourceID 1
iTerminal 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 1
bNumEndpoints 1
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 0
AudioStreaming Interface Descriptor:
bLength 7
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 2
bDelay 1 frames
wFormatTag 0x0001 PCM
AudioStreaming Interface Descriptor:
bLength 35
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bNrChannels 2
bSubframeSize 2
bBitResolution 16
bSamFreqType 9 Discrete
tSamFreq[ 0] 8000
tSamFreq[ 1] 11025
tSamFreq[ 2] 12000
tSamFreq[ 3] 16000
tSamFreq[ 4] 22050
tSamFreq[ 5] 24000
tSamFreq[ 6] 32000
tSamFreq[ 7] 44100
tSamFreq[ 8] 48000
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 1
Transfer Type Isochronous
Synch Type None
Usage Type Data
wMaxPacketSize 0x00c0 1x 192 bytes
bInterval 4
bRefresh 0
bSynchAddress 0
AudioStreaming Endpoint Descriptor:
bLength 7
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x01
Sampling Frequency
bLockDelayUnits 0 Undefined
wLockDelay 0x0000
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.11
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 208
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x003e
bNumInterfaces 2
bConfigurationValue 3
iConfiguration 7
bmAttributes 0xc0
Self Powered
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 6 Imaging
bInterfaceSubClass 1 Still Image Capture
bInterfaceProtocol 1 Picture Transfer Protocol (PIMA 15470)
iInterface 15
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 10
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 254
bInterfaceProtocol 2
iInterface 17
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x04 EP 4 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x85 EP 5 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x0075
bNumInterfaces 3
bConfigurationValue 4
iConfiguration 8
bmAttributes 0xc0
Self Powered
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 6 Imaging
bInterfaceSubClass 1 Still Image Capture
bInterfaceProtocol 1 Picture Transfer Protocol (PIMA 15470)
iInterface 15
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 10
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 254
bInterfaceProtocol 2
iInterface 17
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x04 EP 4 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x85 EP 5 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 253
bInterfaceProtocol 1
iInterface 25
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 1
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 253
bInterfaceProtocol 1
iInterface 25
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x86 EP 6 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x05 EP 5 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 2
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 253
bInterfaceProtocol 1
iInterface 25
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x86 EP 6 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x05 EP 5 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Any ideas?
Hi,
I'm trying to proxy a keyboard just for fun and learning. While the Nintendo Pro Controller works great, the keyboard does not. It looks like something is not reacting right to the response of the get device descriptor request. It times out.
sudo ./facedancer-usbproxy.py -v 04d9 -p 1603
NOTE: Skipping GoodFET-based devices, as pyserial isn't installed.
Using GreatDancer backend.
GreatDancer initialized
GreatDancer connected device Proxy'd USB Device
-- Reset requested! --
[14:36:57] <, standard request to device (GET_DESCRIPTOR: value=DEVICE descriptor (index=0x00), index=0, length=64)
[14:36:57] <: b'\x12\x01\x10\x01\x00\x00\x00\x08\xd9\x04\x03\x16\x10\x03\x01\x02\x00\x01'
[14:37:08] <, standard request to device (GET_DESCRIPTOR: value=DEVICE descriptor (index=0x00), index=0, length=64)
[14:37:08] <: b'\x12\x01\x10\x01\x00\x00\x00\x08\xd9\x04\x03\x16\x10\x03\x01\x02\x00\x01'
Traceback (most recent call last):
File "./facedancer-usbproxy.py", line 50, in <module>
main()
File "./facedancer-usbproxy.py", line 44, in main
d.run()
File "/home/user/Facedancer/facedancer/USBDevice.py", line 164, in run
self.scheduler.run()
File "/home/user/Facedancer/facedancer/core.py", line 492, in run
task()
File "/home/user/Facedancer/facedancer/USBDevice.py", line 84, in <lambda>
self.scheduler.add_task(lambda : self.maxusb_app.service_irqs())
File "/home/user/Facedancer/facedancer/backends/GreatDancerApp.py", line 767, in service_irqs
self._handle_setup_events()
File "/home/user/Facedancer/facedancer/backends/GreatDancerApp.py", line 368, in _handle_setup_events
self._handle_setup_event_on_endpoint(i)
File "/home/user/Facedancer/facedancer/backends/GreatDancerApp.py", line 406, in _handle_setup_event_on_endpoint
self.ack_status_stage(direction=self.DEVICE_TO_HOST)
File "/home/user/Facedancer/facedancer/backends/GreatDancerApp.py", line 145, in ack_status_stage
self.read_from_endpoint(endpoint_number)
File "/home/user/Facedancer/facedancer/backends/GreatDancerApp.py", line 269, in read_from_endpoint
while not self._transfer_is_complete(ep_num, self.HOST_TO_DEVICE):
File "/home/user/Facedancer/facedancer/backends/GreatDancerApp.py", line 429, in _transfer_is_complete
status = self._fetch_transfer_status()
File "/home/user/Facedancer/facedancer/backends/GreatDancerApp.py", line 416, in _fetch_transfer_status
return self._fetch_status_register(self.GET_ENDPTCOMPLETE)
File "/home/user/Facedancer/facedancer/backends/GreatDancerApp.py", line 328, in _fetch_status_register
raw_status = self.device.vendor_request_in(self.vendor_requests.GREATDANCER_GET_STATUS, index=register_number, length=4)
File "/home/user/gf-fd-venv/lib/python3.7/site-packages/GreatFET-0.0-py3.7.egg/greatfet/board.py", line 396, in vendor_request_in
value=value, index=index, timeout=timeout)
File "/home/user/gf-fd-venv/lib/python3.7/site-packages/GreatFET-0.0-py3.7.egg/greatfet/board.py", line 384, in _vendor_request
request, value, index, length_or_data, timeout)
File "/home/user/gf-fd-venv/lib/python3.7/site-packages/pyusb-1.0.2-py3.7.egg/usb/core.py", line 1043, in ctrl_transfer
File "/home/user/gf-fd-venv/lib/python3.7/site-packages/pyusb-1.0.2-py3.7.egg/usb/backend/libusb1.py", line 883, in ctrl_transfer
File "/home/user/gf-fd-venv/lib/python3.7/site-packages/pyusb-1.0.2-py3.7.egg/usb/backend/libusb1.py", line 595, in _check
usb.core.USBError: [Errno 110] Operation timed out
Any ideas?
Can I use this api with a raspi zero only, without the facedancer or greatfet? Thank you.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.