DWR-921 Stock Image Cracking
FW Image into the flash device
The layout into the flash device is the following:
0x000000000000-0x000000010000 : "Bootloader"
0x000000010000-0x000000150000 : "Kernel"
0x000000180000-0x000000f10000 : "RootFS"
The Kernel partition is formatted by two block:
Linux lzma image
The Image Header provides some informations to the jboot (stock) bootloader to execute the bootstrap of the linux lzma image.
The Image Header located in the flash is 0x38 byte long. The Image size is variable and its value is reported in one field of the Image Header.
I'm currently able to decode only some field present in the Image Header, but not all.
With reference to the oem fw available from dlink DWR-921_RevC_Firmware3.01b07.bin, the Image Header is formatted as described below:
00000000: 04 04 24 2b magic
00000004: 74 77 bd 08 Timestamp : (UTC_TIME-0x35016f01)/4
00000008: 3c de 13 00 size(kernel.bin)+0x28
0000000c: 38 b8 1d ba ??? crc of the previous 2/3 words ???
00000010: 24 21 03 02 magic ?
00000014: 00 00 00 80 kernel ram load address ?
00000018: 14 de 13 00 size(kernel.bin)
0000001c: 7c 61 6e 69 crc32(kernel.bin)
00000020: 00 00 00 80 kernel ram load address ?
00000024: 00 00 18 bc root.squashfs flash load address
00000028: 00 a0 75 00 size(root.squashfs)
0000002c: 10 5a e6 1a crc32(root.squashfs)
00000030: fb 8d 6b e6 ??? crc of the previous 7/8 words
00000034: 28 00 00 00 magic
00000038: 5d 00 00 00 <- 0x38 kernel (in lzma format) start
0000003c: 02 64 27 3a
The understanding of the word generation at offset 0x0c and 0x30 shall be enaugh to generate a firmware image accepted by jboot during the boot process.
The squashfs rootfs is stored at the (absolute) location provided in the word at offset 0x24:
bc180000: 68 73 71 73 6a 05 00 00 d1 4c f7 57 00 00 02 00 hsqsj....L.W.... <- squashfs signature
bc180010: 41 00 00 00 01 00 11 00 c0 00 01 00 04 00 00 00 A...............
[ ... ]
At power on reset the jboot should perform the foolowing operations:
verify the crc of the kernel and rootfs image
decompress the lzma image at the location reported in the field at 0x14 or 0x20 in the image
bootstrap the kernel with cmd line: console=ttyS1,57600n8 root=/dev/mtdblock3
This is the early log from the bootstrap:
Starting kernel @80000000...
THIS IS ASIC
Linux version 2.6.36 (email@example.com) (gcc version 4.3.5 (Buildroot 2011.05) ) #19 Thu Jul 7 15:20:08 CST 2016
FW Replacement using jboot
The jboot can be used to replace the fw image. To activate this function it is enough to send a character over the console during the firs seconds of the bootstrap. In this way the standard bootstrap process is interrupted and a web page appears at address 192.168.1.243.
This web page can load a "fw update file" and flash the new image accordingly.
The "fw update file" have a specific format and can be generated using the dlink binboy tool.
The "fw update file" is the concatenation of the following blocks:
specific file headers (0x50 bytes long)
kernel headers (almost identical to the one stored in the kernel flash partition) (0x38 bytes long)
kernel image in lzma format (variable size)
squashfs rootfs headers (0x50 bytes long)
squashfs rootfs image (variable size)
The file headers should be used to verify the file integrity and authenticity. Indeed jboot refuses the file if it is not properly formatted.
Currently the "specific file headers" is completely undecoded.
The kernel headers embedded in the "fw update file" is identical to the Kernel Image Header described in the previous section. The only differences is on the first byte: 0xff into the file, 0x04 into the flash.
With reference to the oem fw available from dlink DWR-921_RevC_Firmware3.01b07.bin:
[flash kernel partition] [fw update file]
00000000: 04 04 24 2b 00000050: ff 04 24 2b
00000004: 74 77 bd 08 00000054: 74 77 bd 08
00000008: 3c de 13 00 00000058: 3c de 13 00
Image Generation flow
Using the binboy tool found in the GPL Source Code is it possible to generate the "fw update file" accepted by the standard jboot bootloader.
With reference to the lede distribution, the "fw update file" can be generated in this way:
cp <LEDE_DIR>/build_dir/target-mipsel_24kc_musl/linux-ramips_mt7620/dwr-921-kernel.bin .
mv dwr-921-kernel.bin zImage.lzma
cp <LEDE_DIR>/build_dir/target-mipsel_24kc_musl/linux-ramips_mt7620/root.squashfs .
mv root.squashfs squashfs.o
The File generatedconcatenate the kernel lzma compressed, the rootfs and