-2

Is it possible replace in place a binary file located inside another binary file? For example, compressed firmware.bin file contains:

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
392           0x188           uImage header, header size: 64 bytes, header CRC: 0x15075729, created: 1969-12-31 23:59:59, image size: 1572736 bytes, Data Address: 0x20008000, Entry Point: 0x20008000, data CRC: 0x1DCD72E0, OS: Linux, CPU: ARM, image type: OS Kernel Image, compression type: none, image name: "abcd_rom_bin"
13596         0x351C          gzip compressed data, maximum compression, from Unix, last modified: 2017-08-02 06:04:47
1573192       0x180148        uImage header, header size: 64 bytes, header CRC: 0x6FFB9B98, created: 1969-12-31 23:59:59, image size: 8376320 bytes, Data Address: 0x0, Entry Point: 0x0, data CRC: 0xC95886CF, OS: Linux, CPU: ARM, image type: Filesystem Image, compression type: none, image name: "abcd_rom_bin"
1573256       0x180188        Squashfs filesystem, little endian, non-standard signature, version 3.1, size: 8372772 bytes, 1028 inodes, blocksize: 131072 bytes, created: 2017-08-02 06:39:51

One of these binaries contains also busybox binary, is there way to replace it without the full decompression?

  • Can you make your question clearer. – ctrl-alt-delor Apr 6 at 21:46
  • It will depend on the file format. – ctrl-alt-delor Apr 6 at 21:48
3

If you want to write the contents of file.gz at offset 13596 within firmware.bin (overwriting what's already there), you'd do:

zsh:

zmodload zsh/system
{ sysseek -u1 13596 && cat; } < file.gz 1<> firmware.bin

ksh93:

cat < file.gz 1<> firmware.bin >#((13596))

dd, any shell, but reading and writing one byte at a time

dd conv=notrunc bs=1 seek=13596 if=file.gz of=firmware.bin

GNU dd, any shell, more efficient

dd bs=64k conv=notrunc oflag=seek_bytes seek=13596 if=file.gz of=firmware.bin

Or to pad with zeros to the length of 1573192 - 13596 (POSIX sh syntax for the arithmetic expansion):

dd bs=64k conv=notrunc,sync bs="$((1573192 - 13596))" count=1 \
   oflag=seek_bytes seek=13596 if=file.gz of=firmware.bin

Now you'll need file.gz to be at most as large as the gzipped file that was already in there. And if those headers contain checksums of the different parts, then you'll also need to compute and update the checksums.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.