Here is a very simple program that tears the image apart. It simply scans
looking for the gzip magic numbers and copies the rest. The output can
then be un-gzip-ped, with a harmless complaint about some extra stuff on
the end.
As an example, a pseudo-uname can be done as:
breakzi /boot/zImage.2.1.42 | gzip -d | strings -a | grep '^Linux version'
=================================================================
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
/*
# Gzip
0 string \037\213 gzip compressed data
>2 byte 8 - deflate method
>3 byte &0x1 , ascii
>3 byte &0x2 , continuation
>3 byte &0x4 , extra field
>3 byte &0x8 , original file name
>3 byte &0x10 , comment
>3 byte &0x20 , encrypted
>8 byte 2 , max compression
>8 byte 4 , max speed
*/
#define BSIZE 4096
#define C1 037
#define C2 0213
#define C3 8
main(int argc, char **argv)
{
unsigned char *bbuf;
int bc;
int ifd = 0;
int ofd = 1;
if (argc > 3) {
fprintf(stderr, "usage: breakzi [in-file [out-file]]\n");
exit(1);
}
if (argc > 1) {
if ((ifd = open(argv[1], O_RDONLY)) < 0) {
perror(argv[1]);
exit(1);
}
}
if (argc > 2) {
if ((ofd = open(argv[2], O_WRONLY | O_CREAT, 0755)) < 0) {
perror(argv[2]);
exit(1);
}
}
if ((bbuf = (char *)malloc(BSIZE)) < 0) {
perror("bbuf");
exit(1);
}
while (1) {
readbyt(ifd, bbuf + 0);
if (bbuf[0] != C1) {
continue;
}
overlap:
readbyt(ifd, bbuf + 1);
if (bbuf[1] != C2) {
if (bbuf[1] == C1) {
bbuf[0] = C1;
goto overlap;
}
continue;
}
readbyt(ifd, bbuf + 2);
if (bbuf[2] != C3) {
if (bbuf[2] == C1) {
bbuf[0] = C1;
goto overlap;
}
continue;
}
break;
}
write(ofd, bbuf, 3);
while (bc = read(ifd, bbuf, BSIZE)) {
write(ofd, bbuf, bc);
}
}
readbyt(int ifd, char *buf)
{
int bc;
if ((bc = read(ifd, buf, 1)) != 1) {
fprintf(stderr, "EOF encountered before header\n");
exit(1);
}
}
=================================================================
B. D. Elliott bde@accessone.com (Seattle)