Demystifying the ADB Protocol
Have you ever typed adb devices
in your terminal and wondered what magic happens behind the scenes? As Android developers, we use ADB (Android Debug Bridge) daily, but few understand the intricate dance between its components. Let’s pull back the curtain and explore the fascinating communication protocols that make our developer workflows possible.
The ADB Trio: Understanding Key Components
ADB operates through three coordinated components:
1. ADB Client
Your command-line companion that initiates requests (e.g., adb shell, adb install);
2. ADB Server
The persistent background maestro managing device connections;
3. ADB Daemon (adbd)
The Android device’s resident helper executing commands;
A detailed and clear overview of the interactions between these components is provided by Google.
- adb client <—> adb server: a smart socket builds on top of TCP/IP socket with protocol which allows targets a device after the connection is initalized.
- adb server <—> adbd: adb server can connect with physical devices through usb or TCP/IP and connect with emulators through TCP/IP.
ADB Client <—> ADB Server
After you inputs commands in terminal like adb devices
or adb start-server
etc,adb client would wrapper command and args in request message and connects with adb server which listens on 127.0.0.1:5037/tcp
by default, then sends the message to adb server.
Handle Commands
The adb client converts commands into request message. Some examples are as follows:
ADB Command | Request Message |
---|---|
adb devices | host:devices |
adb disconnect 0A021FDD4001P1 | host:disconnect:0A021FDD4001P1 |
adb kill-server | host:kill |
adb tcpip:5555 | tcpip:5555 |
adb shell | shell,v2,TERM=xterm-256,pty: |
Protocol Between ADB Client and Server
The protocol between adb client and server is similar to LTV(Length Type Value). A request‘s first four hexadecimal bytes indicates the length of the request and follows by the request message.
- Length (4-byte header)
- Request Message
Let’s look at some examples:
Example: adb devices
- adb client connects with server through TCP handshake
- adb client sent
000Chost:version
to server,000C
means request length is 12,host:version
is request message; - adb server responses
OKAY
and adb version to client,00040029
means response length is4
and version is41
; - adb server closes the connection;
- adb client connects with server again and sends
000Chost:devices
to server - adb server responses
OKAY
and devices list to client,00160A021FDD4001P1\tdevices
means response length is 22, device’s serial is0A021FDD4001P1
; - adb server closes the connection
Example: adb shell
- adb client connects with server through TCP handshake;
- adb client sent
000Chost:version
to server,000C
means request length is 12,host:version
is request message; - adb server responses
OKAY
and adb version to client,00040029
means response length is 4 and version is 41 - adb server closes the connection;
- adb client connects with server again and sends
000Dhost:features
to get features; - adb server responses
OKAY
and features list to client; - adb server closes the connection;
- adb client sends
0021shell,v2,TERM=xterm-256color,pty:
to server - adb server responses OKAY
Some requests are handled directly by adb server(request starts with “host”). In contrast, some requests are handled by Android Devices. Those requests are forward by the server to adbd.
ADB Server <—> adbd
adb server communicates with adbd using a new protocol which can be carried over either USB or TCP/IP.
Protocol
The protocol contains a 24-byte header and follows by payload.
struct message {
unsigned command; // command identifier constant, like A_CNXN, A_AUTH...
unsigned args0; // command first argument
unsigned args1; // command second argument
unsigned data_length; // length of payload
unsigned data_crc32; // crc32 of data payload
unsigned magic; // command ^ 0xffffffff
}
Connection Between Server and ADBD
Before adb server sends message to adbd, they must build connect with each other. Unlike TCP, the connection between adb server adbd doesn’t need handshake.
-
adb server listens usb connection. When android devices connect with host computer, adb server registers usb transport.
-
adb sever sends
A_CNXN
message to adbd,A_CNXN
message packet iscommand is
A_CNXN
,args0 is 0x01000001 which means adb protocol version, args1 is 0x00100000 which means max payload size is1024 * 1024
, next is data_length, data_crc32 and magic.payload is on following packet.
-
adbd receives
A_CNXN
command and sendsA_AUTH
command, args0 is 0x00000001 which meansADB_AUTH_TOKEN
, args1 is zero. data_length is 0x14, data_crc32 is zero. token is on following packet. -
adb server receives
A_AUTH
command andADB_AUTH_TOKEN
args, adb server generates a sign using token and private keys. Then adb server sendsA_AUTH
command, args0 isADB_AUTH_SIGNATURE
, arg1 is zero; -
adbd receives
A_AUTH
command andADB_AUTH_SIGNATURE
args. adbd verifies sign. If failed, adbd sendA_AUTH
command again and arg0 isADB_AUTH_TOKEN
. -
if doesn’t have private keys, adb server sends
A_AUTH
command, args0 isADB_AUTH_RSAPUBLICKEY
, args1 is zero, payload is user_key;