Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I read my device's flash memory without a programmer or UART access? #11

Open
guino opened this issue Dec 21, 2020 · 25 comments
Open

Comments

@guino
Copy link
Owner

guino commented Dec 21, 2020

This is how to read/dump your device's flash memory without a programmer or UART/serial access.

Requirements

  • Linux machine/VM with SD card adapter/reader
  • SD card (one you can erase completely)
  • binwalk (on any machine) for verification

WARNING This WILL erase everything you have on the SD card so copy what you want from it before you start and if you're unsure of something ask for help because if you do something wrong in the steps below you could potentially erase the wrong disk (i.e. your entire computer).

Process

This process has been tested with 2.9.x firmware only -- likely won't work with 2.7.x as it would require different commands to work with older boot loader.

  1. Insert SD card into linux machine with SD card adapter
  2. Open a terminal and login as root user by executing: sudo su
  3. Determine which device has the SD card by executing: lsblk the device will usually show up as mmcblkX or sdX depending on the type of adapter but it should be easy to identify by the size of the device.
  4. Erase/repartition the SD card, by executing: fdisk /dev/<device> (where <device> is mmcblkX or sdX from the previous step, such as fdisk /dev/sdb), then: type o and press enter, type n and press enter, type p and press enter, press enter (for default partition 1), type 32769 for first sector and press enter, press enter (for default last sector), type w and press enter.
  5. Check the partition was created by executing: fdisk -l /dev/<device> (where <device> is the same as from step 4). The last line of the output should show /dev/mmcblkXp1 or /dev/sdX1 and it under 'Start' it should say 32769 confirming the previous operation.
  6. Format the partition as fat by executing: mkfs.vfat /dev/<partition> (where <partition> is the value listed on the last line from step 5 above (i.e. /dev/mmcblk0p1 or /dev/sdb1).
  7. Check your firmware version using http://admin:056565099@ip/devices/deviceinfo -- If you have a mini 7c or device running 2.7.x firmware: UNZIP this mini7c.zip to the root of SD card. If you have 2.9.x firmware UNZIP and copy this ppsMmcTool.txt to the root of the SD card.
  8. Properly eject/unmount SD card from the machine (to avoid data corruption)
  9. Power off the camera/doorbell devlce
  10. Insert prepared SD card into device
  11. HOLD the reset button pressed and power up the device while holding the reset button, you can let go of the reset button after 5 seconds, but let the device boot up as confirmation that the process completed.
  12. Power off device, remove SD card and insert it back into the linux machine
  13. Copy the flash dump from the SD card by executing: dd if=/dev/<device> of=flash.bin skip=1 bs=512 count=32768 (where <device> is the same from step 4 above like /dev/mmcblk0 or /dev/sdb).

The flash.bin file created in step 13 should be a full dump of your device's flash memory, please note that the process above will create a 16Mb file but your flash may be smaller than that, in fact most devices I have seen have 8Mb of flash (I have only seen a few that have 16Mb).

Confirmation

To confirm that the process worked, you should run 'binwalk' on the flash.bin file, and it should detect some recognizable components such as u-boot, uImage and cramfs/jffs filesystems, here's a sample section from mine:

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
18304         0x4780          gzip compressed data, has original file name: "u-boot.bin", from Unix, last modified: 2020-03-19 02:07:20
393216        0x60000         uImage header, header size: 64 bytes, header CRC: 0xCAFBC6AB, created: 2020-03-21 04:08:30, image size: 3205330 bytes, Data Address: 0x40008000, Entry Point: 0x40008000, data CRC: 0x4D094A1B, OS: Linux, CPU: ARM, image type: OS Kernel Image, compression type: none, image name: "Linux-4.9.37"
393280        0x60040         Linux kernel ARM boot executable zImage (little-endian)
395744        0x609E0         device tree image (dtb)
409432        0x63F58         device tree image (dtb)
415388        0x6569C         device tree image (dtb)
419604        0x66714         gzip compressed data, maximum compression, from Unix, last modified: 1970-01-01 00:00:00 (null date)
3584472       0x36B1D8        device tree image (dtb)
3604480       0x370000        CramFS filesystem, little endian, size: 3805184, version 2, sorted_dirs, CRC 0x9C53DE6A, edition 1, 929 blocks, 3 files
8060940       0x7B000C        JFFS2 filesystem, little endian

If your binwalk output has similar parts (uboot, uImage/kernel and cramfs/jffs2 filesystems), then that is your confirmation that the process worked and you should have a full dump of your devices flash memory in flash.bin. You can then execute binwalk -M -e flash.bin to 'extract' all known parts from the flash.bin file (for review/patch/etc).
If your binwalk output is empty or does not look like the above, chances are the process did not work on your device (i.e. device doesn't support ppsMmcTool.txt) in which case your only options are to use a programmer (or UART) review/make any changes to the device.

NOTICE: One device I saw used address 81000000 instead of 42000000 to load data, there's no way to know for sure the address your device will load the data unless you have UART access, so I recommend trying 42000000 first (default value in ppsMmcTool.txt), if that doesn't get you valid results it doesn't hurt to try modifying all 42000000 values in ppsMmcTool.txt to 81000000 and trying again.

@thomasloven
Copy link

thomasloven commented Dec 22, 2020

Adding to the list, I believe my device (Tuya Mini 7C derivative) loads to 0x81808000.

/devices/deviceinfo

{
    "WiFi MAC": "7c:a7:b0:db:de:7f",
    "authkey": "---",
    "deviceid": "---",
    "devname": "Smart Home Camera",
    "firmwareversion": "ppstrong-a2-tuya2_teco-2.7.4.20191111",
    "hardwareversion": "M7C_AK_V10_1245",
    "identity": "MR2003120400934967",
    "model": "Mini 7C",
    "pid": "aaa",
    "serialno": "---",
    "softwareversion": "2.7.4"
}

@guino
Copy link
Owner Author

guino commented Dec 22, 2020

@thomasloven maybe you want to post your fw bin file somewhere I can get it (or email me a link) so I can take a look. Sometimes binwalk doesn’t give good results but maybe a slight change in in the file can make a difference, I would expect at least the bootloader to be unencrypted ? So someone with enough time could find the function that decrypts/loads it into memory ? I mean I doubt they have anything hardware side doing the decryption.

@thomasloven
Copy link

Sorry, I missed this message and posted the bin in #13 (comment).

@guino
Copy link
Owner Author

guino commented Dec 31, 2020

I just got a Mini 7C camera from walmart for $25 to play with it -- so you can expect a way to patch it soon.

@swisslegacy
Copy link

swisslegacy commented Dec 31, 2020

I just got a Mini 7C camera from walmart for $25 to play with it -- so you can expect a way to patch it soon.

@guino I have a Mini 7C too.

output of /devices/deviceinfo:

{
"devname":"Smart Home Camera",
"model":"Mini 7C",
"serialno":"-redacted-",
"softwareversion":"2.7.5",
"hardwareversion":"M7C_AK_V10_1245",
"firmwareversion":"ppstrong-a2-tuya2_geeni-2.7.5.20200520",
"authkey":"-redacted-",
"deviceid":"-redacted-",
"identity":"MR2007201700909866",
"pid":"aaa",
"WiFi MAC":"dc:bd:7a:82:4e:f9"
}

I could not get a proper flash.bin. It is the correct size, but nothing is listed when I check it with binwalk. I tried a few times with address 42000000, 81000000, and 81808000. The result is always the same. Please let me know what you find. I have no UART or programmer but I am happy to help in any way I can.

I had no success with #13 either.

output of /proc/cmdline:

mem=64M console=ttySAK0,115200n8 mtdparts=spi0.0:256k(bld)ro,64k(env)ro,64k(enc)ro,64k(sysflg)ro,2496k(sys),4608k(app),640k(cfg) ppsAppParts=5 ip=192.168.1.99:::255.255.255.0 eth=00:55:7b:b5:7d:f7

@guino
Copy link
Owner Author

guino commented Jan 1, 2021

Bad news, while trying to get the flash chip out I pulled a track and damaged the board. I no longer have a mini 7c ($25 down the drain).
@swisslegacy try this ppsMmcTool.txt to read the flash: #13 (comment)

@swisslegacy
Copy link

Bad news, while trying to get the flash chip out I pulled a track and damaged the board. I no longer have a mini 7c ($25 down the drain).
@swisslegacy try this ppsMmcTool.txt to read the flash: #13 (comment)

@guino That ppsMmcTool.txt did not work either. @thomasloven mentioned he "soldered into a UART . . . ran the same commands with some tweaks" and then tried to translate them back to ppsMmcTool.txt format. So is the translation not correct, or are we thinking the ppsMmcTool.txt method just won't work for the Mini 7C?

@thomasloven
Copy link

I'm quite certain the ppsMmcTool method should work for the Mini 7C too.
I did quite a bit of experimenting with editing the file and just reading the output before @guino helped me get direct write access to the bootloader.

I can try some things to see if I can get this to actually work, though I already fried one sd card, so I'll be moving forward slowly and carefully...

@guino
Copy link
Owner Author

guino commented Jan 1, 2021

@thomasloven with UART access here's what I'd do:
1-power on device into boot loader
2-insert SD card and read flash manually
3-(keep device powered on) remove SD card and read flash on the computer as an exact copy of current flash
4-modify flash file on the computer (to include call to script on mmc card)
5-insert SD card on device (still powered on)
6-mmcload and sf write commands to write flash to device (keep it powered on when done)
7-use commands to read flash manually again
8-(keep device powered on) remove SD card and read flash on the computer and compare the changes match your changes to the flash file made on the computer
9-if everything matches it should be safe to reboot the device and test your changes. If something is different (ie changes from step 7 don't match the changes you made) then the device is still powered on so you can at the very least restore the original flash or adjust commands and try again (until your flash actually matches your modified flash).

@swisslegacy
Copy link

swisslegacy commented Jan 1, 2021

So I did more testing with my Mini 7C. I am getting the same output from binwalk regardless of what ppsMmcTool.txt I use. I can tell something is happening, because the LED begins flashing between red and blue for a few seconds after booting the camera with reset button pressed for 5 seconds. And this only happens when ppsMmcTool.txt is present, so I know my camera sees that file and it is trying to do something with it. But I can tell nothing is written to the 16 MiB unallocated portion of the SD card which we are dumping using dd. I confirmed with md5sum, the .bin dump of my freshly formatted SD card and the flash.bin from my flash dump attempts are the same.

Here is the output I am getting from binwalk:

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
16350997      0xF97F15        Unix path: /dev/mmcblk0p1_/mnt/mmc01;/mnt/mmc01/initrun.sh&\\";eval"
16367104      0xF9BE00        Executable script, shebang: "/bin/sh"
16367315      0xF9BED3        Unix path: /opt/pps/app.tar.gz -C /mnt/mmc01/

@guino
Copy link
Owner Author

guino commented Jan 1, 2021

@swisslegacy I was hoping to iron out the correct commands for ppsMmcTool.txt when I got a mini 7C but since my board got damaged I no longer have that option. Chances are some command needs a tweak/different parameter, but without UART access (to see output/errors) that's not easy to figure out. I tested the commands in the 1st post on 2.9.6 version and expect anyone with 2.9.x bootloared to be able to use it, but for 2.7.x bootloader (older) we need someone to play with it and iron out the commands like I wanted to do.

@swisslegacy
Copy link

swisslegacy commented Jan 1, 2021

@swisslegacy I was hoping to iron out the correct commands for ppsMmcTool.txt when I got a mini 7C but since my board got damaged I no longer have that option. Chances are some command needs a tweak/different parameter, but without UART access (to see output/errors) that's not easy to figure out. I tested the commands in the 1st post on 2.9.6 version and expect anyone with 2.9.x bootloared to be able to use it, but for 2.7.x bootloader (older) we need someone to play with it and iron out the commands like I wanted to do.

@guino I see. I am very new to this but willing to learn. Can you explain how to get UART access so I may try to assist as well?

Additionally, FWIW, I think there was something wrong with the SD card I was using earlier. I tested all the ppsMmcTool.txt I used earlier with a new SD card, and my binwalk output is different now, but it still remained the same after every ppsMmcTool.txt I tried though.

# fdisk -l /dev/sda
Disk /dev/sda: 29.12 GiB, 31266439168 bytes, 61067264 sectors
Disk model: MassStorageClass
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x50a48aa5

Device     Boot Start      End  Sectors  Size Id Type
/dev/sda1       32769 61067263 61034495 29.1G 83 Linux

# dd if=/dev/sda of=flash.bin skip=1 bs=512 count=32768
32768+0 records in
32768+0 records out
16777216 bytes (17 MB, 16 MiB) copied

# binwalk flash.bin 

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------

@guino
Copy link
Owner Author

guino commented Jan 2, 2021

For UART access you need a serial-ttl level adapter for 3.3v. There are some USB and some serial too, then basically you solder some wires to the board and have a way to view and send commands to the bootloader which include functions that read and write the flash chip. If you don’t have the adapter or soldering skills it may not be for you. I didn’t want to play with the commands without a flash image taken by programmer and damaged the board when disconnecting the pin to read the flash - and I am fairly experienced with the soldering iron. Still soldering the UART wires is piece of cake compared to removing surface mount chips/pins without the proper tools.

@swisslegacy
Copy link

For UART access you need a serial-ttl level adapter for 3.3v. There are some USB and some serial too, then basically you solder some wires to the board and have a way to view and send commands to the bootloader which include functions that read and write the flash chip. If you don’t have the adapter or soldering skills it may not be for you. I didn’t want to play with the commands without a flash image taken by programmer and damaged the board when disconnecting the pin to read the flash - and I am fairly experienced with the soldering iron. Still soldering the UART wires is piece of cake compared to removing surface mount chips/pins without the proper tools.

Interesting! Well, I'm not sure where exactly to start with that, but I have an extra camera and I'm willing to try if you can guide me.

Here are some photos of my PCB:
image
image

@thomasloven
Copy link

thomasloven commented Jan 2, 2021

The points marked 2 and 3 at the top right in the second picture are 3.3V RX and TX at 115200 baud.
One of 1 and 4 is probably ground, but I just connected to the ground plane at a screw hole.

@guino
Copy link
Owner Author

guino commented Jan 2, 2021

From what I remember testing point 4 was ground and 2/3 are RX/TX (3.3v) as @thomasloven said. Using the screw hole for ground is very smart as it can be difficult to solder point 4 and these boards seem very fragile.

@guino
Copy link
Owner Author

guino commented Jan 2, 2021

I got a working mini 7c again and from what I can tell the issue is that the ppsMmcTool.txt isn't being loaded by the bootloader correctly. It looks like it tries and fails likely because of something not yet initialized by the bootloader. That said it seems you can read the flash using the UART (still testing). I'm trying to see if there's anything we can do to make it read the chip correctly (gonna try different SD card).

@guino
Copy link
Owner Author

guino commented Jan 2, 2021

looks like a different SD card did the trick to read ppsMmcTool.txt but it is not parsing the file the same way as newer boot loaders, I'm trying to find the boot loader load address so I can review it in ghidra, maybe @thomasloven could share it since he's already been looking at it.
EDIT: found the address

@guino
Copy link
Owner Author

guino commented Jan 2, 2021

Ok, to read the flash on mini 7C (2.7.x) this works:

  • follow steps 1-6 from 1st post
  • unzip this mini7c.zip to the root of SD card
  • follow steps 8 thru 13 of first post using count=16384 (instead of count=32768)

I am still looking to see if we can pass in boot parameters to this device but worst case scenario I'll make an app.img file that can be loaded from SD card using similar steps (reset button + ppsMmcTool.txt).

@guino
Copy link
Owner Author

guino commented Jan 3, 2021

Ok, I got root access with a variation of #13 working on mini 7c (no programmer, no UART, no soldering required), but I think I'm going to make a new github project for this older boot loader because the busybox version we have been using on this project doesn't work on this board (I'll have to look for an older busy box that works on it). So right now I have root access using the built-in telnetd (which is present on this one but not present on the newer boards). Spent a lot of hours on this today so I'm calling it for the night. I'll publish the files/steps on the new project (hopefully along with a working busybox version) soon.

@thomasloven
Copy link

Found your new repo. Works like a charm!

@oliv3r
Copy link

oliv3r commented Mar 30, 2022

I just purchased a new iteration of the LCS action doorbell camera (bell5c, anyka chipset). I have not 'enrolled' it (e.g. connected it to the internet/wifi network) as I have no intend on using the standard software.

I will eventually run a isolated hotspot for the device to connect to, to enable all of our hackery and get root; however as a first step, I wanted to dump the flash. I do have UART access mind you :)

Using U-Boot on the device (U-Boot 2013.10.0-AK_V3.0.07 (Jan 22 2021 - 14:16:01) I tried many variations, however, it seems like they have removed the mmc write command, meaning while I can read the flash, I cannot write it.

Here is my ppcmmctool.txt content:

style=upgrade,,writeAddr=0,,password=nothing,,writeLen=0,,fileName=0;version;sf probe;sf read 0x81808000 0 0x800000;mmcinfo;mmc write 0x81808000 0x1 0x4000;md 0x81808000 32;version,,

which works fine, except of course the mmc write error

arm-anykav200-linux-uclibcgnueabi-gcc.br_real (anyka (gcc-4.8.5 + binutils-2.24 + ulcibc-0.9.33.2)(20170223)) 4.8.5
GNU ld (GNU Binutils) 2.24

SF: 8388608 bytes @ 0x0 Read: OK
find MMC device available
Device: ANYKA SDHC/MMC4.0
Manufacturer ID: 6b
OEM: b1
Name: �\� 
Tran Speed: 25000000
Rd Block Len: 512
SD version 3.0
High Capacity: No
Capacity: 3.7 GiB
Bus Width: 1-bit
mmc - MMC sub system

Usage:
mmc read addr blk# cnt
mmc write addr blk# cnt
mmc erase blk# cnt
mmc rescan
mmc part - lists available partition on current mmc device
mmc dev [dev] [part] - show or set current mmc device [partition]
mmc list - lists available devices

reading 0
** Unable to read file 0 **

Interestingly enough; my 2GB disk gets miss-identified as 3.7 ...

however, the result is the same with a 16G card

SF: 8388608 bytes @ 0x0 Read: OK
cdh:MMC device available:curr_device=0
find MMC device available
Device: ANYKA SDHC/MMC4.0
Manufacturer ID: 56
OEM: 104
Name: � Ak 
Tran Speed: 25000000
Rd Block Len: 512
SD version 3.0
High Capacity: Yes
Capacity: 15 GiB
Bus Width: 1-bit
mmc - MMC sub system

Usage:
mmc read addr blk# cnt
mmc write addr blk# cnt
mmc erase blk# cnt
mmc rescan
mmc part - lists available partition on current mmc device
mmc dev [dev] [part] - show or set current mmc device [partition]
mmc list - lists available devices

Someone must have been looking over the interwebz, found this usefull trick, and decided to disable it. Or, all evilness aside, they just wanted to shrink the bootloader more.
from 'help' I can see a lot of interesting things, not mentioned anywhere, but that's probably a seperate thread.

?       - alias for 'help'
auth    - encrypt product authfile
base    - print or set address offset
bootm   - boot application image from memory
clearCfg- clearCfg
cmp     - memory compare
cp      - memory copy
crc32   - checksum calculation
devmem  - read or write register, now just read
downimage- downimage   - download and write All-Image to FLASH device,partiton table from ENV partition.
downjffs2fs- load usr.jffs2 tftp
downkernel- load uImage tftp
downrootfs- load root.sqsh4 tftp
downsquashfs- load usr.sqsh4 tftp
downuboot- load uboot tftp
env     - environment handling commands
envreset- reset env para
erase   - erase FLASH memory
fatinfo - print information about filesystem
fatload - load binary file from a dos filesystem
fatls   - list files in a directory (default /)
flinfo  - print FLASH memory information
format  - erase all flash except bootloader part
go      - start application at address 'addr'
help    - print command description/usage
loadk   - load kernel to DRAM  
loop    - infinite loop on address range
md      - memory display
mm      - memory modify (auto-incrementing address)
mmc     - MMC sub system
mmcboot - from mmc start
mmcinfo - display MMC info
mw      - memory write (fill)
nm      - memory modify (constant address)
parts   - read out partitions table info.
parts_adjust- 
adjust parts info. Each part's size,offset etc.

pcbMenu - select Pcb
printenv- print environment variables
protect - enable or disable FLASH write protection
readcfg - read config from config.
reset   - Perform RESET of the CPU
run     - run commands in an environment variable
saveenv - save environment variables to persistent storage
setenv  - set environment variables
setloadaddr- set loadaddr to  config infor .
sf      - spi flash sub-system:
tfdownjffs2fs- load usr.jffs2TF
tfdownkernel- load uImageTF
tfdownrootfs- load root.sqsh4TF
tfdownsquashfs- load usr.sqsh4TF
tfdownuboot- load u-boot.binTF
tfupdateimage- tfupdateimage   - download and write All-Image to FLASH device
uartdown- down style 0:tftp 1:uart 2:mmc
upa     - update app image appfile
upb     - update bootloader bldfile
update  - update upgrade.bin
updatecfg- update config from config infor table.
upe     - update auth image authfile
upf     - update firmware, format and update (factory use upffile)
upk     - update uImage kernelfile
upr     - update backup.img
version - print monitor, compiler and linker version

pcbMenu was interesing, as you could configure various boards that this bootloader supports.

Anyway, I'll try to see what I can do to pull the flash; worst case, I'll just print all the data, and convert it after reading it from the serial port. Porbably start small with just the bootloader, and see if I can get the password string. Should be compiled into the binary, so not too hard to find, and we do have u-boot source which should offer this as a standard feature (could be they created their own password feature of course ...)
Sadly, as no ethernet is available, and no wifi drivers surely exist, tftp is out.

'uartdown' might be intresting, as they may have used this to provision these boards in the factory maybe ... then again, the direction is wrong of course :( and no x/y/z modem options enabled of course.

I could get into Linux, and dump it much easier from there; and I'll do that eventually I suppose.

edit: Hah, so, I didn't even realize, but if we look closely:

cmd:fatload mmc 0 0x81c08000 ppsmmctool.txt
cdh:test_part_dos DOS_PART_MAGIC_OFFSET ok!
reading ppsmmctool.txt
184 bytes read in 0 ms
cmdBuf:fatload mmc 0 0x81c08000 0;version;sf probe;sf read 0x81808000 0 0x800000;mmcinfo;mmc wr

we can see that while there's no size limit on loading the file, (184 is the size of the txt) the buffer actually gets cut off.

So i'll use the 'env' trick from the mini7c next :)

edit:

cmdBuf:fatload mmc 0 0x81c08000 env;env import 0x81808000;md 0x81808000;run fcmd

I should have played closer attention once more; this failed due to this u-boot loading the env at different offset. With this small change (maybe I did it? :p) it actually worked to dump the spi flash :) now to analyzing the dump, to check if i have it all.

@guino
Copy link
Owner Author

guino commented Mar 30, 2022

@oliv3r write me an email (my address is on my github profile) and I can give you some help for UART access. I have seen many cases where they modify the command and don’t bother modifying the help information, so chances are the mmc write command is there just not in that format listed in the help.

@oliv3r
Copy link

oliv3r commented Apr 5, 2022

@oliv3r write me an email (my address is on my github profile) and I can give you some help for UART access. I have seen many cases where they modify the command and don’t bother modifying the help information, so chances are the mmc write command is there just not in that format listed in the help.

I did, from 2 addresses, the one it bounced with MS blocking me, from my other address, it seemed to have worked; but maybe it ended up in your spam. I will e-mail from my gmail; 3times is a charm @guino :)

@guino
Copy link
Owner Author

guino commented Apr 5, 2022

@oliv3r I sent you an email reply, let me know if you didn't get it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants