Aquaboutic | Focus Security Research | Vulnerability Exploit | POC


safe customer, safe information platform

Posted by ulberg at 2020-03-19

On the first day of working in this company, there were a lot of things that made me crazy. In this pile of things, there is a health monitoring bracelet that can be customized. From a technical point of view, it's cool to be able to monitor your health anytime, anywhere.

On the outside of the bracelet, there is no other logo except FCC ID: 2ahftid115 printed on the back. After searching, I found that the name of this device is id115, and there are also some pictures of internal structure. Looking carefully, we can see that the largest chip is written with "n51822", which indicates that MCU is probably Nordic's nrf51822, a 32-bit arm Mo CPU supporting low-power Bluetooth. In theory, this can be programmed to do things other than the existing functions of the bracelet.

Before and after removing the bracelet

Before disassembling it, I found a bracelet using the same chip and similar on Google. Many people have successfully disassembled the bracelet.

It's not easy to open it. The black plastic cover is stuck on the gray plastic back cover. I use a hair dryer to heat the glue to soften it, and then use a knife to carefully cut the glue to make sure that the bracelet won't be hurt too much. After disassembling, I confirm that nrf51822 is used. Later, I bought a similar bracelet, but this bracelet uses the MCU of Texas Instruments. This difference needs special attention.

Nrf51822 vs. ballpoint pen

Find a way to talk to it

According to the manual, two pins of serial wire debug (SWD) can be used for programming / debugging. This means two things, if we want to talk to it:

Fortunately, there are many exposed gaskets on the board. Their presence means that further debugging / testing / validation is required. I think there must be a cool engineer who reserves these gaskets. For people like me, this is a gift for us. Not all the gaskets are marked. I made a mark according to my guess.

Front and back sides of PCB board

Using a cheap USB microscope, I took some positive and negative pictures of the board, trying to track the trace from MCU to gasket.

Track swdio and swdclk on both sides of the board

Note that this is a multilayer PCB with through holes on it. So we need to track both sides of the board. Using these images, we can trace swdio and swdclk from chip to IO and CLK gasket. This also confirms that the pin of "CLK" marked on the board is actually swdclk. The pin on its right is swdio. We can get the first mapping table.

Open chip surgery

In order to access the two pins of SWD, I welded a thin wire to each contact pad on the board.


The next goal is to try to program something else. To run the simplest program, we need to make sure that:

In this case, the "Hello, world" program is to realize the continuous flashing of LD. Even so, it is not easy. First, there is no led on the board. If we add another one ourselves, we must find out where to connect. This adds another degree of freedom to the problem. There is no free lunch in the world. I only connect two LEDs on P1 and P2, hoping to find the corresponding pins on MCU.

P1 P2

Messy connection

To be able to use the j-link emulator, you need to download the driver and command-line program from the segger website. If you are using Mac OS, you can install homebrew. Support is provided by caskroom / Drivers / segger JLINK. After installation, you can use the command sequence jlinkexe to communicate with the SWD emulator.

caskroom/drivers/segger-jlink JLinkExe

Later, I downloaded and unzipped the Nordic's nrf5 SDK (I used version 12.3.0). Mining the samples in the SDK, obviously we need a compiler that knows how to output the arm program, so I installed GCC ARM embedded (which can also be installed through homebrew).


Browse the SDK related posts on the developer forum of Nordic, and find that this is the commonly used development board. SDK is pre configured with some variables of development package. In order to directly talk with MCU, we need to modify some settings in SDK.

Your browser does not support Video Tags

horse race lamp

I spent a lot of time to understand how nrf5 system makes the program run, and finally understand the context. You can see two blinking LEDs in the video above. So I created a GitHub repository, and I wrote makefiles. One of the biggest tricks is to find some variables of nrf51822, for example, my ram is only 16kb. Considering these factors, we need to make some adjustments to the linker script.


Digital IO

As I mentioned, flashing the LED also involves hoping and guessing which pin of MCU is connected to P1 and P2, and P1 and P2 are connected to LEDs. The easiest way is to keep the digital IO pin up and down. To my surprise, both LEDs are on. What surprises me even more is that the vibrating motor can also be turned on and off.

