USB Endpoint
The USB Endpoint plugin was designed with developers of non-standard USB devices in mind and is also an invaluable tool for those looking to reverse engineer USB interfaces. It provides direct, low-level access to USB transactions, making it indispensable when standard USB classes and system-level drivers fall short. Powered by the libusb library, the plugin offers an intuitive, interactive interface for performing all 4 kinds of USB transfers (control, bulk, interrupt, and isochronous), bridging the gap for custom and proprietary USB development scenarios.
Basic Setup
If on Windows, ensure that your USB device is associated with a supported driver before starting. You can follow Microsoft’s official guide, or use a tool such as Zadig.

In IO Ninja, click the “New Session” dropdown and select a new “USB Endpoint” session

From the “Device:” dropdown menu, select the USB device you want to communicate with.

Open the device by clicking the “Open Device” button on the far side of the dropdown menu.

In the “Control” pane, check the USB interfaces you want to claim, and press the “Claim” button.
USB devices can have multiple interfaces. Claiming an interface is akin to locking it for exclusive use by the plugin, allowing data transfers to occur without interference from other software.

In the “Control” pane, check the In-endpoints you want to read, and press the “Read” button.
This sets up asynchronous listeners on IN-endpoints (data flowing from device to host), enabling real-time monitoring of incoming packets, e.g., sensor readings, device responses, or status updates.

In the “Control” pane, select the OUT-endpoint.
This endpoint handles host-to-device transfers such as commands, control codes, or payloads.

In the “Control” pane’s “USB control transfer” section, send parameters such as request type, value, and index using the built-in form. Check the log to monitor communications.
Control transfers are used for operations like getting device descriptors, setting configuration parameters, or executing proprietary commands.

Note
The “Send” button in the Transmit pane takes data from the Transmit pane and sends it to the currently selected OUT endpoint. For the “Send” button in the “Control transfer” group, if the Direction is IN, it initiates an IN-control request (e.g., to read a USB descriptor). If the Direction is OUT, then it issues an OUT-control request using the data in Transmit pane as parameters.
Adjust settings as needed via the “Settings” button (see “Settings” section below for details).
Settings

Setting |
Description |
Default |
---|---|---|
Device |
The target USB device. |
|
Auto-detach
(Linux and Mac-only)
|
Some devices may already have a kernel driver attached. If this setting is set to “True”, the plugin will automatically detach any currently attached kernel driver (when possible) so it can communicate directly with the device. If this setting is set to “False”, you’ll have to detach the kernel driver manually or ensure a compatible driver (like WinUSB) is already in use before the plugin can access the device. |
True |
Direction |
Specifies whether the control transfer is “In” (device-to-host) or “Out” (host-to-device). See available options. |
In |
Recipient |
Recipient of the USB control transfer. See available options. |
Device |
Type |
Class of the USB control request code. See available options. |
Standard |
Request |
Code of the USB control request. See available options. |
0 |
Value |
The 1st parameter of the USB control request. |
0x0000 |
Index |
The 2nd parameter of the USB control request. |
0x0000 |
Use read timeout |
For control transfers, timeouts do not apply, as a control transfer always waits for the device response and completes. For bulk/interrupt/isochronous transfers, if this setting is set to ON, read parallelism is disabled, allowing only one ongoing transfer. This transfer completes either when the Read block size is filled or when the Read timeout expires. If Use read timeout is set to OFF (default), read parallelism is enabled and Read block size is ignored; transfers are performed using the “native” size defined in the USB descriptor for that endpoint. |
False |
Read timeout |
Specify the timeout for USB read transfers. |
1000 |
Read parallelism
|
Maximum number of read requests to issue in parallel. Having more than one pending read at a time helps with increasing read throughput when incoming data arrives in rapid streams (after filling one user buffer, the kernel can immediately switch to the next one without any waiting). Increasing this number beyond 4 usually won’t yield any extra performance gains. |
4 |
Read block size (B) |
The size of each individual read block submitted to the underlying transport. |
4KB |
RX buffer size (B) |
The full size of the incoming data (RX) buffer. Affects read throughput. |
64KB |
TX buffer size (B) |
The full size of the outbound data (TX) buffer. Affects write throughput. |
2KB |
Keep read block size |
Don’t merge read blocks in RX buffer. Incoming data blocks coming in quick succession can be merged together so that IO Ninja writes them to log as a whole. When this option is set to |
False |
Keep write block size |
Don’t merge write blocks in TX buffer. Outbound data blocks sent in quick succession can be merged together before submission to the underlying transport. When this option is set to |
False |
RX buffer full notifications |
Toggle warnings in log about the incoming data (RX) buffer getting full. |
False |
Control transfer buffer size |
Specify the size of a buffer for control IN transfers. |
1024 (bits) |
Direction Options
Option |
Description |
---|---|
In |
Device-to-host data flow (IN endpoint). |
Out |
Host-to-device data flow (OUT endpoint). |
Recipient Options
Option |
Description |
---|---|
Device |
The request is directed to the device as a whole. |
Interface |
The request targets a specific interface on the device. |
Endpoint |
The request targets a specific endpoint on the device. |
Other |
The request is for an unspecified recipient (not device, interface, or endpoint). |
Type Options
Option |
Description |
---|---|
Standard |
A standard request (defined by core USB specifications). |
Class |
A class-specific request (defined by a USB device class). |
Vendor |
A vendor-specific request. |
Request Options
Option |
Description |
---|---|
Get Status |
Request the status of the specified recipient. Should return two bytes of 0x00, 0x00. |
Clear Feature |
Clear or disable a specific boolean features on the recipient. |
Set Feature |
Set or enable a specific boolean feature on the recipient. |
Set Address |
Assign a device address for all future communications. |
Get Descriptor |
Retrieve the specified descriptor from the device. |
Set Descriptor |
Update or add a descriptor on the device. |
Get Configuration |
Get the current device configuration value. |
Set Configuration |
Set the device’s configuration. |
Get Interface |
Return the currently selected alternate interface setting. |
Set Interface |
Select an alternate interface setting for a given interface. |
Synch Frame |
Set then read an endpoint’s synchronization frame number. |
For more information on device requests, please see Beyond Logic’s excellent explanation.