* Initramfs from existing vmlinuz @ 2008-12-23 22:28 Martin Schlemmer 2008-12-23 23:34 ` Willy Tarreau 0 siblings, 1 reply; 7+ messages in thread From: Martin Schlemmer @ 2008-12-23 22:28 UTC (permalink / raw) To: linux-kernel Hi I had a bit of an accident, and wondered if somebody already had to try to extract the initramfs image from an existing vmlinuz? I did try google, but either my search terms was not right, or nobody really touched on the subject before, because all the results mostly dealt with an external image. Any advice will be appreciated. Thanks MS ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Initramfs from existing vmlinuz 2008-12-23 22:28 Initramfs from existing vmlinuz Martin Schlemmer @ 2008-12-23 23:34 ` Willy Tarreau 2008-12-24 11:37 ` Martin Schlemmer 2009-01-05 11:12 ` Initramfs from existing vmlinuz Ian Campbell 0 siblings, 2 replies; 7+ messages in thread From: Willy Tarreau @ 2008-12-23 23:34 UTC (permalink / raw) To: Martin Schlemmer; +Cc: linux-kernel On Wed, Dec 24, 2008 at 12:28:53AM +0200, Martin Schlemmer wrote: > Hi > > I had a bit of an accident, and wondered if somebody already had to try to extract the initramfs image from an existing vmlinuz? > > I did try google, but either my search terms was not right, or nobody really touched on the subject before, because all the results mostly dealt with an external image. > > Any advice will be appreciated. yes, it happens to me from time to time. You first have to extract and uncompress the ELF image from vmlinuz. For this, look for the gzip signature 1F 8B 08 in your vmlinuz, and feed all data starting from this point to zcat. Either you do the same on the resulting file -and you may find several compressed images- or you simply pass it through "objdump -h". It will show you a .init.ramfs section. Use the fourth field as the file offset, and dump from that position. You'll find your initramfs, likely starting with 1F 8B 08 since it's supposed to be compressed with gzip. You need an hex editor, dd, zcat and objdump for this. It's not much complicated once you have the tools, but it might require a few attempts before finding the right image (I tend to find config.gz before initramfs). Regards, Willy ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Initramfs from existing vmlinuz 2008-12-23 23:34 ` Willy Tarreau @ 2008-12-24 11:37 ` Martin Schlemmer 2008-12-25 17:55 ` Martin Schlemmer 2008-12-25 18:17 ` Initramfs from existing vmlinuz (#2) Martin Schlemmer 2009-01-05 11:12 ` Initramfs from existing vmlinuz Ian Campbell 1 sibling, 2 replies; 7+ messages in thread From: Martin Schlemmer @ 2008-12-24 11:37 UTC (permalink / raw) To: Willy Tarreau, Martin Schlemmer; +Cc: linux-kernel >>> On 2008/12/24 at 01:34 AM, Willy Tarreau <w@1wt.eu> wrote: > On Wed, Dec 24, 2008 at 12:28:53AM +0200, Martin Schlemmer wrote: Hi Willy >> I had a bit of an accident, and wondered if somebody already had to try to > extract the initramfs image from an existing vmlinuz? >> >> I did try google, but either my search terms was not right, or nobody > really touched on the subject before, because all the results mostly dealt > with an external image. >> >> Any advice will be appreciated. > > yes, it happens to me from time to time. > You first have to extract and uncompress the ELF image from vmlinuz. For > this, look for the gzip signature 1F 8B 08 in your vmlinuz, and feed all > data starting from this point to zcat. Either you do the same on the > resulting file -and you may find several compressed images- or you simply > pass it through "objdump -h". It will show you a .init.ramfs section. Use > the fourth field as the file offset, and dump from that position. You'll > find your initramfs, likely starting with 1F 8B 08 since it's supposed > to be compressed with gzip. > > You need an hex editor, dd, zcat and objdump for this. It's not much > complicated once you have the tools, but it might require a few attempts > before finding the right image (I tend to find config.gz before initramfs). > Appreciated, I should be able to go from here now - just getting the starting point is sometimes the main issue. Thanks M ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Initramfs from existing vmlinuz 2008-12-24 11:37 ` Martin Schlemmer @ 2008-12-25 17:55 ` Martin Schlemmer 2008-12-25 18:17 ` Initramfs from existing vmlinuz (#2) Martin Schlemmer 1 sibling, 0 replies; 7+ messages in thread From: Martin Schlemmer @ 2008-12-25 17:55 UTC (permalink / raw) To: Willy Tarreau; +Cc: linux-kernel [-- Attachment #1: Type: text/plain, Size: 1688 bytes --] >>> On 2008/12/24 at 01:37 PM, "Martin Schlemmer" <Martin.Schlemmer@nwu.ac.za> wrote: >>>> On 2008/12/24 at 01:34 AM, Willy Tarreau <w@1wt.eu> wrote: >> On Wed, Dec 24, 2008 at 12:28:53AM +0200, Martin Schlemmer wrote: Hi >>> I had a bit of an accident, and wondered if somebody already had to try to >> extract the initramfs image from an existing vmlinuz? >>> >>> I did try google, but either my search terms was not right, or nobody >> really touched on the subject before, because all the results mostly dealt >> with an external image. >>> >>> Any advice will be appreciated. >> >> yes, it happens to me from time to time. >> You first have to extract and uncompress the ELF image from vmlinuz. For >> this, look for the gzip signature 1F 8B 08 in your vmlinuz, and feed all >> data starting from this point to zcat. Either you do the same on the >> resulting file -and you may find several compressed images- or you simply >> pass it through "objdump -h". It will show you a .init.ramfs section. Use >> the fourth field as the file offset, and dump from that position. You'll >> find your initramfs, likely starting with 1F 8B 08 since it's supposed >> to be compressed with gzip. >> >> You need an hex editor, dd, zcat and objdump for this. It's not much >> complicated once you have the tools, but it might require a few attempts >> before finding the right image (I tend to find config.gz before initramfs). >> > > Appreciated, I should be able to go from here now - just getting the starting > point is sometimes the main issue. > Simple Perl script to do above in case anybody might find it useful in the future. M [-- Attachment #2: extract_initramfs.pl --] [-- Type: application/octet-stream, Size: 2103 bytes --] #!/usr/bin/perl # # extract_initramfs.pl: extracts the initramfs out of a packed kernel image # # Copyright (C) Martin Schlemmer <azarah@nosferatu.za.org> # # Released under the terms of the GNU GPL # use strict; use warnings; use Cwd; use Encode; use IO::File; use IO::Pipe; use IO::Uncompress::Gunzip qw (gunzip $GunzipError); if (! defined ($ARGV[0]) && ! defined ($ARGV[1])) { print "usage: $0 VMLINUZ [VMLINUX] [INITRAMFS_IMAGE]\n"; exit (1); } if (! -f $ARGV[0]) { print "$ARGV[0] does not exists\n"; exit (1); } my ($input,$vm_output,$rm_output) = @ARGV; $vm_output = cwd . '/vmlinux', if (! defined ($vm_output) || $vm_output eq ''); $rm_output = cwd . '/initramfs.cpio.gz', if (! defined ($rm_output) || $rm_output eq ''); eval { my $fh = IO::File->new; $fh->open ($ARGV[0]) or die ($!); $fh->binmode; my $data; my $count = 0; do { $data = ''; $fh->seek ($count++, 0) or die ($!); $fh->read ($data, 3) or die ($!); } until ($data =~ /^\x{1F}\x{8B}\x{08}$/ || $fh->eof); if ($data !~ /^\x{1F}\x{8B}\x{08}$/ || $fh->eof) { print STDERR "Could not find GZIP marker!\n"; exit (1); } $fh->seek (--$count, 0) or die ($!); $data = ''; while (! $fh->eof) { my $buffer; $fh->read ($buffer, 2048) or die ($!); $data .= $buffer; } $fh->close; my $image; gunzip \$data => \$image, or die ("Gunzip failed: $GunzipError\n"); $fh->open ($vm_output, '>') or die ($!); $fh->binmode; $fh->write ($image) or die ($!); $fh->close; my $have_ramfs = 0; my $pipe = IO::Pipe->new or die ($!); $pipe->reader ('objdump', '-h', $vm_output) or die ($!); while (my $line = $pipe->getline) { if ($line =~ /^\s+\d+\s+(\S+)\s+(\S+)\s+\S+\s+\S+\s+(\S+)\s+/) { my ($section,$size,$offset) = ($1,$2,$3); next if ($section ne '.init.ramfs'); $fh->open ($rm_output, '>') or die ($!); $fh->write ($image, hex ($size), hex ($offset)) or die ($!); $fh->close; $have_ramfs = 1; last; } } $pipe->close; die ('No \'.init.ramfs\' section found!') if (! $have_ramfs); }; if ($@) { printf STDERR "$@\n"; exit (1); } exit (0); ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Initramfs from existing vmlinuz (#2) 2008-12-24 11:37 ` Martin Schlemmer 2008-12-25 17:55 ` Martin Schlemmer @ 2008-12-25 18:17 ` Martin Schlemmer 1 sibling, 0 replies; 7+ messages in thread From: Martin Schlemmer @ 2008-12-25 18:17 UTC (permalink / raw) To: Willy Tarreau, Martin Schlemmer; +Cc: linux-kernel >>> On 2008/12/24 at 01:37 PM, "Martin Schlemmer" <Martin.Schlemmer@nwu.ac.za> wrote: >>>> On 2008/12/24 at 01:34 AM, Willy Tarreau <w@1wt.eu> wrote: >> On Wed, Dec 24, 2008 at 12:28:53AM +0200, Martin Schlemmer wrote: Hi >>> I had a bit of an accident, and wondered if somebody already had to try to >> extract the initramfs image from an existing vmlinuz? >>> >>> I did try google, but either my search terms was not right, or nobody >> really touched on the subject before, because all the results mostly dealt >> with an external image. >>> >>> Any advice will be appreciated. >> >> yes, it happens to me from time to time. >> You first have to extract and uncompress the ELF image from vmlinuz. For >> this, look for the gzip signature 1F 8B 08 in your vmlinuz, and feed all >> data starting from this point to zcat. Either you do the same on the >> resulting file -and you may find several compressed images- or you simply >> pass it through "objdump -h". It will show you a .init.ramfs section. Use >> the fourth field as the file offset, and dump from that position. You'll >> find your initramfs, likely starting with 1F 8B 08 since it's supposed >> to be compressed with gzip. >> >> You need an hex editor, dd, zcat and objdump for this. It's not much >> complicated once you have the tools, but it might require a few attempts >> before finding the right image (I tend to find config.gz before initramfs). >> > Not sure if the previous post got through due to mail scanner, but it was also an older version. Anyhow, below is a simple Perl script to do above if anybody ever have the same need in the future. M ------------------------------- #!/usr/bin/perl # # extract_initramfs.pl: extracts the initramfs out of a packed kernel image # # Copyright (C) Martin Schlemmer <azarah@nosferatu.za.org> # # Released under the terms of the GNU GPL # use strict; use warnings; use Cwd; use Encode; use IO::File; use IO::Pipe; use IO::Uncompress::Gunzip qw (gunzip $GunzipError); my ($input,$vm_output,$rfs_output) = @ARGV; $vm_output = cwd . '/vmlinux', if (! defined ($vm_output) || $vm_output eq ''); $rfs_output = cwd . '/initramfs.cpio.gz', if (! defined ($rfs_output) || $rfs_output eq ''); if (! defined ($input)) { print "usage: $0 VMLINUZ [VMLINUX] [INITRAMFS_IMAGE]\n"; exit (1); } if (! -f $input) { print "'$input' does not exist!\n"; exit (1); } eval { my $fh = IO::File->new; $fh->open ($input) or die ($!); $fh->binmode; my $data; my $count = 0; do { $data = ''; $fh->seek ($count++, 0) or die ($!); $fh->read ($data, 3) or die ($!); } until ($data eq "\x1F\x8B\x08" || $fh->eof); if ($data ne "\x1F\x8B\x08" || $fh->eof) { print STDERR "Could not find GZIP marker!\n"; exit (1); } $fh->seek (--$count, 0) or die ($!); $data = ''; while (! $fh->eof) { my $buffer; $fh->read ($buffer, 2048) or die ($!); $data .= $buffer; } $fh->close; my $image_data; gunzip \$data => \$image_data, or die ("Gunzip failed: $GunzipError\n"); $fh->open ($vm_output, '>') or die ($!); $fh->binmode; $fh->write ($image_data) or die ($!); $fh->close; my $have_ramfs = 0; my $pipe = IO::Pipe->new or die ($!); $pipe->reader ('objdump', '-h', $vm_output) or die ($!); while (my $line = $pipe->getline) { if ($line =~ /^\s+\d+\s+(\S+)\s+(\S+)\s+\S+\s+\S+\s+(\S+)\s+/) { my ($section,$size,$offset) = ($1,$2,$3); next if ($section ne '.init.ramfs'); $fh->open ($rfs_output, '>') or die ($!); $fh->write ($image_data, hex ($size), hex ($offset)) or die ($!); $fh->close; $have_ramfs = 1; last; } } $pipe->close; die ('No \'.init.ramfs\' section found!') if (! $have_ramfs); }; if ($@) { printf STDERR "$@\n"; exit (1); } exit (0); ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Initramfs from existing vmlinuz 2008-12-23 23:34 ` Willy Tarreau 2008-12-24 11:37 ` Martin Schlemmer @ 2009-01-05 11:12 ` Ian Campbell 2009-01-05 11:47 ` Willy Tarreau 1 sibling, 1 reply; 7+ messages in thread From: Ian Campbell @ 2009-01-05 11:12 UTC (permalink / raw) To: Willy Tarreau; +Cc: Martin Schlemmer, linux-kernel [-- Attachment #1: Type: text/plain, Size: 730 bytes --] On Wed, 2008-12-24 at 00:34 +0100, Willy Tarreau wrote: > You first have to extract and uncompress the ELF image from vmlinuz. > For this, look for the gzip signature 1F 8B 08 in your vmlinuz, and > feed all data starting from this point to zcat. Since v2.6.26 (I think, it was v2.08 of the x86 bzImage format anyhow, which was the same point the payload became ELF formatted) you can find it directly using the payload_offset and payload_length fields in the bzImage header. Attached bzexplode.c demonstrates this. e.g. "bzexplode vmlinuz | zcat > vmlinux.elf" Ian. -- Ian Campbell Current Noise: Electric Wizard - Saturn's Children A likely impossibility is always preferable to an unconvincing possibility. -- Aristotle [-- Attachment #2: bzexplode.c --] [-- Type: text/x-csrc, Size: 1251 bytes --] #include <stdio.h> #include <fcntl.h> #include <stdint.h> #include <unistd.h> #include <inttypes.h> #include <err.h> #include <sys/types.h> #include <sys/mman.h> #include <sys/stat.h> int main(int argc, char **argv) { int fd; struct stat sb; void *p; uint8_t *hdr; int setup_sectors; uint32_t compressed_payload_offset; uint32_t compressed_payload_length; if (argc != 2) errx(1, "usage: bzexplode <bzImage>"); fd = open(argv[1], O_RDONLY); if (fd < 0) err(1, "open"); if (fstat(fd, &sb) < 0) err(1, "fstat"); p = mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0); if (p == MAP_FAILED) err(1, "mmap"); hdr = p; setup_sectors = hdr[0x1f1]; compressed_payload_offset = *(uint32_t*)&hdr[0x248]; fprintf(stderr, "setup sectors %d\n", setup_sectors); compressed_payload_offset += (setup_sectors+1) * 512; //compressed_payload_length = *(uint32_t*)(p + compressed_payload_offset - 4); compressed_payload_length = *(uint32_t*)&hdr[0x24c]; fprintf(stderr, "compressed_payload_offset %"PRIx32" (abs)\n", compressed_payload_offset); fprintf(stderr, "compressed_payload_length %"PRIx32"\n", compressed_payload_length); write(1, p + compressed_payload_offset, compressed_payload_length); return 0; } ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Initramfs from existing vmlinuz 2009-01-05 11:12 ` Initramfs from existing vmlinuz Ian Campbell @ 2009-01-05 11:47 ` Willy Tarreau 0 siblings, 0 replies; 7+ messages in thread From: Willy Tarreau @ 2009-01-05 11:47 UTC (permalink / raw) To: Ian Campbell; +Cc: Martin Schlemmer, linux-kernel On Mon, Jan 05, 2009 at 11:12:26AM +0000, Ian Campbell wrote: > On Wed, 2008-12-24 at 00:34 +0100, Willy Tarreau wrote: > > You first have to extract and uncompress the ELF image from vmlinuz. > > For this, look for the gzip signature 1F 8B 08 in your vmlinuz, and > > feed all data starting from this point to zcat. > > Since v2.6.26 (I think, it was v2.08 of the x86 bzImage format anyhow, > which was the same point the payload became ELF formatted) you can find > it directly using the payload_offset and payload_length fields in the > bzImage header. Attached bzexplode.c demonstrates this. e.g. "bzexplode > vmlinuz | zcat > vmlinux.elf" Thanks Ian. Indeed, I'm sure this will be useful from time to time! Cheers, Willy ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2009-01-05 11:47 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-12-23 22:28 Initramfs from existing vmlinuz Martin Schlemmer 2008-12-23 23:34 ` Willy Tarreau 2008-12-24 11:37 ` Martin Schlemmer 2008-12-25 17:55 ` Martin Schlemmer 2008-12-25 18:17 ` Initramfs from existing vmlinuz (#2) Martin Schlemmer 2009-01-05 11:12 ` Initramfs from existing vmlinuz Ian Campbell 2009-01-05 11:47 ` Willy Tarreau
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox