Hacking A Dollar Store Bluetooth Device

Hardware hackers are always looking for devices to tear apart and scavenge from. It’s hardly a secret that purchasing components individually is significantly more expensive than the minuscule cost per unit that goes along with mass manufacturing. Bluetooth devices are no exception. Sure, they’re not exactly a luxury purchase anymore, but they’re still not dirt cheap either.

Luckily for [Troy Denton], it seems dollar stores have started carrying a Bluetooth camera shutter for just a few dollars (it was three bucks, perhaps the dollar store actually means divisible-by). The device is designed to pair with a smart phone, and has two buttons allowing you to control the camera from afar. The fact that it works at all at that price is a small miracle, but the device also has potential for hacking that adds to its appeal.

Inside is a Bluetooth chips with integrated ARM controller. It connects to an EEPROM via I2C. Using an oscilloscope, an Arduino, and a Bus Pirate, [Troy] has so far succeeded in dumping and deciphering the EEPROM and was successful in renaming the device. He has high hopes that he’ll be able to discover something juicy from his preliminary explorations of the USART on the Bluetooth chip.

Ultimately he plans to document his quest to rewrite which keys the device’s buttons emulate. Once that’s accomplished, this dollar store find will have a lot of potential for cheap Bluetooth control. If you’re a reverse engineering veteran we’d love to hear some suggestions of low hanging fruit for him to explore. If you’re eager to learn more about about what you can do with Bluetooth, check out our awesome BLE primer.

