From 5d86636e203a4a7f9a8f541629ec3ac439dc8378 Mon Sep 17 00:00:00 2001 From: Giulio Date: Tue, 14 Apr 2020 21:13:22 +0200 Subject: [PATCH] First draft --- Readme.md | 291 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 289 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index f011f74..5b14393 100644 --- a/Readme.md +++ b/Readme.md @@ -137,6 +137,9 @@ for X in 0..6 -rwxrwxrwx 1 user user 8388608 Apr 12 12:40 flash.bin ``` +Also do a `sha1sum` of the final file. It should match the image extracted later via the SOIC Clip. + + Where `8388608/1024=8192K`. When the device boots up, a lot of custom scripts and services will run. The most custom part of the firmware, which means the web interface and their custom binaries are somehow encrypted or more simply obfuscated and loaded at runtime in ram. At rest, the obfuscated files are called `/usr/web.bin`, `/usr/sbin.bin`, `/usr/apps.bin`. The executable responsabile for decrypting them to more simpler `tgz` archives is called `ap_monitor`. Ghidra sucessfully decompile this binary and the obfuscation mechanism is not very complicated and could reversed with not too much effort but there's proably no reason to do so. @@ -255,7 +258,7 @@ From a root prompt on the Rpi # flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=1000 -r flash3.bin # sha1sum flash*.bin ``` -Check that all the checksums do match. In case they don't there's probably something wrong in the clip position or in the wiring. Remember that no pin should left floating even if it's not useful for the operation. /WP and /HOLD should be always connected to something like GND or VCC. +Check that all the checksums do match (also with the dump obtained via `dd` and `cat`). In case they don't there's probably something wrong in the clip position or in the wiring. Remember that no pin should left floating even if it's not useful for the operation. /WP and /HOLD should be always connected to something like GND or VCC. A working alternative is to use a CH341 USB. In this case, an external VCC source is needed. @@ -460,7 +463,81 @@ bootargs=console=ttyS0,115200 root=31:02 rootfstype=squashfs,jffs2 init=/bin/ini bootcmd=bootm 0x9f020000 ``` -Where, `root=31:02` stands for the `mtd2` partition which is labelled `firmware`. The `boocmd` address is `0x0002000` which is 128KiB. `8000k` is the OpenWrt partition size. +Where, `root=31:02` stands for the `mtd2` partition which is labelled `firmware`. The `bootcmd` address is `0x0002000` which is 128KiB. `8000k` is the OpenWrt partition size. + +#### Changing u-boot environment +U-boot ships also with the commands `setenv` and `saveenv`. The first one will change or add a variable in the current session, the second one will write the current state on the u-boot-env partition. + +``` +ar7240> setenv bootargs0 +ar7240> setenv bootcmd0 +ar7240> setenv bootargs1 +ar7240> setenv bootcmd1 +ar7240> setenv bootargs console=ttyS0,115200 root=31:02 rootfstype=squashfs,jffs2 init=/bin/init mtdparts=ar7240-nor0:64k(u-boot),64k(u-boot-env),8000k(firmware),64k(ART) +ar7240> setenv bootcmd bootm 0x9f020000 +ar7240> saveenv +Saving Environment to Flash... +Protect off 9F010000 ... 9F01FFFF +Un-Protecting sectors 1..1 in bank 1 +Un-Protected 1 sectors +Erasing Flash...Erase Flash from 0x9f010000 to 0x9f01ffff in Bank # 1 +First 0x1 last 0x1 sector size 0x10000 1 +Erased 1 sectors +Writing to Flash... write addr: 9f010000 +done +Protecting sectors 1..1 in bank 1 +Protected 1 sectors +ar7240> printenv +baudrate=115200 +ethaddr=0x00:0xaa:0xbb:0xcc:0xdd:0xee +ethact=eth0 +filesize=27d000 +fileaddr=80060000 +ipaddr=192.168.0.144 +serverip=192.168.0.141 +bootparam=0 +bootdelay=4 +runver1=AWS-SX9331027-4.3.3 +runver0=OEM-SX933146B-4.3.7 +LANG=en +stdin=serial +stdout=serial +stderr=serial +ver=U-Boot 1.1.413 (Aug 29 2012 - 10:36:47) +bootargs=console=ttyS0,115200 root=31:02 rootfstype=squashfs,jffs2 init=/bin/init mtdparts=ar7240-nor0:64k(u-boot),64k(u-boot-env),8000k(firmware),64k(ART) +bootcmd=bootm 0x9f020000 + +Environment size: 498/65532 bytes +``` + +##### Warning +The following methos has not worked with me, but I'm documenting it anyway. + +As for the u-boot environment, it is possible to create an entirely new `u-boot-env` data using an utility called `mkenvimage` which is shipped within the u-boot source. +Simply write all the parameters in a file called `env.txt` + +``` +baudrate=115200 +ethaddr=0x00:0xaa:0xbb:0xcc:0xdd:0xee +stdin=serial +stdout=serial +stderr=serial +ver=U-Boot 1.1.413 (Aug 29 2012 - 10:36:47) +bootargs=console=ttyS0,115200 root=31:02 rootfstype=squashfs,jffs2 init=/bin/init mtdparts=ar7240-nor0:64k(u-boot),64k(u-boot-env),8000k(firmware),64k(ART) +bootcmd=bootm 0x9f020000 +ethact=eth0 +filesize=27d000 +fileaddr=80060000 +ipaddr=192.168.0.144 +serverip=192.168.0.141 +bootparam=0 +bootdelay=4 +runver1=AWS-SX9331027-4.3.3 +runver0=OEM-SX933146B-4.3.7 +LANG=en +``` + +And run `./mkenvimage -s 0x01000 -o env.bin env.txt`. The output should be a 64KiB env.bin. ## Building OpenWrt Adding a device target for an already supported SoC shouldn't be a difficult task. The OpenWrt wiki has some pages that help understand the process: @@ -468,7 +545,210 @@ Adding a device target for an already supported SoC shouldn't be a difficult tas * https://openwrt.org/docs/guide-developer/add.new.device * https://openwrt.org/docs/guide-developer/defining-firmware-partitions +So what need to be done is: + + * Find out the target partition scheme + * Find out led and button GPIO + * Add additional board specific files (for network, calibration, etc) +One of the best way to understand the process is to look at recent commits that add supports for some device, especially if with the same SoC. As an example reference, I used the [Comfast CF-EW72 target](https://git.openwrt.org/?p=openwrt/openwrt.git;a=commit;h=7daab6286110b95167e291409395494f18edc9dc). + +I copied a DTS of the same SoC, specifically `./target/linux/ath79/dts/ar9330_glinet_gl-ar150.dts` in the OpenWrt source tree, adjusted the partition scheme, removed the GPIO info that i don't have yet, checked that the ART partition offsets do match with mine. Here's the result: + +``` +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/dts-v1/; + +#include +#include + +#include "ar9330.dtsi" + +/ { + model = "ZiKing CPE46B"; + compatible = "ziking,cpe46b", "qca,ar9330"; + + aliases { + serial0 = &uart; + label-mac-device = ð0; + }; + +}; + +&gpio { + status = "okay"; +}; + +&uart { + status = "okay"; +}; + + +&spi { + status = "okay"; + + num-chipselects = <1>; + + flash@0 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <50000000>; + reg = <0>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x000000 0x010000>; + read-only; + }; + + partition@1 { + label = "u-boot-env"; + reg = <0x010000 0x010000>; + }; + + partition@2 { + compatible = "denx,uimage"; + label = "firmware"; + reg = <0x020000 0x7d0000>; + }; + + art: partition@3 { + label = "art"; + reg = <0x7f0000 0x010000>; + read-only; + }; + }; + }; +}; + +ð0 { + status = "okay"; + + mtd-mac-address = <&art 0x0>; +}; + +ð1 { + status = "okay"; + + mtd-mac-address = <&art 0x0>; + +}; + +&wmac { + status = "okay"; + + mtd-cal-data = <&art 0x1000>; + mtd-mac-address = <&art 0x0>; +}; +``` + +Futhermore, i added the `ZiKing CPE46B` target in order to be able to select the target image using OpenWrt build system. + +In the file `./target/linux/ath79/image/generic.mk` add: + +``` +define Device/ziking_cpe46b + SOC := ar9330 + DEVICE_VENDOR := ZiKing + DEVICE_MODEL := CPE46B + IMAGE_SIZE := 8000k + SUPPORTED_DEVICES += cpe46b +endef +TARGET_DEVICES += ziking_cpe46b +``` + +`8000k` is the size of the partition we decided before. It should be now possible to select the new target using the standard `make menuconfig` and following normal OpenWrt build instructions. + +The result should be the file called `./bin/targets/ath79/generic/openwrt-ath79-generic-ziking_cpe46b-squashfs-sysupgrade.bin` + +## Putting it all together +Technically, there are at least three methods to flash back the newly obtained images: + + * Flash from a running system, using `mtd` + * Flash from U-Boot via tftp + * Flash using the SOIC Clip + +As of now, I have yet to try the first two. This document will be updated accordingly. + +### Flash via Soic +_Warning: the `du` command do not report exact file sizes but round instead in order to follow the sector size in use._ + +In order to flash using `flashrom` the target image needs to be exctly 8192KiB. So what needs to be done is to assemble a full image and add NULL padding where necessary. + +Firstly, dump the new u-boot-env partition with the new parameters written using `setenv` as described in the U-Boot specific section. +Out final layout should be: + + * `u-boot` 64KiB, the exact same file as dumped (`mtd0`) + * `u-boot-env` 64KiB, newly dumped with the changes + * `firmware` 8000KiB, the OpenWrt image padded with 0x00 + * `ART` 64KiB, the exact same file as dumped (`mtd6`) + +``` +# cat u-boot > flash +# cat u-boot-env >> flash +# ls -l openwrt-ath79-generic-ziking_cpe46b-squashfs-sysupgrade.bin +-rwxrwxrwx 1 user user 3998478 Apr 14 01:11 openwrt-ath79-generic-ziking_cpe46b-squashfs-sysupgrade.bin +# cat openwrt-ath79-generic-ziking_cpe46b-squashfs-sysupgrade.bin >> flash +# ls -l flash +-rwxrwxrwx 1 user user 4129550 Apr 14 20:53 flash +# dd if=/dev/zero of=padding bs=1 count=4193522 +# cat padding >> flash +# cat art >> flash +# ls -l flash +-rwxrwxrwx 1 user user 8388608 Apr 14 20:54 flash +``` + +The `dd` command `count` is the result of the following operation: `8000*1024-3998478=4193522`. + + + +And now flash the obtained `flash` binary. + +``` +# flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=1000 -w flash +flashrom on Linux 4.19.97+ (armv6l) +flashrom is free software, get the source code at https://flashrom.org + +Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns). +No EEPROM/flash device found. +Note: flashrom can never write if the flash chip isn't found automatically. +root@raspberrypi:/home/pi# flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=1000 -w flash_new +flashrom on Linux 4.19.97+ (armv6l) +flashrom is free software, get the source code at https://flashrom.org + +Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns). +Found Winbond flash chip "W25Q64.V" (8192 kB, SPI) on linux_spi. +Reading old flash chip contents... done. +Erasing and writing flash chip... Erase/write done. +Verifying flash... VERIFIED. +``` + +## Reboot! +Now it is possible to reboot the device and hope everything has worked as expected. While the serial console is still useful in order to see the boot process, the debug messages and eventual problems, OpenWrt will now work normally and it is possible to connect via thernet and get an IP Address assigned (by default there's `odhcpd` running). + +``` +BusyBox v1.31.1 () built-in shell (ash) + + _______ ________ __ + | |.-----.-----.-----.| | | |.----.| |_ + | - || _ | -__| || | | || _|| _| + |_______|| __|_____|__|__||________||__| |____| + |__| W I R E L E S S F R E E D O M + ----------------------------------------------------- + OpenWrt SNAPSHOT, r12948-97c5fb4709 + ----------------------------------------------------- +=== WARNING! ===================================== +There is no root password defined on this device! +Use the "passwd" command to set up a new password +in order to prevent unauthorized SSH logins. +-------------------------------------------------- +root@OpenWrt:/# uname -a +Linux OpenWrt 4.19.108 #0 Mon Apr 13 08:14:48 2020 mips GNU/Linux +``` ## Acknowledgements @@ -476,6 +756,13 @@ Adding a device target for an already supported SoC shouldn't be a difficult tas A special thanks to _Paul Fertser_, (`PaulFertser` on `irc.freenode.net`) +## TODO + + * Merge DTS with OpenWrt + * Configure the GPIO + * Flash via tftp + * Flash via the command injection + ## Notes #### On the 0x9f bootcmd prefix