Breaking

BlackBerry 10 USB Modes

So we got these shiny new BlackBerry Q10 and Z10 device laying on the desk one morning. It’s my first BlackBerry, I have to admit, but never the less, the hole wushy GUI and touchy glass stuff wasn’t my main concern, instead i took a look at the stuff going on while you connect the phone (do i have to call it blackberry? its a phone, isn’t it?) to your computer.

When you attach the phone to USB without the RIM host driver installed, the phone will show up as a “Blackberry Playbook (CD-Rom mode)” and serve a mass-storage read only CD image with an installer and the host drivers.

# lsusb -v -s 1:3
Bus 001 Device 003: ID 0fca:8020 Research In Motion, Ltd.
 Blackberry Playbook (CD-Rom mode)
#

If the host driver is installed, is will signalize the phone to switch over in the connected mode, in which the mass-storage device disappears and the proprietary RIM communication interface comes up.

# lsusb -v -s 1:4
Bus 001 Device 004: ID 0fca:8012 Research In Motion, Ltd.
#

This behavior is common with USB 3G dongles and there is a linux tool that can switch a lot of devices to their second mode. usb_modeswitch is based on libusb and quite straight forward.

So we have to identify the magic signaling of the RIM host driver. Under windows, I installed the “BlackBerry Device Manager” from the CD image of the phone and also usbpcap together with a wireshark version >= 1.10.0rc1. Sniffing the USB interface showed this:

blackberry-usb

First the device enumeration takes place, the device descriptor is requested from the host and the device answers with a device descriptor for the “CD-Rom” mode:

Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x0fca Research In Motion, Ltd.
  idProduct          0x8020 Blackberry Playbook (CD-Rom mode)
  bcdDevice            2.00
  iManufacturer           1 Research In Motion, Ltd.
  iProduct                2 RIM Disk Device
  iSerial                 3 dab25d420e20cabeaa2367ec5f40a455a849fe70

Then the configuration descriptor is requested from the host and the device answers with a configuration including an mass-storage interface:

Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           32
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              500mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         8 Mass Storage
      bInterfaceSubClass      6 SCSI
      bInterfaceProtocol     80 Bulk-Only
      iInterface              0

After the initial device enumeration the host driver sends two unknown control messages to the phone (the two marked packets) and after that a second device enumeration takes place. So again one sees the device descriptor and configuration descriptor exchange. With one difference, this time the phone shows up with a different device ID (0x8012 vs 0x8020) and a different configuration:

Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x0fca Research In Motion, Ltd.
  idProduct          0x8012 
  bcdDevice            2.40
  iManufacturer           1 Research In Motion, Ltd.
  iProduct                2 RIM Network Device
  iSerial                 3 dab25d420e20cabeaa2367ec5f40a455a849fe70
Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         2 Communications
      bInterfaceSubClass      2 Abstract (modem)
      bInterfaceProtocol    255 Vendor Specific (MSFT RNDIS?)
      iInterface              0 
      CDC Header:
        bcdCDC               10.01
      CDC Call Management:
        bmCapabilities       0x00
        bDataInterface          0
      CDC ACM:
        bmCapabilities       0x00
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x85  EP 5 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval               4
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass        10 CDC Data
      bInterfaceSubClass      0 Unused
      bInterfaceProtocol      0 
      iInterface              0 
      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     0x07  EP 7 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0

Now that we have identified the signaling to switch the phone into the second mode, the next step is to integrate this into usb_modeswitch. As the signalling happens on the control channel, its not done with a device configuration file, but a small patch to the usb_modeswitch sources gives the special BlackBerry mode:

void switchBlackberryMode ()
{
    int ret;
    SHOW_PROGRESS(output,"Sending Blackberry control message 1 ...\n");
    ret = usb_control_msg(devh, USB_TYPE_VENDOR | USB_RECIP_DEVICE | \
        USB_ENDPOINT_IN, 0xb1, 0x0000, 0, buffer, 8, 1000);
    if (ret != 8) {
        fprintf(stderr, \
        "Error: sending Blackberry control message 1 failed (error %d). Aborting.\n\n",\
        ret);
        exit(1);
    } else
        SHOW_PROGRESS(output," OK, Blackberry control message 1 sent\n");

    SHOW_PROGRESS(output,"Sending Blackberry control message 2 ...\n");
    ret = usb_control_msg(devh, USB_TYPE_VENDOR | USB_RECIP_DEVICE | \
        USB_ENDPOINT_IN, 0xa9, 0x000e, 0, buffer, 2, 1000);
    if (ret != 2) {
        fprintf(stderr, \
        "Error: sending Blackberry control message 2 failed (error %d). Aborting.\n\n",\
        ret);
    exit(1);
    } else
        SHOW_PROGRESS(output," OK, Blackberry control message 2 sent\n");
}

