Jul 7, 2013

As a hacker, just like most other occupations that require physical work, your toolset can make or break you. If you can't solder SMD components because your soldering iron is uncontrolled or has a point that's too big, forget about hacking on SMD pcbs with tiny 0402 components. The same goes for e.g. programmers: if you don't have an AVR programmer, programming AVRs is going to be impossible. The advantage, however, is that we can hack together our own tools: you can still program an AVR if you, for example, have an Arduino board you can persuade to act as a programmer.

I have run into a similar problem in the past. When security-testing the 'secure' USB-sticks I got my hands on in the past, I needed a way to directly read the NAND-flash these sticks use to store the data on. For that, I created a quick hack: a NAND-reader consisting of a small PCB the flash had to be soldered on and a parallel port interface. There was no voltage conversion apart from some resistors to limit the current from the 5V parallel port to the 3.3V flash chip and the software was a horrific hack, but the contraption worked: I now had a tool to read out NAND flash, even if it was tied together with the solder and the software equivalent of lots of duckttape.

Since then, I've been getting a slow but steady trickle of requests for the code and schematics for the nand reader. I've never been willing to release those because it's such a hack. It also uses the parallel port, something that is unavailable in more and more PCs nowadays.

Recently, I had the need to read out a NAND-flashchip again. Ofcourse, I could get out the old device, try to find a parallel port somewhere and hope the software still worked. I could also build a new one and improve both the software and hardware to something a bit less hack-ish.

Hardware

As you may have guessed, I opted for building a NAND-flash reader from scratch. I wanted a few things that weren't an option on the old parallel port based one:

USB connectivity. Parallel ports are almost extinct, USB ones probably will stay with us for the forseeable future.

Speedy. The original unit took a day to read out the 1Gbyte nand chip I connected to it. I really wouldn't mind my new one to be a bit quicker

Easy connectivity. Needing to solder a NAND to a board in order to read it out means a chance to mess up the chip, and without a backup that can be quite painful.

Cheap. I wasn't planning on spending hundreds of Euros for this.

The easy-connectivity-requirement was the easiest to fill: a while ago, I managed to pick up a TSOP56 ZIF-socket for about ten Euros. The socket has a few more pins than the NAND chips usually have (56 vs 48) but the chip fits perfectly and makes good contact. If you're looking for cheap TSOP48 ZIF-sockets yourself, take a look at e.g. Ebay: there are multiple sellers offering them for EUR10-EUR15.

USB was a bit harder. For the device to be speedy, I'd need at least USB2.0. Not a lot of cheap and easy microcontrollers have that, so one of those would be out of the question. Luckily, I knew about a chip called the FT2232H. This chip is marketed as a dual-port USB2-to-serial converter, but it actually can do a lot more than that: you can do FIFO, JTAG, I2C with it natively, and it also has a so-called 'host emulation mode'. That last mode was of particular interest: it gives you a multiplexed data and address bus with read and write strobes, just like a microcontroller like the 8051 has. The flash chip should be interfacable easily with this, and the 480MBit/s the USB2 chip offered should be enough to be a lot quicker than the parallel port reader.

The FT2232H needs a few parts around it to work, and it's a TQFP chip, so I couldn't just plug it into a breadboard or prototyping PCB. FTDI does make a module with the FT2232H on it and all relevant pins connected to headers; modules like this can be found on eBay too. While the EUR30 this would cost didn't worry me too much, I knew I could get a quicker result from the loose FT2232H I had stashed away somewhere, plus one of the TQFP adapter PCBs I had in a box somewhere. All in all, after a bit of soldering I ended up at this contraption:

On the adapter pcb, I soldered all the components needed for the FTDI-chip to work in bus-powered mode, like page 53 of the datasheet indicates. I then connected the bus pins of the FTDI-chip to the NAND ZIF-socket like this:

The connections are fairly simple. The data-lines of the FTDI-chip are connected directly to the databus of the NAND-flashchip. The FTDI multiplexes the low address bits on these lines too, but because we don't need them we can ignore that. The read and write strobe run directly to their counterparts on the flash chip too. The ALE and CLE-lines, as well as the write-protect line, connect to the high address lines. This way, by reading from or writing to a particular address, we can set the values of these lines. The R/B-line, a line the flashchip uses to indicate if it's busy with something, is connected to a spare I/O-line.

Software

To read the NAND, I also needed some PC software to control the FTDI lines. Luckily, there already is a library which supports all the nifty bitbang modes of the chip, including the host-bus-emulation mode needed here. I whipped up a small bit of software that'll try to autodetect the specific NAND installed and uses that info to set the parameters and algorithm to read out the chip. It does that by reading out the NAND page by page.

The software can read out a NAND quicker than my parallel port solution can, it'll get about 250KByte a second. That still is orders of magnitude below the maximum attainable speed of the FT2232H. The reason probably is because of latency: every time you switch from writing data to reading data, the chip will introduce a bit of latency because of how the USB bus works. Reading just one page at a time means the latency gets introduced fairly often, degrading performance. The software could be speeded up a lot by sending the read commands for multiple pages, then requesting the data read. For me, this was enough: the current software can read an 1GByte chip in about half an hour and that was the biggest chip I tested

I also wanted to build the ability to write a NAND chip in the software, but after some thought I decided to abandon it: I didn't need that feature myself, and writing a page to the NAND also means the OOB data for the page, containing e.g. the ECC-data, would have to be written. The ways to do ECC and the location to store that vary from device to device, and I wasn't willing to dive into that.

Conclusion

So, there you have it: a NAND-reader for 3.3V 8bit NAND flash chips for about EUR30 worth of components. It's not lightning fast or feature-rich yet, but it can be expanded to be. It was useful for me: I managed to read out the NAND chip I built it for.

The software (for Linux) is available, as usual, under the GPLv3. If you manage to upgrade it or make it faster, I'd appreciate a note.

One last note: If you have a broken SD-card or USB-stick and think you can recover it using this, be warned: reading out the flash (with a tool like this) only is half the work. As soon as you have an image, you'll still need to know how to interpret it: most flash chips do bad block management and/or will swap sectors around for wear leveling. Unfortunately, I know of no free or cheap tool to undo that yet.