While inspecting the Pokémon Go application, I incidentally found information on the forthcoming Pokémon Go Plus device. Basically, this is the Pokémon IoT: a connected wristband with a button (to throw a pokéball, for instance), an RGB LED, and vibration capability (e.g to notify of nearby pokémon).
The device has not yet released, and the software is still under development: as you can see below, version 0.29.x corresponds to "BETA4".
Implementation in version 0.31.0 has changed considerably, with lots of code shifted inside its native library libpgpplugin.so. And no, this is not a PGP / GPG plugin. PGP probably means Pokémon Go Plus ;)
At first look, we immediately see that the device will communicate via Bluetooth Low Energy (just like many IoT devices, such as Fitbit Flex, Beam toothbrush, etc).
Currently, 4 BLE services are planned:
Basically, in version 0.31.0, a client service receives the intents com.nianticlabs.pokemongoplus.service.ToClient. The "extra" action of the intent (e.g "batteryLevel", "encounterId", "pokestop") calls the appropriate method from the ClientBridge class. For example, respectively sendBatteryLevel(), sendEncounterId() and sendPokestopId(). Those methods then call the native functions implemented in libpgpplugin.so.
So, most of the interesting stuff should occur in the native library. Below, we see the JNI stub which corresponds to public native void sendEncounterId(long arg1).
The code retrieves a native handle with type "J", where J stands for "long" in JNI. Unfortunately, to my understanding so far, communication with the device has not yet been implemented.
Consequently, we have to look at earlier versions (v0.29.x) to get more hints as to how the Pokémon Go Plus device may work.
Indeed, versions 0.29.x show a few test messages to send to the Pokémon Go Plus device. For example, there are the bytes to send to have the device blink red, or what to do on the device when a pokémon is captured.
The format for those patterns is coded as follows.
There is a header with:
Then, the 3-byte pattern has:
Let's confirm this with the pattern getBlinkRed():
The other patterns repeat the process of flashing the red light and vibrating, then stopping. This has the expected effect of having the device "blink" red.
Let's see now what getCaptureSucceeded does. I'll go a bit faster this time, but you can follow bit per bit.
The header indicates we have 24 3-byte patterns. Actually, they consist of 4 patterns repeated 6 times.
This will probably look like a glowing red, then green, then blue, with vibration impulses.
There are several other patterns to "decode" (getDowserProximity1(), getPokemonCaught(), getReachedPokestop(), getSpawnedPokemon()...) and possibly funny ones like getMorseGame1(). You can use my Python script to decode them.
All of this reversing will naturally need to be confirmed with a real Pokémon Go Plus device once it is released. Meanwhile, we never know how specs may change.
First of all, good news, I found no malicious code in the Dalvik classes nor in the native library I inspected.
Second, with all of this information readily available, hackers can build their own Pokémon Go Plus device. In fact, there are already initiatives for that with Arduino.
It is also possible to get ready for alternate usages of these devices. For instance, if as expected the device does generate a random nonce, it can be used as a hardware random number generator as I did with the Fitbit Flex. Or code your own pattern.
Finally, depending on how good the pairing mechanism turns out to be, an attacker or a jealous competitor might send dummy patterns to have your device run out of battery (repeated vibration), or send fake alarms telling you that you are close to a Pokémon. Note that this has already happened without the Pokémon Go Plus, so be cautious where you go!
Thanks to Raphael Le Bras for his tips on Pokémon Go.
-- the Crypto Girl