P1 P2 P1 P2

Manually, I identified the following mapping relationships.


In debugging, the ability to talk to a computer is invaluable. The j-link emulator supports real time transfer (RTT). RTT chips send and receive data between computers. Use it by including the header file ාinclude "segger ﹐ RTT. H" and calling the function segger ﹐ RTT ﹐ writestring(). To read it on the computer, you need to use the command sequence jlinkrtlogger in the j-link package.

#include "SEGGER_RTT.h" SEGGER_RTT_WriteString() jlinkrttlogger


Another challenging task is to turn on the OLED display. The common OLED display in the market uses ssd1306 driver / controller to communicate with MCU in serial, such as SPI, I2C.

I find it difficult to buy 96 × 32 pixel display in general stores. It seems that this resolution is not a conventional model. On the Google search screen, "qt1316p01a", the best match is a Chinese website. I found the closest one in global express, but there is no other document except for the pin name.

OLED pin definition from Alibaba Global Express

If the above table is accurate, it can be seen from SCL, SDA and res pins that it supports I2C bus. If we can find three reasonable connections between nrf51822 pin and OLED pin, it will be a good start. Let's use a microscope again.

Trace OLED data pin

A new correspondence table is established preliminarily.

I2C protocol involves more things than simple protocol like UART. One of the biggest advantages is to support multiple master and slave devices on the same bus. This adds a little more complexity. To be small, we need to know that MCU should communicate with the slave device; to be large, we need to know not only the physical pin, but also the "logical" address of the physical pin for OLED display.

Fortunately, there is an example of an I2C scanner in the nrf5 SDK. In short, it attempts to communicate with every possible logical address and returns a report when there is a response at the other end. A version I modified is here to run and view the output:

$ make # ... $ make flash # ... $ make log # ... TWI scaner TWI device detected 0x3c

That's good news. We have reason to believe that the display screen is really recognized, and it does use I2C bus. According to Google search, 0x3c is the general address of such devices.


Now, we can try to send some pixels to the display. There are no abstract libraries available at this level. In the document of ssd1306, we found some low-level methods to send data to the display screen. This process consists of a number of column configuration commands. It includes setting the screen direction, writing mode and size. After that, the data byte sequence displayed on the screen is sent to the graphic display data RAM (gddram) of the display.

To get the right configuration, I took a look at the adafruit's ssd1306 library and tried to give a similar command. I spend the most time here in this project. It's very time-consuming to clear all the details. Up to now, there are still some behaviors that I can't parse, but the display can display data normally.

Drew a hard coded bitmap

This is a sample program.

With these settings, the display is divided into 4 lines (pages) with 96 lines. So the height of each page is 8 pixels. The data of the first byte sent will be placed vertically on the first column; the data of the second byte will occupy the unknown of the second row; the third row is similar until the 96th row. When the first page is finished, a similar process will be continued on the second page.

In other words, this is the expected result. In the following video, the results are different: first, some odd columns are filled, then even columns, and finally, a similar cycle process.

Your browser does not support video label debugging for bitmap display in slow playback version

It took me a long time to figure out why I could see meaningless content on the screen, and then it took me some time to adjust the configuration to fix it. Finally, I put down my self-esteem and realized this strange rendering logic in the program. Let's stop today!

Arduino Tour

When I mine the adafruit's ssd1306 library, I hope there is a way to "simulate" Arduino specific bits in nrf51822. In fact, an experienced God has already done similar projects, and this project is more than that. He uses nrf5 SDK to implement Arduino core library.

With this project, we can open Arduino ide to select nrf5 board, and we can use Arduino's existing ecological development program. I fork this project and add support for our Bracelet board. You can select Tools > board > id115 fitness Bracelet (nrf51822) from the drop-down menu.

Tools > Board > ID115 Fitness Bracelet(nRF51822)

Adafruit ssd1306 library uploaded through Arduino ide without any patches

This also means that we can use adafruit's OLED library. To my surprise and gratification, OLED also has the rendering order of "odd first, then even prime". I'm glad to have forked this library. Now we have a variety of abstract methods instead of the low-level methods we used before, such as drawing text.

