Rizin
unix-like reverse engineering framework and cli tools
mztools.c
Go to the documentation of this file.
1 /*
2  Additional tools for Minizip
3  Code: Xavier Roche '2004
4  License: Same as ZLIB (www.gzip.org)
5 */
6 
7 /* Code */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include "zlib.h"
12 #include "unzip.h"
13 
14 #define READ_8(adr) ((unsigned char)*(adr))
15 #define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) )
16 #define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) )
17 
18 #define WRITE_8(buff, n) do { \
19  *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \
20 } while(0)
21 #define WRITE_16(buff, n) do { \
22  WRITE_8((unsigned char*)(buff), n); \
23  WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \
24 } while(0)
25 #define WRITE_32(buff, n) do { \
26  WRITE_16((unsigned char*)(buff), (n) & 0xffff); \
27  WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \
28 } while(0)
29 
30 extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered)
31 const char* file;
32 const char* fileOut;
33 const char* fileOutTmp;
34 uLong* nRecovered;
35 uLong* bytesRecovered;
36 {
37  int err = Z_OK;
38  FILE* fpZip = fopen(file, "rb");
39  FILE* fpOut = fopen(fileOut, "wb");
40  FILE* fpOutCD = fopen(fileOutTmp, "wb");
41  if (fpZip != NULL && fpOut != NULL) {
42  int entries = 0;
43  uLong totalBytes = 0;
44  char header[30];
45  char filename[1024];
46  char extra[1024];
47  int offset = 0;
48  int offsetCD = 0;
49  while ( fread(header, 1, 30, fpZip) == 30 ) {
50  int currentOffset = offset;
51 
52  /* File entry */
53  if (READ_32(header) == 0x04034b50) {
54  unsigned int version = READ_16(header + 4);
55  unsigned int gpflag = READ_16(header + 6);
56  unsigned int method = READ_16(header + 8);
57  unsigned int filetime = READ_16(header + 10);
58  unsigned int filedate = READ_16(header + 12);
59  unsigned int crc = READ_32(header + 14); /* crc */
60  unsigned int cpsize = READ_32(header + 18); /* compressed size */
61  unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */
62  unsigned int fnsize = READ_16(header + 26); /* file name length */
63  unsigned int extsize = READ_16(header + 28); /* extra field length */
64  filename[0] = extra[0] = '\0';
65 
66  /* Header */
67  if (fwrite(header, 1, 30, fpOut) == 30) {
68  offset += 30;
69  } else {
70  err = Z_ERRNO;
71  break;
72  }
73 
74  /* Filename */
75  if (fnsize > 0) {
76  if (fnsize < sizeof(filename)) {
77  if (fread(filename, 1, fnsize, fpZip) == fnsize) {
78  if (fwrite(filename, 1, fnsize, fpOut) == fnsize) {
79  offset += fnsize;
80  } else {
81  err = Z_ERRNO;
82  break;
83  }
84  } else {
85  err = Z_ERRNO;
86  break;
87  }
88  } else {
89  err = Z_ERRNO;
90  break;
91  }
92  } else {
94  break;
95  }
96 
97  /* Extra field */
98  if (extsize > 0) {
99  if (extsize < sizeof(extra)) {
100  if (fread(extra, 1, extsize, fpZip) == extsize) {
101  if (fwrite(extra, 1, extsize, fpOut) == extsize) {
102  offset += extsize;
103  } else {
104  err = Z_ERRNO;
105  break;
106  }
107  } else {
108  err = Z_ERRNO;
109  break;
110  }
111  } else {
112  err = Z_ERRNO;
113  break;
114  }
115  }
116 
117  /* Data */
118  {
119  int dataSize = cpsize;
120  if (dataSize == 0) {
121  dataSize = uncpsize;
122  }
123  if (dataSize > 0) {
124  char* data = malloc(dataSize);
125  if (data != NULL) {
126  if ((int)fread(data, 1, dataSize, fpZip) == dataSize) {
127  if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) {
128  offset += dataSize;
129  totalBytes += dataSize;
130  } else {
131  err = Z_ERRNO;
132  }
133  } else {
134  err = Z_ERRNO;
135  }
136  free(data);
137  if (err != Z_OK) {
138  break;
139  }
140  } else {
141  err = Z_MEM_ERROR;
142  break;
143  }
144  }
145  }
146 
147  /* Central directory entry */
148  {
149  char header[46];
150  char* comment = "";
151  int comsize = (int) strlen(comment);
152  WRITE_32(header, 0x02014b50);
153  WRITE_16(header + 4, version);
154  WRITE_16(header + 6, version);
155  WRITE_16(header + 8, gpflag);
156  WRITE_16(header + 10, method);
157  WRITE_16(header + 12, filetime);
158  WRITE_16(header + 14, filedate);
159  WRITE_32(header + 16, crc);
160  WRITE_32(header + 20, cpsize);
161  WRITE_32(header + 24, uncpsize);
162  WRITE_16(header + 28, fnsize);
163  WRITE_16(header + 30, extsize);
164  WRITE_16(header + 32, comsize);
165  WRITE_16(header + 34, 0); /* disk # */
166  WRITE_16(header + 36, 0); /* int attrb */
167  WRITE_32(header + 38, 0); /* ext attrb */
168  WRITE_32(header + 42, currentOffset);
169  /* Header */
170  if (fwrite(header, 1, 46, fpOutCD) == 46) {
171  offsetCD += 46;
172 
173  /* Filename */
174  if (fnsize > 0) {
175  if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) {
176  offsetCD += fnsize;
177  } else {
178  err = Z_ERRNO;
179  break;
180  }
181  } else {
183  break;
184  }
185 
186  /* Extra field */
187  if (extsize > 0) {
188  if (fwrite(extra, 1, extsize, fpOutCD) == extsize) {
189  offsetCD += extsize;
190  } else {
191  err = Z_ERRNO;
192  break;
193  }
194  }
195 
196  /* Comment field */
197  if (comsize > 0) {
198  if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) {
199  offsetCD += comsize;
200  } else {
201  err = Z_ERRNO;
202  break;
203  }
204  }
205 
206 
207  } else {
208  err = Z_ERRNO;
209  break;
210  }
211  }
212 
213  /* Success */
214  entries++;
215 
216  } else {
217  break;
218  }
219  }
220 
221  /* Final central directory */
222  {
223  int entriesZip = entries;
224  char header[22];
225  char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools";
226  int comsize = (int) strlen(comment);
227  if (entriesZip > 0xffff) {
228  entriesZip = 0xffff;
229  }
230  WRITE_32(header, 0x06054b50);
231  WRITE_16(header + 4, 0); /* disk # */
232  WRITE_16(header + 6, 0); /* disk # */
233  WRITE_16(header + 8, entriesZip); /* hack */
234  WRITE_16(header + 10, entriesZip); /* hack */
235  WRITE_32(header + 12, offsetCD); /* size of CD */
236  WRITE_32(header + 16, offset); /* offset to CD */
237  WRITE_16(header + 20, comsize); /* comment */
238 
239  /* Header */
240  if (fwrite(header, 1, 22, fpOutCD) == 22) {
241 
242  /* Comment field */
243  if (comsize > 0) {
244  if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) {
245  err = Z_ERRNO;
246  }
247  }
248 
249  } else {
250  err = Z_ERRNO;
251  }
252  }
253 
254  /* Final merge (file + central directory) */
255  fclose(fpOutCD);
256  if (err == Z_OK) {
257  fpOutCD = fopen(fileOutTmp, "rb");
258  if (fpOutCD != NULL) {
259  int nRead;
260  char buffer[8192];
261  while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) {
262  if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) {
263  err = Z_ERRNO;
264  break;
265  }
266  }
267  fclose(fpOutCD);
268  }
269  }
270 
271  /* Close */
272  fclose(fpZip);
273  fclose(fpOut);
274 
275  /* Wipe temporary file */
276  (void)remove(fileOutTmp);
277 
278  /* Number of recovered entries */
279  if (err == Z_OK) {
280  if (nRecovered != NULL) {
281  *nRecovered = entries;
282  }
283  if (bytesRecovered != NULL) {
284  *bytesRecovered = totalBytes;
285  }
286  }
287  } else {
289  }
290  return err;
291 }
static bool err
Definition: armass.c:435
RzList * entries(RzBinFile *bf)
Definition: bin_ne.c:98
#define NULL
Definition: cris-opc.c:27
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
const char * filename
Definition: ioapi.h:137
voidpf uLong offset
Definition: ioapi.h:144
void * malloc(size_t size)
Definition: malloc.c:123
#define header(is_bt, len_min, ret_op)
uLong filetime(char *f, tm_zip *tmzip, uLong *dt) const
Definition: minizip.c:141
#define READ_32(adr)
Definition: mztools.c:16
#define READ_16(adr)
Definition: mztools.c:15
#define WRITE_16(buff, n)
Definition: mztools.c:21
int ZEXPORT unzRepair(char *file, const char *fileOut, const char *fileOutTmp, uLong *nRecovered, uLong *bytesRecovered) const
Definition: mztools.c:30
#define WRITE_32(buff, n)
Definition: mztools.c:25
string FILE
Definition: benchmark.py:21
static int
Definition: sfsocketcall.h:114
Definition: buffer.h:15
Definition: gzappend.c:170
static int file
Definition: z80asm.c:58
unsigned long uLong
Definition: zconf.h:394
#define ZEXPORT
Definition: zconf.h:380
#define Z_ERRNO
Definition: zlib.h:180
#define Z_OK
Definition: zlib.h:177
#define Z_STREAM_ERROR
Definition: zlib.h:181
#define Z_MEM_ERROR
Definition: zlib.h:183