The Pokewalker was a pedometer that was released with Heart Gold/Soul Silver in 2010. Since then, people have been trying to reverse how the device works without success. Dmitry (an crazy reverse engineer who works at Google) took on this challenge.
The first part of the article goes over the hardware of the Pokewalker. It appears that this was mostly from online and publicly available data sheets.
The Pokewalker communicates over infrared. Crazy enough, the Pokemon game cartridge itself had the IR hardware, not the Nintendo DS! To reverse the protocol, the author just recorded a bunch of traffic and correlated it with actions happening in the game.
The SIR signaling at 115,200 and 8n1. From there, it was time to decode the protocol. The data had a bunch of 0xAAs and 0x55s. Normally, the most frequent data being sent is 0x00s and 0xFFs. So, the author deduced that the bytes being sent were being XORed with 0xAA. The packets had a header with the command type and length, then a custom implementation of LZ compression.
So, the real question is how do we get in? The EEPROM chip is used to store data and can be read out easily using SPI. In-circuit debugging is supported, but chip will self-erase if programmed, so no way to dump it that way. This makes the situation really hard, as we are attacking blind!
Dmitry has a good motto: "assume that any code you encounter was written by a drunk student." The main point of entry is through the IR. What can we be done here?
The author messed with the compression algorithm, trying to find the mistakes of a drunk student. What could be done to a compression algorithm?
- Change the size of the decompression.
- Decompress to a larger size than expected.
- Double compression attacks
In the end, the bug was that while decompressing LZ backreferences, size checks are only performed at the end, and they are performed for equality and not 'greater than or equal'. This means that it will keep decompressing until a particular byte is met.
To make this more exploitable, the decompressed buffer follows the compressed buffer! So, if the decompressed data is also valid compressionable data, we can keep decompressing. For sure, using this technique, a crash of the PokeWalker occurred. But now what?
From brute forcing the offsets, the author figured out where the stack pointer was. Then, with such a small address space and an executable stack, the author wrote a payload to brute force this location. Now, we have code execution!
Using the IR transmission in the shellcode, data can be leaked! Using this (and restarting after the watchdog timer), the entire ROM can be leaked.
The rest of the article goes into the reversing of the ROM and the rest of the commands. This is an incredible article where a completely random attacker gets code execution with no prior knowledge. One for the ages!