Dumping Flash Content

It may sound weird to some people that we are trying to perform a flash dump at this point. After all, we've already got the firmware file, right?
It's important to understand in terms of analyzing a device, that having access to runtime environment is better than having a flash dump; having a flash dump is better than having a firmware file for upgrade; and having a firmware file is way better than having nothing.

The logic behind this is that runtime environment is, well, how the device is really working. And flash dump is an image of the system's data storage with some private data (like the hard drive of your computer). Firmware file is more like an installation image of your OS. The amount of information within them is different. 

Of course, the above statement is just the reflection of a general mindset. It is not an absolute truth, as each situation has its own pros and cons. [*]

The "Hard" Way

Dumping flash usually needs to be done the "hard" way, i.e. desoldering the flash chip and reading it with compatible hardware. Usually this can be done with reasonable soldering skills and simple hardware like a raspberry pi with wide body SOP8 chip socket and flashrom.

However, the C200 makes use of a flash chip made by XMC - a not so well known flash chip manufacturer. A raspberry pi alone will have hard a time reading the flash content and reliably (compared to dumping flash chips from Winbond or GigaDevice).
This is due to the fact that the flash chip used in the C200 can't work properly under the raw currents and voltages a raspberry pi is providing. You will thus need to use some more specific hardware to communicate with the SPI flash chip.
For example, we have to use a buspirate and an external 3.3V power supply to obtain a stable and consistent flash dump. 





Desoldering the flash chip and dumping it is the most straightforward and fastest way. However it presents some risks.
First of all, heating the flash chip too much and for a prolonged period of time can damage it.
Second, as mentioned before in "Console" section, PCB pads are extremely fragile. If you are not careful enough during the (de)soldering process, you can rip the pads off and render your device useless after dumping the flash [*].

Here's a victim of mine : 

 
Practice soldering, don't do as i do 😝 !

The Safe Way

Tinkering with hardware isn't for every one. But thankfully, the C200 provides us with enough information to dump the whole flash content in a safer programmatic way.
First of all, we can take a look at this specific portion of the boot log :



Let me make it clearer [*]:

0x0 - 0x1d800 
factory_boot
0x1d800 - 0x20000
factory_info
0x20000 - 0x40000
art
0x40000 - 0x50000
config
0x50000 - 0x60000
boot
0x60000 - 0x1c6400
kernel
0x1c6400 - 0x730000
rootfs
0x730000 - 0x800000
rootfs_data

Why is this important?
We can see that the hex value is incrementing, and it ends at 0x800000. Let's remember this for a while.
Next we can check the datasheet of the XM25QH64A flash chip used in the C200.

In the "Memory Organization" section, the datasheet contains the following information:




We can see from here that this flash chip has 8,388,608 bytes of memory capacity, and guess what? 0x800000 is exactly 8,388,608 in decimal value!

So by now we know that this information in boot log is actually telling you the physical mapping of flash memory address to its partition name. 

MTD and MTDblock devices

Having the partition names in mind, we can check /proc/mtd with command cat /proc/mtd.




Looks familiar?
The information in /proc/mtd is in particular telling you what mtd virtual device each partition of the flash chip is attached to. For example, "factory_boot" is attached to mtd0.

We can also take a look at /proc/partitions :




This shows the mapping of flash partitions to mtdblock virtual devices. [*]
Now, if we can get access to these virtual devices, then we may have a chance to directly read the contents of the flash chip! 

Usually in a fully initialized Linux system, we will see these virtual devices under /dev . However, there's currently nothing under /dev directory as we bypassed the initialization process of the C200 to get a shell. Therefore we'll have to manually create them one by one.
First of all we'll have to make /dev writable [*] . Issue command mount -t tmpfs tmpfs /dev -o mode=0755,size=512K to mount a tmpfs on  /dev . After that, mounting a mtdblock device is as simple as issuing command:

 mknod /dev/mtdblockX b [major] [minor] 

For example, to access "factory_boot" (mtdblock0), simply issue command mknod /dev/mtdblock0 b 31 0 . This will make a virtual device node of  mtdblock0 under /dev . You can then access this partition of flash chip with various tools and programs in the OS.


Dumping Flash Content Into a File

Our ultimate goal here is to obtain an image of the physical flash chip content.
Now we've managed to create virtual device nodes for each partitions, the only thing left is to write all the contents of each node into a file and extract it.
However, up to now, there is no network access, and transferring 8MB of data over serial console will take forever.
Fortunately, C200 cameras have an SD card slot for storing recorded videos. We can use this feature to our advantage and dump the flash to an SD card!
 
Insert a fat32 formatted SD card into the slot and after a while, the console should tell you it has detected an SD card. And if you check /proc/partitions again, you will find two new entries : mmcblk0 and mmcblk0p1. These are the virtual device for your SD card.




To read / write to your SD card, you'll have to :

1. Create a node for mmcblk0p1.
2. Mount the node to a directory in the system.

First step is simple, we've already done it before.  mknod /dev/mmcblk0p1 b 179 1 will do the trick and create a node for us.
To achieve step 2, we can just simply mount it under /dev (which is currently writable). But for the sake of cultivating good habits, let's mount it under /tmp .

Issue following command in order :
mount tmpfs /tmp -t tmpfs -o size=20633600,nosuid,nodev,mode=1777 [*]
mkdir /tmp/sdcard
mount -t vfat /dev/mmcblk0p1 /tmp/sdcard/

And now you will be able to read / write to your SD card under /tmp/sdcard .

The final step is to actually write the flash contents into a file and store it in your SD card. We can achieve this with a simple command we used again and again - cat .
Simply  cat /dev/mtdblock0 >> /tmp/sdcard/flashdump.bin and the content of /dev/mtdblock0 will be appended into /tmp/sdcard/flashdump.bin.
Loop this command through /dev/mtdblock0 to /dev/mtdblock7 and you will get a dump of the entire flash chip!




Finally, use umount /tmp/sdcard to safely unmount your SD card, whose content can now be transferred to a PC.