While RE an embedded device I ran into a problem - I need to patch a check in the kernel which has no sources available. Unpacking the kernel and binary-patching went smoothly. However I cannot get over repacking the vmlinux into zImage/bzImage.
I extracted the kernel using extract-vmlinux
(modified to show offset here):
$ ../../extract-vmlinux zImage > vmlinux
Found valid magic - decompressed using unlzma (tail -c+15967 "zImage" | unlzma)
Header at: head -c15966
Compressed at: tail -c+15967
$ binwalk zImage
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
15966 0x3E5E LZMA compressed data, properties: 0x5D, dictionary size: 67108864 bytes, uncompressed size: -1 bytes
Next, without any modifications, I wanted to recompress it back and keep the header, as to my knowledge it has the decompression code:
$ cat <(head -c15966 zImage) <(lzma -z < vmlinux) > zImage-repacked
$ ls -l
-rw-r--r-- 1 user user 3032080 Jun 5 22:32 zImage
-rw-r--r-- 1 user user 3024065 Jun 6 00:04 zImage-repacked
$ binwalk zImage-repacked
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
15966 0x3E5E LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: -1 bytes
The image came ~8k short, which didn't worry me (as my compression might have been more aggressive). However the image is now broken:
$ ../../extract-vmlinux zImage-repacked > /dev/null
extract-vmlinux: Cannot find vmlinux.
I also found that the extract-linux
script pipes everything after the offset to unlzma
but there's 9441 bytes of something which unlzma
ignores. When removed I'm getting a pure archive which matches the size saved just after it:
$ tail -c+15967 zImage | head -c-9441 | unlzma > /dev/null ; echo $?
0
$ tail -c+15967 zImage | head -c-9441 | unlzma | wc --bytes
13871216
$ tail -c+15967 zImage | head -c-9437 | tail -c4 | od -i --endian=little
0000000 13871216
0000004
I know the classical wisdom is "you have to recompile" but we're on RE - this is not possible ;)
How can I approach re-packing of the modified vmlinux back to LZMA-zImage?