Firmware 5: Binary Manipulation (Spoilers)

I have the modified kernel running! :tada:

Key steps required:

  1. The uImage header contains 2 CRCs and an image size. These three values must be modified.
  2. The squashfs filesystem starts immediately after the compressed kernel (based on the size in the header), so if the compressed kernel size has changed, the squashfs must be dd’d into the correct place. Otherwise: VFS: Cannot open root device "(null)" or unknown-block(0,0): error -6

So the procedure is:

  1. Modify kernel
  2. Compress kernel
  3. Put size and CRC of compressed kernel into header
  4. Calculate CRC of header with null CRC, then put this CRC in the header.
  5. dd header + compressed kernel + squashfs rootfs

Hope this helps.

1 Like

congrats, good work!
Were there any external references you found particularly helpful that i should include in the ‘hints’ section of that lab?


Not really.

I just started by looking at the binwalk output:

327680 0x50000 uImage header, header size: 64 bytes, header CRC: 0xC525C4D1, created: 2016-09-13 04:48:02, image size: 1138908 bytes, Data Address: 0x80000000, Entry Point: 0x80000000, data CRC: 0x2E6A1444, OS: Linux, CPU: MIPS, image type: OS Kernel Image, compression type: lzma, image name: “MIPS OpenWrt Linux-3.18.36”

I then looked for the CRCs within the header hex so that I knew where to edit.

The file which binwalk uses to describe the uImage firmware header structure could be useful: binwalk/firmware at 772f271f0bcce18771f814b5f20cb19b29082831 · ReFirmLabs/binwalk · GitHub or even the uImage source u-boot/image.h at d8729a114e1e98806cffb87d2dca895f99a0170a · u-boot/u-boot · GitHub

Running crc32 50040.7z gave the expected 2e6a144 so I knew how to calculate the data CRC. The compressed image size in hex is wc -c 50040.7z | awk '{printf("%x",$1)}'.

I found How do I calculate the CRC32 of u-boot header? - Installing and Using OpenWrt - OpenWrt Forum (and later how do I calculate crc32 of a u-boot header in a modified firmware image? - Reverse Engineering Stack Exchange) to help me calculate the header CRC but you can probably find some proper resource.

As for moving the rootfs squashfs to the correct place, I don’t know how things work. That was just a guess based on the error messages and comparing the screen output between the working and broken versions. You’ll see that if you don’t move the squashfs then the following lines are missing (among others) showing a problem finding partitions:

[    0.390000] 2 uimage-fw partitions found on MTD device firmware
[    0.390000] 0x000000050000-0x00000016611c : "kernel"
[    0.400000] 0x00000016611c-0x000000800000 : "rootfs"

I tried hexedit for the first time, so I needed to use hexedit(1) - Linux man page to find out the keyboard commands as it’s a little tricky.

1 Like

Thanks for the details!
Something I miss from face-to-face classes is the ability to talk to everyone about how they arrive at the solutions they find - it’s really helpful to me to know when people ‘get’, and also helpful when i see where people are lead astray - both are what i keep in mind as i continually revise the content to gently (not too firmly, but not too gently either) guide people in the right direction.