62 thoughts on “Hacking A Dollar Store Bluetooth Device

    1. I knew it was a HID device, way hoping to use it to convert a folding palm keyboard to bluetooth. Found the stuff he found.

      Also was kind of thinking of it as having the potential to be kind of like a nano with bluetooth, i/o limited though.

  1. I found mine at 5 Below. Bought it with hopes that pairing it with my computer it’d send a keystroke, which it does. Was able to map it to my python script to help do my store’s inventory with.

  2. i think i saw something similar at Dollar Tree but i ignored it assuming it was the type that used the headphone connector. I’ll check there again sometime, hopefully it’s the bluetooth kind.

  3. I looked at the provided dump from the eeprom

    looks like it is the patch ram for the bt chip
    structure seems to me:
    u32 magic
    u32 num_entries
    u32 patch_addrs[num_entries]
    u8 padding[up to 0xb0]
    …patch code here

    instruction set appears to be ARMv4

    1. Yeah, Just looking at the shape of the data, after the first 32-bits from 0x05 up-to 0xb0 could be considered 32-bit integer quantities with the (little-endian) MSB set to 0. The final of those 32-bit quantities is 0x00000000.

      Then the 0xff padding from 0x90 to 0xaf. Then from 0xb0 up-to 0x1ff are 64-bit quantities in the form [04 f0 1f e5 XX YY ZZ 00], where XX and YY can be pretty varied, but ZZ is always in the range [ 00 – 03 ]. Maybe the first 32-bits are an opcode and the last 32 are an integer quantity?

      The rest looks like it’s 32-bit aligned (Lots of 0x34X bytes in the last byte of these groups), up-to 0x18f8 where there are 5 repetitions of the 64-bit patten [ 0x58 0x71 0x00 NN 0x00 NN 0x00 0x00 ] – Where NN is _mostly_ a 1-up, except for the first group where one of the 2 copies is 0x00.

      Then there’s the string “AB Shutter 3\0\0\0”.

      Then it’s finally padded-out with 0xff values to the end at 0x1b00.

    1. Awesome, keep up the good work.

      I was wondering if the serial output might get defaulted to a console, monitor or debugger if something like this was tried… http://hackaday.com/2016/08/08/pwning-with-sewing-needles/ in spirit, i.e. corrupting the output from the eprom or disconnecting it from I2C (Try it on the one that the ROM got killed, or is that behaving 100% dead now?)

      The 5871 has some ROM in it, so I’m assuming there’s some basic functions happening without the code in the 8 pin.

      1. There’s actually a ROM tool called Mix. Look for it on the Google Code or Plex sites. I had no luck. These devices also have the write-protect line high, so you have to snap it off.

        I’ve renamed mine, but I wasn’t able to find make/break codes.

        I think me and Troy are going to try decompiling the data section this weekend as he’s got more assembly skills than I do.

        If anyone wants to be added to SkullSpace’s Slack, e-mail me at edwknguy@gmail.com with the subject “SkullSpace Bluetooth”

  4. Spot on with the “divisible by” comment!
    If you pay more than a dollar for something, is it really still a dollar store?

    If a dollar store is not defined by the price of $1 and less, what’s the difference between a dollar store and every other store?

  5. If you’re in the UK, try looking in “Poundworld”, which is where I found mine. Can’t yet get it working with a Raspberry Pi, although it does work as a selfie button with a suitable phone app.

      1. Aha! If it’s the same as the one I bought, it’s not bluetooth. It’s actually a microcontroller that plays a high frequency audio tone pattern, which is then picked up by the microphone of the smartphone to trigger the camera shutter, which is why it needs a separate app. YMMV, but I could actually hear the tone mine made and confirmed it by capturing the audio signal.

  6. We have them here as well as one with zoom in and zoom out.
    I looked at the doc. he was talking about. and google translate seem to have no problems converting it to english.
    I have no time to do this or I would of.
    Im going to keep a eye on this one. this sounds like gold to me.
    Thanks great work.

  7. Just remember the dollar store also sells rechargeable usb batteries that explode and 2 GB usb sticks that don’t work, so be sure whatever you test your DS finds with you’re not too attached to.

  8. Picked up a couple at Dollarama. Same store, same packaging, but grabbed different coloured cases–the white-cased one has the same blue PCB, but another with a green case has a larger, green PCB. The green PCB uses a RDA-branded 5871 (white case is not branded). It also uses a 24c64 EEPROM, a different brand/package though.

    1. It is, the bluetooth suite provided by Jabra for their USB dongle I bought a few years ago spoiled me. But it was on windowsXP. Every other implementation on desktop windows has pissed me off. The strange thing is that what was used on windows CE/Mobile was quite workable, not super polished, but got the job done. I am actually unsure if the installed bluetooth on my laptop is working, win8/10 interfaces to it being so appalling.

    1. Is there any central place with hacking info on these?

      I’m REALLY hoping someone will find a way to make one of these into a pokemon go plus. I know there are a few projects on the pokemon go front, being able to use the hardware from one of these would be brilliant.

      1. The main task would be to find out what BT device sends to the connected phone and where that data resides.
        Here’s a link for SDK : https://5871e.codeplex.com/ you can compile it with ARM toolchain. The SDK also contains some tools to create binary EEPROM flashable, more on this later.

        See my last comment, I posted a link to entire EEPROM dump. This is what I’ve understood after reading the docs and comparing it with EEPROM.
        1) starting 8 bytes are information head. (This is what blogger also found).
        2) starting two bytes are used for chip validation, if you change those values then the device won’t work.

        Then there is a section of config values which configures the how BT device would interact with its host:

        3) At address 0xD4 (see EEPROM dump), the value 0x1C indicates sleep time of the device.

        4) The next byte at address 0xD5 indicates the ioCapabilty of BT device. This link explains what is ioCapability in detail :http://blog.bluetooth.com/bluetooth-pairing-part-1-pairing-feature-exchange/, the default value is 0x02 which is the value for ‘KeyboardOnly’. If you change that to 0x04 it will ask for pairing key.

        5) There is also a byte for variable _config_eeprom_testdebug which has 6 different config values:
        HID_DEBUG_UART 0x01
        HID_DEBUG_SLEEP 0x04
        HID_DEBUG_LOW_POWER 0x08
        HID_DEBUG_SNIFF_3 0x010
        HID_DEBUG_SPP 0x020
        These are defined in the header files in the src folder of SDK.

        6) From address 0x15E to 0x12B, the entire block holds the data under name ‘SDP keyboard descriptor’. I tried to zero-out the entire block but nothing happened.

        7) From the address 0x1FB0, next 6 bytes is the MAC address of the BT device. Changing these values would change the MAC.

        8) The values at 0x1FC0 to 0x1FD9 are unique for each BT device. (I tested 3 BT devices). So my guess is they are the data for pairing keys.

        This is all I found in the EEPROM dump. I also connected the Arduino to UART interface as the blogger did. All I got is the 4 digits ‘4314’, I’m not sure what they mean, but if you see the source code there’s a function called p_spp_rx_ack which sends some data to UART lines. So it could be the those ACK values ( I stand to be corrected) which BT send when it finishes the EEPROM reading.

        Finally, as I said earlier, there’s a tool called MIX_SDK_toolset which converts .pac files which are available in a folder called ‘pac’. into an EEPROM flashable .bin files. You can open this files in Hex editor and see the contents.

        .There also a section in EEPROM called ‘data’ in which vendor specific data resides. Unfortunately, I couldn’t find what exact data BT sends to the Host device.

        For fun, I had made a Python script which lets you control LED using BT device. link: https://www.hackster.io/adikhandkar/selfie-blink-control-leds-using-selfie-bluetooth-remote-93558e

        1. Interesting.
          I now just assume that BT-Keyboards working like USB-HID, then the HEX-scancodes would be 28 for enter and 80 for volume up. This would match in your dump at address 1790 and the other guy’s one at 3170.

          Maybe just changing those values will change the Keys pressed? I currently have no setup to flash the chip but will create one if i find the time. You could try it meantime?

        2. Thanks! for the link to hackster.io.

          How could something similar be implemented in an ESP32? Using for example the Arduino IDE … How to detect the id of the selfie button and what modifications should be considered in your python program to run on an ESP32? Of course I appreciate any advice.

  9. I finally broke down and grabbed a green one from Dollarama…

    The most significant difference IMO is ALL PINS ARE BROUGHT OUT of the 5871 to pads, not all connected to anything, probably the same ones as show on the headline pic are connected.

    This is of great significance to me, because now I can retreat to a mountaintop for 2 years and learn to solder-ninja enough to break them out. :-D

    I am not sure if someone mentioned it already, couldn’t see it, and might have been in one of the links, but part of what’s in the EEPROM should be a keymap, basically maps column and row to key code.

    Anyhoo, after gawping gormlessly at the black one with board identical to header pic for weeks, trying to figure how exactly the hell I could pervert it to my will, I think I might actually be able to get started with this green one. I’m wanting to convert a folding palm keyboard to BT. (Because folding palm keyboards are the model M of portable keyboards, that’s why. Though maybe I could grab another greenie and make a wireless model M too.)

    However, the black one might come in handy still, have I think a couple of columns and rows on it, so when the keyboard reamapping is figured out then maybe can do a WASD or arrow key gamepad type deally.

  10. It’s nice to find cheap Bluetooth things. The clicker I have uses an RDA5871 and an 24C64. The bottom side has convenient test points for SDA, SCL, /WC so there is no micro soldering involved. It’s easy to get an EEPROM dump out and to modify it.

    One of the things that most annoys me with BT and Android is that many cheap things represent themselves as qwerty. This causes the soft keyboard to never appear (unless you set an option). Wouldn’t it be better to have the clicker not appear as qwerty? The EEPROM dump clearly shows the HID report descriptor. All you have to do is to modify it so that it doesn’t say that it can generate alpha chars (I believe that Android looks specifically for “Q”).

    95 06 Report count (6)
    75 08 Report size (8)
    15 00 Logical minimum (0) <– change to 15 1E (means I send no alpha, first key is "1")
    26 FF 00 Logical maximum (255)
    05 07 Usage page (Keyboard)
    19 00 Usage minimum (Keyboard no event) <– change to 19 1E
    29 FF Usage maximum (255)
    81 00 Input (Array, Absolute)

    There are actually 4 separate HID reports, keyboard, 2 x consumer control & custom.

    (My version has the two altered bytes at 0x0199 and 0x01a0, null-terminated name at 0x1b44.)

    The USB scan codes are still in the code somewhere. I haven't found that. Still, Enter & Volume Up are not too bad.

    1. The little button sends a keyboard key code, the big button sends a consumer control.
      The USB keycode for the little button is in the ARM code, 0x1aa4=28 10 A0 E3
      The 28 is Enter, make it what you will.
      I haven’t dug down to where the big button sends the consumer control,
      but you can just change it in the HID report descriptor, 0x01e9=09 E9
      The E9 is Volume up, make it what you will (CD is media play/pause).

      I’ll have to do a bit more work to figure out how to make both keycode or both consumer.

    2. Well, I think I’m screaming into a barrel here, but here are the mods for the two keystroke solution.
      Page down/page up seems to me a fairly useful thing. I’ll use it in any case.

      0199: 00 -> 1e
      01a0: 00 -> 1e

      1aa4: 28 -> 4b ; page down

      1abc: 03 -> 08

      1ac0: 0f -> 10
      1ac1: 00 -> 90
      1ac2: a0 -> c5
      1ac3: e3 -> e5
      1ac4: 73 -> 4e ; page up
      1ac5: fe -> 10
      1ac6: ff -> a0
      1ac7: eb -> e3
      1ac8: 0f -> 00
      1ac9: 60 -> 00
      1aca: c5 -> a0
      1acb: e5 -> e3
      1acc: 08 -> 9b
      1acd: 00 -> fe
      1ace: 00 -> ff
      1acf: ea -> eb
      1ad0: 0f -> 06
      1ad1: 60 -> 00
      1ad2: c5 -> 00
      1ad3: e5 -> ea

      Please give me feedback if the model you have uses the RDA5871 and matches this code.

      1. This deserves its own write up/blog somewhere.
        Great work!

        I’ve been looking for a bt remote to do simple video recording WITH pause ability and haven’t found anything. (simple recording without post editing to cut/etc)
        Recently found “open camera” which I can modify the source code for, so with your eeprom edits I should be able to rig up some small button/big button to start/stop + pause.

        Now to find a dollarama that has them in stock so I can try this tomorrow. (not paying amazon $10, and aliexpress will take 2 weeks)

  11. Hi Renate,

    I have the same chip, but not in a clicker or Cheap dollar store remote.
    I do have it in a ipad mini size keyboard that can be used for windows ios and android…(different key settings).
    I’m looking for getting away from entering a various 4 pin digit.
    But i do know that the key mapping is not in the eprom but on the 5871 chip.


Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.