24

I have already tried uncompress, gzip, and all other solutions that come up as google results and these have not worked for me.

To get just the image search for the GZ signature - 1f 8b 08 00.

> od -A d -t x1 vmlinuz | grep '1f 8b 08 00'
0024576 24 26 27 00 ae 21 16 00 1f 8b 08 00 7f 2f 6b 45

so the image begins at 24576+8 => 24584. Then just copy the image from the point and decompress it -

> dd if=vmlinuz bs=1 skip=24584 | zcat > vmlinux
1450414+0 records in
1450414+0 records out
1450414 bytes (1.5 MB) copied, 6.78127 s, 214 kB/s

Got these instructions verbatim from a forum online: http://www.codeguru.com/forum/showthread.php?t=415186

This process does not work for me and end up giving errors that states file not found 0024576 and all subsequent numbers.

How do I proceed extracting vmlinux from vmlinuz?

Thank you.

EDITED: This is a reverse engineering question. I have no access to the distro to install any RPM or recompile. I start with nothing but vmlinuz.

3
  • 2
    Why do you want to do this?
    – Flimzy
    Jun 18, 2011 at 4:12
  • This is actually for a friend who had to do something with it. The question seemed interesting and I pursued it for my academic interest. An alternative to this is to build the kernel :-/
    – Lord Loh.
    Jun 18, 2011 at 4:22
  • 1
    Well, for academic interest, I don't know if it's easily possible. I believe a vmlinuz kernel has an executable preamble--it's essentially a self-extracting archive. That's why using straight gunzip didn't work for you. The quoted method attempts to skip past that preamble. Why it doesn't work, I don't know for sure. Maybe somebody else with similar academic interests can give you a useful answer. :)
    – Flimzy
    Jun 18, 2011 at 4:25

7 Answers 7

37

The kernel sources now contain a script for this, extract-vmlinux. You don't need to roll your own.

See this SO answer.

3
  • 1
    Is this available in Ubuntu 14.04? I seen it in the git repo, what ubuntu package can I find it in? - Thank you :-)
    – Lord Loh.
    Feb 22, 2016 at 2:21
  • @LordLoh apt-file search extract-vmlinux gives several linux kernel header packages, and locate extract-vmlinux leads to a few hits on my local Ubuntu 18.04 machine: /usr/src/linux-headers-4.15.0-33/scripts/extract-vmlinux although nothing in PATH it seems. Sep 15, 2018 at 22:24
  • 1
    For ARM it fails with "extract-vmlinux: Cannot find vmlinux": unix.stackexchange.com/questions/352215/… Nov 19, 2018 at 17:51
34

Maybe you misunderstood what the author of that post meant.

  1. The vmlinuz file contains other things besides the gzipped content, so you need to find out where the gzipped content starts. To do that, use:

    od -A d -t x1 vmlinuz | grep '1f 8b 08 00'
    

    What this does is to show you where in that file you can find the gzip header. The output looks like:

    0024576 24 26 27 00 ae 21 16 00 1f 8b 08 00 7f 2f 6b 45
    

    This means that at 0024576 (at least for the author of the post, yours might be somewhere completely different) in the vmlinuz file, you will find the binary values "24 26 27 00 ae 21 16 00 1f 8b 08 00 7f 2f 6b 45". You're looking for 1f 8b 08 00, which can be found from character 9 onwards, or, at 0024576 + 8 (start counting from 0) = 24584.

  2. Now that you know where the gzipped content starts (at position 24584) you can use dd to extract that gzipped content and ungzip it. To do that, use:

    dd if=vmlinuz bs=1 skip=24584 | zcat > vmlinux
    

    The first command will seek to that position and copy everything to stdout. zcat then will uncompress everything it gets from stdin and will output the uncompressed string to stdout. Then the > will redirect zcat's output to a new file named vmlinux.

4
  • Thanks! That makes sense now. However, '1f 8b 08 00' did nor return anything for my kernel after a few seconds of execution. Apparently the code has changed. Any suggestion on how to get the new set of magic numbers?
    – Lord Loh.
    Jun 18, 2011 at 4:32
  • @Lord Loh.: Two possibilities: 1) The magic numbers cross line boundaries in od's output. Use bgrep to search for 1f8b0800. 2) The kernel is compressed using a different algorithm. Try fd377a585a00 for xz or 425a6839 for bzip2. Jun 18, 2011 at 9:16
  • @ grawity - Thank you for the reply. I tried that. neither 1f8b0800, fd377a585a00 nor 425a6839 returned any results. So I started chopping down the magic string byte by byte till I got some results, and they were hundreds of matches :-( So I am still without success.
    – Lord Loh.
    Jun 19, 2011 at 16:51
  • LZMA is "5d 00 00 80" according to minimodding.com/…. Still didn't work for me. Mar 12, 2012 at 10:55
7

Actually, before generating the vmlinuz file, most symbols are stripped. So you cannot rebuild a true vmlinux from vmlinuz, the file will not be as useful for debugging.

4

I ran into simple problem - looking for correct version of vmlinux for crash. Instead of trying to decompress vmlinuz to vmlinux.

The better solution is: install the RPM: kernel-debuginfo, that RPM contains proper vmlinux file.

Pay attention to the rpm name, there are multiple similar (confusing) names. Gotta be: kernel-debuginfo-$(version).rpm

2

Modern kernels are not always (in fact, not generally) gzip compressed. They may use bzip2 or LZMA. A quick web search didn't help me find the magic strings for those compression methods--you might be better off checking several kernel images to find the invariant header that includes the decompression code.

0
1

The decompression lines above worked for me and, of course, the kernel was stripped. Therefore no good information there.

If you need to make changes to your old kernel, like put it in debug, use uname -r to get the revision of your kernel and get its source:

sudo apt-get source linux-image-\`uname -r\`

The source will be in /usr/src/linux... cd to the source tree and:

make oldconfig
make

This will attempt to find the file containing the config for the currently running kernel -- usually

/boot/config-\`uname -r\` 

and use it for this build thus recreating the running kernel.

Build that the way you want it; have access to the unstripped kernel as needed.

The shells above probably won't find the gzip magic number due to spacing. Yes they are still compressed the same way, though I'm writing a year after the original discussion. Send the output to less and search for 1f 8b or even 1f. Check the rest of the bytes manually to determine a match and verify you have the first instance. Use the offset found remembering it is decimal.

0

You might not have readelf installed and need the elfutils package installed with the call being eu-readelf instead.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .