UE Boom Reverse Engineering
My adventure in trying to reverse engineer the bluetooth message format for a UE Boom speaker. I wanted to turn off bluetooth low energy to test to see if it improves battery life. However, the new app doesn’t support that setting option anymore, and I don’t have an Android phone new enough that supports BLE to disable the feature. Therefore, I went on a journey to try and figure out how to disable the feature.
Here is the old app running on a Nexus S which only has bluetooth 2.1 and therefore sees an error message.
Reverse Engineering
-
Take the legacy ue boom apk and decompile it into a jar file using dex2jar
./d2j-dex2jar.sh path/to/your-app.apk
-
Create a java project to import that jar as a library and start looking around repo
-
Write unit tests to output the correct hex codes needed for specific commands using the decompiled jar, I converted the following hex commands
-
Adjust Volume Up by One
04 01 BB 01 01
-
Announce Battery Level
02 01 6B
-
Set Sonfication (Conga)
03 01 65 01
-
Set Sonfication (None)
03 01 65 00
-
Emit Sound (Power On)
04 01 6C 60 C0
-
Set BLE State Off
03 01 B9 00
-
Set BLE State On
03 01 B9 01
-
-
Install bluetooth python tooling (ubuntu 21.10) to send data via rfcomm socket
sudo apt install python3.9 sudo add-apt-repository universe sudo apt install python3-pip sudo apt install libbluetooth-dev pip install pybluez
-
Writing a python program to test sending data using pybluez library
blue.pyfrom bluetooth import * import sys uuid = "00001101-0000-1000-8000-00805F9B34FB" addr = "88:C6:26:xx:xx:xx" service_matches = find_service( uuid = uuid, address = addr ) if len(service_matches) == 0: print("not found") sys.exit(0) for i in range(len(service_matches)): m = service_matches[i] print(m) m = service_matches[0] try: sock=BluetoothSocket( RFCOMM ) sock.connect((m["host"], m["port"])) except bluetooth.btcommon.BluetoothError: print("unable to connect") sys.exit(0) # example commands # send battery annoucement #sock.send(bytes.fromhex('02 01 6B')) (1) # send sonfication #sock.send(bytes.fromhex('03 01 65 00')) # play power on sound #sock.send(bytes.fromhex('04 01 6C 60 C0')) # sets BLE to off #sock.send(bytes.fromhex('03 01 B9 00')) sock.close()
-
Run program, success!
$ python3 blue.py {'service-classes': ['1101'], 'profiles': [], 'name': 'LWACP', 'description': None, 'provider': None, 'service-id': None, 'protocol': 'RFCOMM', 'port': 1, 'host': '88:C6:26:xx:xx:xx'}
Other Interesting Stuff
Here’s some other random stuff I found about bluetooth and bluetooth low energy.
UE Boom BLE Characteristics
Querying the gatt for characteristics information
$ gatttool -I
[ ][LE]> connect xx:xx:xx:xx:xx:xx
Attempting to connect to xx:xx:xx:xx:xx:xx
Connection successful
[xx:xx:xx:xx:xx:xx][LE]> primary
attr handle: 0x0001, end grp handle: 0xffff uuid: 000061fe-0000-1000-8000-00805f9b34fb
[xx:xx:xx:xx:xx:xx][LE]> characteristics 0x0001 0xffff
handle: 0x0002, char properties: 0x08, char value handle: 0x0003, uuid: c6d6dc0d-07f5-47ef-9b59-630622b01fd3
handle: 0x0005, char properties: 0x0a, char value handle: 0x0006, uuid: 16e009bb-3862-43c7-8f5c-6f654a4ffdd2
handle: 0x0008, char properties: 0x0a, char value handle: 0x0009, uuid: 16e005bb-3862-43c7-8f5c-6f654a4ffdd2
handle: 0x000b, char properties: 0x02, char value handle: 0x000c, uuid: 54f7f292-7ebb-4267-83c2-8e6ee7e881ff
handle: 0x000d, char properties: 0x02, char value handle: 0x000e, uuid: 00002a28-0000-1000-8000-00805f9b34fb
handle: 0x000f, char properties: 0x02, char value handle: 0x0010, uuid: 00002a25-0000-1000-8000-00805f9b34fb
handle: 0x0011, char properties: 0x02, char value handle: 0x0012, uuid: 00002a00-0000-1000-8000-00805f9b34fb
handle: 0x0013, char properties: 0x02, char value handle: 0x0014, uuid: 00002a19-0000-1000-8000-00805f9b34fb
handle: 0x0015, char properties: 0x02, char value handle: 0x0016, uuid: 4356a21c-a599-4b94-a1c8-4b91fca02a9a
handle: 0x0017, char properties: 0x0a, char value handle: 0x0018, uuid: 03ed06ef-6f39-4b62-8143-e2cc6d8a3cd9
handle: 0x0019, char properties: 0x02, char value handle: 0x001a, uuid: 765c2f02-4292-45c6-b69c-725e131f97a2
handle: 0x001b, char properties: 0x02, char value handle: 0x001c, uuid: 00002a27-0000-1000-8000-00805f9b34fb
handle: 0x001d, char properties: 0x02, char value handle: 0x001e, uuid: 015c9ee9-f3bf-4f2c-a35b-58267432c9ca
handle: 0x001f, char properties: 0x0a, char value handle: 0x0020, uuid: 69c0f621-1354-4cf8-98a6-328b8faa1897
handle: 0x0021, char properties: 0x08, char value handle: 0x0022, uuid: 8da149b6-5d82-11e5-885d-feff819cdc9f
handle: 0x0023, char properties: 0x0a, char value handle: 0x0024, uuid: fd6c01c5-25d5-4cd0-8806-52486311bd32
handle: 0x0025, char properties: 0x08, char value handle: 0x0026, uuid: b8387326-c355-4efc-b258-a67a38c00efd
handle: 0x0027, char properties: 0x02, char value handle: 0x0028, uuid: 5e72ccf6-f526-4bfb-b334-0204a75c84ff
handle: 0x0029, char properties: 0x02, char value handle: 0x002a, uuid: 00002a1a-0000-1000-8000-00805f9b34fb
Example characteristics queries:
Device name UUID: 00002a00-0000-1000-8000-00805f9b34fb
-
char-read-uuid
00002a00-0000-1000-8000-00805f9b34fb
-
handle:
0x0012
value:55 45 20 42 4f 4f 4d 20 32 00
-
Hex to Ascii → UE Boom
Battery Level UUID: 00002a19-0000-1000-8000-00805f9b34fb
-
char-read-uuid
00002a19-0000-1000-8000-00805f9b34fb
-
handle:
0x0014
value:5d
-
Hex to Dec → 93
Power On via BLE
From the gist you can power on the device if BLE is enabled.
#!/bin/sh
set -ue
HANDLE=0x0003 (1)
VALUE=4480ebedc17401 (2)
MAC=88:C6:26:xx:xx:xx (3)
gatttool -b $MAC --char-write-req --handle=$HANDLE --value=$VALUE
1 | HANDLE ⇒ is the command hex code that should be sent |
2 | VALUE ⇒ is the phone or computer bluetooth mac address + "01" at the end. VALUE=4480ebedc17401 is 44:80:eb:ed:c1:74+01 . You can get the mac address of your computers bluetooth device by running bluetoothctl show or hcitool dev |
3 | MAC ⇒ is the UE Boom mac address |
iOS Bluetooth Sniffing
Bluetooth sniff ios/macos https://www.bluetooth.com/blog/a-new-way-to-debug-iosbluetooth-applications/