Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revisionLast revisionBoth sides next revision | ||
| inbox:d-link:dwr-921_image_cracking [2018/01/31 20:43] – Add info about 0x30 address. chkdsk | toh:d-link:dwr-921_image_cracking [2018/04/04 20:47] – tmomas | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== DWR-921 Stock Image Cracking ====== | ||
| + | ~~NOTOC~~ | ||
| + | |||
| + | /* This template is intended to be used via https:// | ||
| + | |||
| + | {{page> | ||
| + | |||
| + | ===== FW Image into the flash device ===== | ||
| + | The layout into the flash device is the following: | ||
| + | |||
| + | 0x000000000000-0x000000010000 : " | ||
| + | 0x000000010000-0x000000150000 : " | ||
| + | 0x000000180000-0x000000f10000 : " | ||
| + | |||
| + | The Kernel partition is formatted by two block: | ||
| + | - Image Header | ||
| + | - 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, | ||
| + | |||
| + | 00000000: 04 04 24 2b magic | ||
| + | 00000004: 74 77 bd 08 Timestamp : (UTC_TIME-0x35016f00)/ | ||
| + | 00000008: 3c de 13 00 size(kernel.bin)+0x28 | ||
| + | 0000000c: 38 b8 | ||
| + | 0000000e: 1d ba | ||
| + | 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 start ram 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 crc32 (area 0x20 -> 0x37, 0x30-> | ||
| + | 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 enough to generate a firmware image accepted by jboot during the boot process. | ||
| + | |||
| + | (*) To calculate crc32 from 0x30 You must set 0x30-0x33 to zero. Example: | ||
| + | |||
| + | 00000020: 00 00 00 80 | ||
| + | 00000024: 00 00 18 bc | ||
| + | 00000028: 00 a0 75 00 | ||
| + | 0000002c: 10 5a e6 1a | ||
| + | 00000030: 00 00 00 00 | ||
| + | 00000034: 28 00 00 00 | ||
| + | |||
| + | What is jboot_checksum? | ||
| + | |||
| + | <code c> | ||
| + | { | ||
| + | uint32_t counter; | ||
| + | uint16_t | ||
| + | |||
| + | counter = start_val; | ||
| + | ptr = data; | ||
| + | while ( size > 1 ) | ||
| + | { | ||
| + | counter += *ptr; | ||
| + | ++ptr; | ||
| + | while ( counter >> 16 ) | ||
| + | counter = (uint16_t) counter + (counter >> 16); | ||
| + | size -= 2; | ||
| + | } | ||
| + | if ( size > 0 ) | ||
| + | counter += *(uint8_t *)ptr; | ||
| + | while ( counter >> 16 ) | ||
| + | counter = (uint16_t) counter + (counter >> 16); | ||
| + | return counter; | ||
| + | }</ | ||
| + | |||
| + | |||
| + | 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.... | ||
| + | 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, | ||
| + | |||
| + | This is the early log from the bootstrap: | ||
| + | | ||
| + | ................... | ||
| + | Starting kernel @80000000... | ||
| + | | ||
| + | LINUX started... | ||
| + | | ||
| + | THIS IS ASIC | ||
| + | Linux version 2.6.36 (tja@localhost.localdomain) (gcc version 4.3.5 (Buildroot 2011.05) ) #19 Thu Jul 7 15:20:08 CST 2016 | ||
| + | CMD_LINE: | ||
| + | |||
| + | |||
| + | ===== 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 " | ||
| + | |||
| + | 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] | ||
| + | 00000000: 04 04 24 2b | ||
| + | 00000004: 74 77 bd 08 | ||
| + | 00000008: 3c de 13 00 | ||
| + | |||
| + | |||
| + | ===== Image Generation flow ===== | ||
| + | Using the binboy tool found in the [[https:// | ||
| + | |||
| + | With reference to the lede distribution, | ||
| + | |||
| + | cp < | ||
| + | mv dwr-921-kernel.bin zImage.lzma | ||
| + | |||
| + | cp < | ||
| + | mv root.squashfs squashfs.o | ||
| + | |||
| + | ./ | ||
| + | ./ | ||
| + | ./ | ||
| + | ./ | ||
| + | | ||
| + | The File generatedconcatenate the kernel lzma compressed, the rootfs and FIXME | ||
| + | |||
| + | {{ : | ||
| + | |||