Open Ansuel opened 7 months ago
I don't have your device, so I can't comment on that. Maybe you messed up things. In my opinion, as long as you don't mess with the kernel image, you don't need to update its CRC in the header. Also, if you modify the root filesystem and it aligns with the length specified in the header, then you don't even need to touch the header, and you're good to go. But if you heavily modify the root filesystem, then you need to fix all offsets and lengths in the header and regenerate the hash for the header, which is going to be messy, so refrain from it. As for the CRC algorithm, it's in U-Boot, which may be different for you as I have seen devices with their own custom implementation. And if you still insist on finding the CRC algorithm for your vendor, I'll narrow down your search area so you don't need to look for it in the U-Boot. As you may know, IoT devices include the mechanism to update the firmware while the device is running, which leaves us with an important clue that the mechanism to verify the CRC of components should be in the binary updating the firmware, and that binary is usually called 'fw_flashing'. Analyze this binary to find the CRC algorithm, but do note that this binary may delegate this to another binary.
Well I had some fun with ghidra and confirmed some thing... The header size is ALWAYS 0x4a
Normally if the thing have 2 partition it's at 0x8000 and at 0x780000 The first byte is header offset (most of the time it's zero... but uboot source offset it) and then there is 0x4a header. After that there is the header CRC. The header CRC algo is the usual one CRC-32 0x04C11DB7 init 0xFFFFFFFF refin refout and xorout 0xFFFFFFFF.
On these system also rootfs is guarded by CRC and needs to be updated.
Just leaving this here for reference... ALSO CRC is swapped (little-endian)
@0xXA The confusing part is that rootfs offset value doesn't make any sense... Any clue where that values comes from?
I'm creating a little python script that will parse the header and validate it (and add way to regenerate it)
The header size is ALWAYS 0x4a
Nope, there's no such thing as a 'Fixed header size' due to the fact that vendors can opt for as many images as they want. For example, you can consider a flash of 128Mb, which may contain more than 2 rootfs and other images for different purposes. It totally depends on the vendor and their intended purpose. Also, there are more such headers in U-Boot if you carefully analyze the firmware, which may be serving different purposes. The fact that you found 0x4a is valid too, but the main headers which contain rootfs and other partition offsets and sizes are variable in length and will always be padded to make it a multiple of 16 so that the kernel will begin at a good offset.
Normally if the thing have 2 partition it's at 0x8000 and at 0x780000
These are the main header offsets, and you can't assume that the headers will always begin at these offsets. However, you can assume that the kernel will certainly be adjacent to the headers. If you look at the partition dumps, both kernel images have these headers preceding them in the partition dumps.
On these system also rootfs is guarded by CRC and needs to be updated.
Nope, it varies from vendor to vendor. In my case, the rootfs was not guarded by CRC32 checks, only the kernel.
CRC is swapped (little-endian)
Yes, it's usually stored in host byte order for most devices.
The confusing part is that rootfs offset value doesn't make any sense... Any clue where that values comes from?
Are you referring to the values present in the header ? If yes, then all these offsets are after adjustments by padding them with 0xff
to make them a multiple of 16, which serves two purposes: first, they need to adjust the firmware to the size of the flash, and second, adjustments to multiples of 16 help them to effectively regenerate the offsets from the base address of the header from the U-Boot code.
@Ansuel which ONT are you working on? I did a mod script for ZTE F601v6 almost 1 year ago, now i'm trying to figure out F6005 that seems to work like this unit but with Secboot.
This ONT has the rootfs (that's a jffs2) CRC embedded in the header, so any change needs a CRC fix both for rootfs and header itself. This device has also secboot enable and a sort of signature, but not sure if this is also dynamically based on CRC into the heaer
Did you manage to find what kind of crc algo they use?
I'm trying to modify a Fiber ONT that makes use of the ZTE firmware but I'm stuck with crc header error...
Also it would be handy to understand the CRC instead of relying to uboot to provide it.