Serial Peripheral Interfaces

Serial Peripheral Interface (SPI) is a synchronous serial communication protocol used for transferring data between a micro controller and peripheral devices, such as sensors, displays, or memory chips. It is commonly used in embedded systems and electronics for its simplicity and speed.

Typically, four pins are used for SPI:

  • Clock Signal (CK): The master device provides a clock signal that synchronizes the data transmission between the master and slave.
  • Chip Select (CS): Each slave device is connected to a Chip Select (or Slave Select) line. The master uses this line to select which slave it wants to communicate with at any given time.
  • MOSI (Master Out, Slave In) Carries data from the master to the slave.
  • MISO (Master In, Slave Out) Carries data from the slave to the master.

By interfacing with a memory chip via SPI, we can extract software from a devices ROM chip.

Communication is typically between a master and a slave device. In this example, our processor is the master and our ROM would be the slave.


Identifying the ROM Pins

The below photo shows the location of our target ROM chip.

Taking a closure look at the ROM shows it has a manufacturer part name: eFeon QH328-104HIP.

By searching the name of the chip online, we can find the following datasheet that shows the chip can be interfaced with using SPI:

It also goes onto list the pins used for SPI communication.


Connecting a Flash Programmer

To connect to the ROM chip and extract it’s memory, we can use a CH341A programmer. Looking at the underside of the reader, you should be able to see the SPI pins are labelled.

The reader will need an adapter inserted into the slot on the top. Based on where we know the SPI pins are, this will be closest to the USB port.

Ensure the red ribbon is in the same position as the picture below.

Place the clips on top of the flash chip. Do not apply power to board. The programmer will do that for us, so keep the device disconnected from the mains supply.

Assuming this is connected correctly, you should be able to move onto the next step. If you have issues reading from memory, just try re-seating the clips (this may take several attempts).


Extracting the firmware contents

First, check to see if the reader is recognized by your operating system by using lsusb.

lsusb
Bus 003 Device 006: ID 1a86:5512 QinHeng Electronics CH341 in EPP/MEM/I2C mode, EPP/I2C adapter

Next, we can use the flashrom command to take a copy of the firmware. Typically, the only argument required is the type of reader, in this case a ch341a_spi. However, in this instance the capture fails since it’s unable to determine the flash chip type.

sudo flashrom -p ch341a_spi -r router.bin            
flashrom 1.4.0 on Linux 6.11.2-amd64 (x86_64)
flashrom is free software, get the source code at https://flashrom.org

Found Eon flash chip "EN25QH32" (4096 kB, SPI) on ch341a_spi.
Found Eon flash chip "EN25QH32B" (4096 kB, SPI) on ch341a_spi.
Multiple flash chip definitions match the detected chip(s): "EN25QH32", "EN25QH32B"
Please specify which chip definition to use with the -c <chipname> option.

Manually specify the chip type with the -c flag.

sudo flashrom -p ch341a_spi -r EN25QH32.bin -c EN25QH32
flashrom 1.4.0 on Linux 6.11.2-amd64 (x86_64)
flashrom is free software, get the source code at https://flashrom.org

Found Eon flash chip "EN25QH32" (4096 kB, SPI) on ch341a_spi.
===
This flash part has status UNTESTED for operations: WP
The test status of this chip may have been updated in the latest development
version of flashrom. If you are running the latest development version,
please email a report to flashrom@flashrom.org if any of the above operations
work correctly for you with this flash chip. Please include the flashrom log
file for all operations you tested (see the man page for details), and mention
which mainboard or programmer you tested in the subject line.
You can also try to follow the instructions here:
https://www.flashrom.org/contrib_howtos/how_to_mark_chip_tested.html
Thanks for your help!
Reading flash... done.

Now we have a copy of the image, we can use binwalk to extract it’s contents.

binwalk -e EN25QH32.bin

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
66048         0x10200         LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 2986732 bytes

WARNING: Symlink points outside of the extraction directory: /home/kali/_EN25QH32.bin-0.extracted/squashfs-root-0/etc/passwd -> /var/passwd; changing link target to /dev/null for security purposes.

WARNING: Symlink points outside of the extraction directory: /home/kali/_EN25QH32.bin-0.extracted/squashfs-root-0/etc/TZ -> /var/tmp/TZ; changing link target to /dev/null for security purposes.

WARNING: Symlink points outside of the extraction directory: /home/kali/_EN25QH32.bin-0.extracted/squashfs-root-0/etc/resolv.conf -> /var/tmp/resolv.conf; changing link target to /dev/null for security purposes.

WARNING: Symlink points outside of the extraction directory: /home/kali/_EN25QH32.bin-0.extracted/squashfs-root/etc/passwd -> /var/passwd; changing link target to /dev/null for security purposes.

WARNING: Symlink points outside of the extraction directory: /home/kali/_EN25QH32.bin-0.extracted/squashfs-root/etc/TZ -> /var/tmp/TZ; changing link target to /dev/null for security purposes.

WARNING: Symlink points outside of the extraction directory: /home/kali/_EN25QH32.bin-0.extracted/squashfs-root/etc/resolv.conf -> /var/tmp/resolv.conf; changing link target to /dev/null for security purposes.
1048576       0x100000        Squashfs filesystem, little endian, version 4.0, compression:xz, size: 3001860 bytes, 552 inodes, blocksize: 262144 bytes, created: 2022-08-16 03:52:07

WARNING: One or more files failed to extract: either no utility was found or it's unimplemented

Once that completes, you should have a directory structure of the recovered files.

tree -L 2
.
├── 100000.squashfs
├── 10200
├── 10200.7z
├── squashfs-root
│   ├── bin
│   ├── dev
│   ├── etc
│   ├── lib
│   ├── linuxrc -> bin/busybox
│   ├── mnt
│   ├── proc
│   ├── sbin
│   ├── sys
│   ├── usr
│   ├── var
│   └── web


In Conclusion

SPI is fairly simple to interface with, just be careful to make sure everything is connected the right away round, or you risk frying the chip.