Rizin
unix-like reverse engineering framework and cli tools
scanlzma.c
Go to the documentation of this file.
1 /*
2  scanlzma, scan for lzma compressed data in stdin and echo it to stdout.
3  Copyright (C) 2006 Timo Lindfors
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 */
15 
16 /* Usage example:
17 
18  $ wget http://www.wifi-shop.cz/Files/produkty/wa2204/wa2204av1.4.1.zip
19  $ unzip wa2204av1.4.1.zip
20  $ gcc scanlzma.c -o scanlzma -Wall
21  $ ./scanlzma 0 < WA2204-FW1.4.1/linux-1.4.bin | lzma -c -d | strings | grep -i "copyright"
22  UpdateDD version 2.5, Copyright (C) 2005 Philipp Benner.
23  Copyright (C) 2005 Philipp Benner.
24  Copyright (C) 2005 Philipp Benner.
25  mawk 1.3%s%s %s, Copyright (C) Michael D. Brennan
26  # Copyright (C) 1998, 1999, 2001 Henry Spencer.
27  ...
28 
29 */
30 
31 
32 /* LZMA compressed file format */
33 /* --------------------------- */
34 /* Offset Size Description */
35 /* 0 1 Special LZMA properties for compressed data */
36 /* 1 4 Dictionary size (little endian) */
37 /* 5 8 Uncompressed size (little endian). -1 means unknown size */
38 /* 13 Compressed data */
39 
40 #include <stdlib.h>
41 #include <stdio.h>
42 #include <string.h>
43 
44 #define BUFSIZE 4096
45 
46 int find_lzma_header(unsigned char *buf) {
47  return (buf[0] < 0xE1
48  && buf[0] == 0x5d
49  && buf[4] < 0x20
50  && (memcmp (buf + 10 , "\x00\x00\x00", 3) == 0
51  || (memcmp (buf + 5, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8) == 0)));
52 }
53 
54 int main(int argc, char *argv[]) {
55  unsigned char buf[BUFSIZE];
56  int ret, i, numlzma, blocks=0;
57 
58  if (argc != 2) {
59  printf("usage: %s numlzma < infile | lzma -c -d > outfile\n"
60  "where numlzma is index of lzma file to extract, starting from zero.\n",
61  argv[0]);
62  exit(1);
63  }
64  numlzma = atoi(argv[1]);
65 
66  for (;;) {
67  /* Read data. */
68  ret = fread(buf, BUFSIZE, 1, stdin);
69  if (ret != 1)
70  break;
71 
72  /* Scan for signature. */
73  for (i = 0; i<BUFSIZE-23; i++) {
74  if (find_lzma_header(buf+i) && numlzma-- <= 0) {
75  fwrite(buf+i, (BUFSIZE-i), 1, stdout);
76  for (;;) {
77  int ch;
78  ch = getchar();
79  if (ch == EOF)
80  exit(0);
81  putchar(ch);
82  }
83  }
84  }
85  blocks++;
86  }
87  return 1;
88 }
lzma_index ** i
Definition: index.h:629
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
voidpf void * buf
Definition: ioapi.h:138
static static fork const void static count static fd const char const char static newpath char char argv
Definition: sflib.h:40
int main(int argc, char *argv[])
Definition: scanlzma.c:54
int find_lzma_header(unsigned char *buf)
Definition: scanlzma.c:46
#define BUFSIZE
Definition: scanlzma.c:44
uint64_t blocks
Definition: list.c:104