Demystifying the ADB Protocol

Android

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. 20250104-143650.jpeg

  • 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_devices.png

  1. adb client connects with server through TCP handshake
  2. adb client sent 000Chost:version to server,000C means request length is 12,host:version is request message;
  3. adb server responses OKAY and adb version to client, 00040029 means response length is 4 and version is 41;
  4. adb server closes the connection;
  5. adb client connects with server again and sends 000Chost:devices to server
  6. adb server responses OKAY and devices list to client, 00160A021FDD4001P1\tdevices means response length is 22, device’s serial is 0A021FDD4001P1;
  7. adb server closes the connection

Example​​: adb shell

adb_shell.png

  1. adb client connects with server through TCP handshake;
  2. adb client sent 000Chost:version to server,000C means request length is 12,host:version is request message;
  3. adb server responses OKAY and adb version to client, 00040029 means response length is 4 and version is 41
  4. adb server closes the connection;
  5. adb client connects with server again and sends 000Dhost:features to get features;
  6. adb server responses OKAY and features list to client;
  7. adb server closes the connection;
  8. adb client sends 0021shell,v2,TERM=xterm-256color,pty: to server
  9. 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.

usb_connect.png

  1. adb server listens usb connection. When android devices connect with host computer, adb server registers usb transport.

  2. adb sever sends A_CNXN message to adbd, A_CNXN message packet is

    A_CNXN.jpeg

    command is A_CNXN,args0 is 0x01000001 which means adb protocol version, args1 is 0x00100000 which means max payload size is 1024 * 1024, next is data_length, data_crc32 and magic.

    payload is on following packet.

    host-features.png

  3. adbd receives A_CNXN command and sends A_AUTH command, args0 is 0x00000001 which means ADB_AUTH_TOKEN, args1 is zero. data_length is 0x14, data_crc32 is zero. token is on following packet.

    AUTH1.png

  4. adb server receives A_AUTH command and ADB_AUTH_TOKEN args, adb server generates a sign using token and private keys. Then adb server sends A_AUTH command, args0 is ADB_AUTH_SIGNATURE , arg1 is zero;

    auth2.png

  5. adbd receives A_AUTH command and ADB_AUTH_SIGNATURE args. adbd verifies sign. If failed, adbd send A_AUTH command again and arg0 is ADB_AUTH_TOKEN.

  6. if doesn’t have private keys, adb server sends A_AUTH command, args0 is ADB_AUTH_RSAPUBLICKEY , args1 is zero, payload is user_key;

    Auth3.png