The traditional "Hello, world!"

Simulated IO

In addition to digital IO, "on, off.". Nrf51822 has 10 pins for reading analog inputs. This is useful, such as reading the current power. According to the document, when the input is 0V, we will read 0; when the input is VCC, we will read 1023; when the input voltage is between it, it also corresponds to the corresponding value.

0V VCC 1023

I regularly output the value of analog signal and draw the complete signal result.

Effect of vibration plate and charging on analog input

I think the P0.05 pin is related to the state of charge. When charging, its value will increase, and when not charging, it will decrease. I suspect that the p0.26 pin is connected to the acceleration sensor output, and its value will soar when I shake the bracelet. P0.03 and p0.04 may also be connected to the acceleration sensor output, but this behavior may correspond to the second-order effect of the chip input. For example, note that in the first figure, when the acceleration sensor needs more energy, the battery power (pin5) will also shake. Here is an example of a second-order effect.

P0.05 P0.26 P0.03 P0.04

The code can be found on the sketch. Raw data and drawing scripts are here. Now we can add a few more lines to our mapping table.


In the original firmware, touch the designated position of the bracelet screen to light the screen. If I remember correctly, pressing and holding it can be used to time. It's not a physical click, it's a capacitive sensor that works well. Using the same method to find the digital output, I found its connection with MCU.

Your browser does not support video label buttons

The code can be found here.

Low power Bluetooth (ble)

Nrf5's Bluetooth capabilities are implemented using a software device called softdevice. It is a precompiled binary contained in the stack of ble. It should run independently of the application. There are many versions of softdevice. Finding the right version depends on the SDK version and the chip version.

In the document (unfortunately, there is no direct link) compatibility table, you can find the SDK version and softdevice version corresponding to the specified chip version. For me, the chip is marked with "qfaaho", which has 256 KB flash memory and 16 KB raw, and is compatible with softdevice S130.

There are some sample programs using software S130 in the 12.3 SDK I used. Compared with the programs we have swiped so far, these programs are directly swiped to address 0x0. Now we need to brush softdevice to address 0x0, and the actual address is 0x1b000. After startup and initialization, to illustrate this, I made an example similar to Binky. But the behavior observed here is consistent from softdevice, except that we need to make sure that softdevice has been written before.

0x0 0x0 0x1b000 $ make # ... $ make flash-softdevice # ... $ make flash # ... $ make log # ... Hello,world!

It can be said that the simplest "Hello world" program in Bluetooth applications is to turn a device into a beacon. Beacons only broadcast themselves, and the responsibility of the monitor is to detect and respond to beacons within its scope. This SDK provides such an example under the same ble app beacon. It assumes that the softdevice S130 has been nearly burned before.

ble_app_beacon s130

Here, we communicate directly with the chip, not through the SDK, which makes things more difficult. In addition, I have to adjust the size of RAM (as I learned from the blinky example), another problem that is hard to track. It turns out that the ble stack uses a crystal oscillator to perform time sensitive tasks. The SDK example assumes an external crystal oscillator. I used to use thousands of printfs to figure this out. I need to change the configuration flag to use the composite clock generator to solve this problem. Beacon source code can be found here.


BLE + Arduino

Once the ble sample program using the nrf5 SDK is running properly, and you understand the ram and crystal trap. I watched Arduino's running environment again and again. Sandeepmistry / Arduino bleepiphalal is another great project for the person who did the aruino-nrf5 project. It provides a nice abstraction of the internal details of setting up ble peripherals.

Your browser doesn't support video tags using ble to light blue LEDs (using this app)

To my surprise, I don't have the fork library. The author of arduino-nrf5 project spent some time to make all boards configurable, so he needs to select the appropriate softdevice and crystal oscillator from the drop-down menu Tools > low frequency clock > integrated. It's amazing. As you can see in the video above, I wrote a quick start example of switching LEDs.

Tools > Low Frenquency Clock > Synthesized

Next step

At this time, after staring at the board for several hours in a few weeks, I am very looking forward to putting it back in the back of the drawer and putting it there for a while.

Note: the original author has authorized