Fake flash

Being a complete fanny, I managed to drop my phone and break the display assembly again.


I was in the pub the next day with a friend recounting my tale of woe, and as he was showing off his shiny new phone to me, it suddenly occurred to me that we used to have the same phone. I ended up buying his old phone off him for parts, and repaired my phone there and then.


Annoyingly, in doing so I managed to snap my SD card!

I bought a new 64GB SD card on ebay and when it arrived I decided to do a check of its integrity:

$ dd if=/dev/urandom bs=1M count=64000|pv|sudo tee /dev/mmcblk0|sha1sum -

Already things were seeming suspicious: It claimed to be a class 10 card (10MB/s) but it initially wrote (at least for the first few GB when I was paying attention) at about 2-2.5MB/s.
When I came back later, it was ~45GB in and had sped up to about 15MB/s.

I had planned to read it back and check that the data were the same:

$ sudo pv /dev/mmcblk0 | sha1sum -

But it read at about 10MB/s (rather than the advertised 50MB/s) so I lost interest and tried a different approach, writing to random locations and reading back. 54MiB in was fine, but 54722MiB in returned garbage.

I threw together a quick script to check random 1MiB blocks throughout the disk:

dd if=/dev/urandom bs=1M count=1 of=somerandom
for i in $(seq 1 1000) 
	thisblock=$(shuf -i 0-63999 -n 1)
	sudo dd if=somerandom of=/dev/mmcblk0 bs=1M seek=$thisblock
	sudo sync
	sudo dd if=/dev/mmcblk0 skip=$thisblock bs=1M count=1 | diff - somerandom
	if [ $? == 1 ]
		echo "bad"
		echo $thisblock >> badblocks
		echo "good"
		echo $thisblock >> goodblocks

(I don’t know if the sync is necessary – I wasn’t sure if maybe there’d be some transparent caching in play whereby the OS would assume what it’s just written is still there.)

This gave me two lists, one of the known good blocks and one of the known bad blocks. About 3/4 of the blocks were bad, so it was looking like this 64GB was a 16GB in disguise:

 $ wc -l goodblocks badblocks 
 240 goodblocks
 760 badblocks
1000 total

I threw together a piece of octave too, to make a visualisation:

for i=goodblocks'
for i=badblocks'
colourmap=[0 0 0; 0 1 0; 1 0 0];

The result:
Each pixel represents a 1MiB block of the SD card, top left being the start, working right then down, with the bottom right being 64GB (more accurately 64kMiB, or 64000MiB). Black pixels are unknown (the script took a random sample of 1000 blocks out of 64k), green are good (read back the same) and red are bad. This looks pretty conclusively like it’s a 16GB card in disguise.

The bad section seems to be the same 512 byte pattern repeated over and over for a bit, then the repeated pattern changes sometimes for no discernible reason. I haven’t invested much energy into figuring out why yet.