This function does the same thing as the RIM host driver, it first sends a USB control message of type 0xb1 with value 0x00 and a length of 8 and then a message of type 0xa9 with value 0x0e and a length of 2 (The two marked packages in the screen shot).

If the phone is in the second mode, one can load the linux rndist_host driver:

# modprobe rndis_host

And see a network interface spawning:

# dmesg | tail
[197166.202262] usb 2-1.2: usb_probe_device
[197166.202272] usb 2-1.2: configuration #1 chosen from 1 choice
[197166.205276] usb 2-1.2: adding 2-1.2:1.0 (config #1, interface 0)
[197166.205384] rndis_host 2-1.2:1.0: usb_probe_interface
[197166.205387] rndis_host 2-1.2:1.0: usb_probe_interface - got id
[197166.210253] rndis_host 2-1.2:1.0: rndis media connect
[197166.238763] rndis_host 2-1.2:1.0 usb0: register 'rndis_host' at usb-0000:00:1d.0-1.2,
RNDIS device, 96:eb:cd:27:cd:2a

It speaks DHCP for comfort:

# ifconfig usb0 up
# dhcpcd -n usb0
dhcpcd[25645]: usb0: offered 169.254.195.202 from 169.254.195.201

And finally we can ping and even nmap the phone:

# ping 169.254.195.201
PING 169.254.195.201 (169.254.195.201) 56(84) bytes of data.
64 bytes from 169.254.195.201: icmp_seq=1 ttl=255 time=1.44 ms
64 bytes from 169.254.195.201: icmp_seq=2 ttl=255 time=0.730 ms
64 bytes from 169.254.195.201: icmp_seq=3 ttl=255 time=0.710 ms
^C
--- 169.254.195.201 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2001ms
rtt min/avg/max/mdev = 0.710/0.961/1.445/0.343 ms
# nmap -sSV -A -O -p0- 169.254.195.201
Nmap scan report for 169.254.195.201
Host is up (0.00071s latency).
Not shown: 65529 closed ports
PORT     STATE SERVICE             VERSION
80/tcp   open  http?
|_http-methods: GET HEAD POST
|_http-title: 404 Not Found
139/tcp  open  netbios-ssn         Samba smbd 3.X (workgroup: WORKGROUP)
443/tcp  open  ssl/https?
|_http-methods: GET HEAD POST
|_http-title: 404 Not Found
| ssl-cert: Subject: commonName=PlayBook: 94:eb:cd:29:87:2d/organizationName=Research In Motion Limited
| Issuer: commonName=PlayBook: 94:eb:cd:29:87:2d/organizationName=Research In Motion Limited
| Public Key type: rsa
| Public Key bits: 3072
| Not valid before: 2011-03-01T00:00:00+00:00
| Not valid after:  2021-03-01T00:00:00+00:00
| MD5:   c321 2fe0 8bae f0dd fe0f 1c5f fe9b 6370
|_SHA-1: 3078 3b2d fbdb 2332 14ed 43d5 85bd 563b 4220 f024
|_ssl-date: 2013-07-23T17:42:13+00:00; +2m49s from local time.
|_sslv2: server supports SSLv2 protocol, but no SSLv2 cyphers
445/tcp  open  netbios-ssn         Samba smbd 3.X (workgroup: WORKGROUP)
1111/tcp open  ssl/lmsocialserver?
4455/tcp open  unknown
8443/tcp open  ssl/https-alt?
| ssl-cert: Subject: commonName=PlayBook: 94:eb:cd:29:87:2d/organizationName=Research In Motion Limited
| Issuer: commonName=PlayBook: 94:eb:cd:29:87:2d/organizationName=Research In Motion Limited
| Public Key type: rsa
| Public Key bits: 3072
| Not valid before: 2011-03-01T00:00:00+00:00
| Not valid after:  2021-03-01T00:00:00+00:00
| MD5:   c321 2fe0 8bae f0dd fe0f 1c5f fe9b 6370
|_SHA-1: 3078 3b2d fbdb 2332 14ed 43d5 85bd 563b 4220 f024
|_ssl-date: 2013-07-23T17:42:13+00:00; +2m49s from local time.
|_sslv2: server supports SSLv2 protocol, but no SSLv2 cyphers

If that doesn’t look like some kind of linux with Samba installed 😉

cheers and have a good one

/daniel