Rizin
unix-like reverse engineering framework and cli tools
in-memory.c
Go to the documentation of this file.
1 /*
2  in-memory.c -- modify zip file in memory
3  Copyright (C) 2014-2022 Dieter Baron and Thomas Klausner
4 
5  This file is part of libzip, a library to manipulate ZIP archives.
6  The authors can be contacted at <libzip@nih.at>
7 
8  Redistribution and use in source and binary forms, with or without
9  modification, are permitted provided that the following conditions
10  are met:
11  1. Redistributions of source code must retain the above copyright
12  notice, this list of conditions and the following disclaimer.
13  2. Redistributions in binary form must reproduce the above copyright
14  notice, this list of conditions and the following disclaimer in
15  the documentation and/or other materials provided with the
16  distribution.
17  3. The names of the authors may not be used to endorse or promote
18  products derived from this software without specific prior
19  written permission.
20 
21  THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
22  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
25  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
29  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
31  IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33 
34 #include <errno.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <sys/stat.h>
39 
40 #include <zip.h>
41 
42 static int
43 get_data(void **datap, size_t *sizep, const char *archive) {
44  /* example implementation that reads data from file */
45  struct stat st;
46  FILE *fp;
47 
48  if ((fp = fopen(archive, "rb")) == NULL) {
49  if (errno != ENOENT) {
50  fprintf(stderr, "can't open %s: %s\n", archive, strerror(errno));
51  return -1;
52  }
53 
54  *datap = NULL;
55  *sizep = 0;
56 
57  return 0;
58  }
59 
60  if (fstat(fileno(fp), &st) < 0) {
61  fprintf(stderr, "can't stat %s: %s\n", archive, strerror(errno));
62  fclose(fp);
63  return -1;
64  }
65 
66  if ((*datap = malloc((size_t)st.st_size)) == NULL) {
67  fprintf(stderr, "can't allocate buffer\n");
68  fclose(fp);
69  return -1;
70  }
71 
72  if (fread(*datap, 1, (size_t)st.st_size, fp) < (size_t)st.st_size) {
73  fprintf(stderr, "can't read %s: %s\n", archive, strerror(errno));
74  free(*datap);
75  fclose(fp);
76  return -1;
77  }
78 
79  fclose(fp);
80 
81  *sizep = (size_t)st.st_size;
82  return 0;
83 }
84 
85 static int
87  /* modify the archive */
88  return 0;
89 }
90 
91 
92 static int
93 use_data(void *data, size_t size, const char *archive) {
94  /* example implementation that writes data to file */
95  FILE *fp;
96 
97  if (data == NULL) {
98  if (remove(archive) < 0 && errno != ENOENT) {
99  fprintf(stderr, "can't remove %s: %s\n", archive, strerror(errno));
100  return -1;
101  }
102  return 0;
103  }
104 
105  if ((fp = fopen(archive, "wb")) == NULL) {
106  fprintf(stderr, "can't open %s: %s\n", archive, strerror(errno));
107  return -1;
108  }
109  if (fwrite(data, 1, size, fp) < size) {
110  fprintf(stderr, "can't write %s: %s\n", archive, strerror(errno));
111  fclose(fp);
112  return -1;
113  }
114  if (fclose(fp) < 0) {
115  fprintf(stderr, "can't write %s: %s\n", archive, strerror(errno));
116  return -1;
117  }
118 
119  return 0;
120 }
121 
122 
123 int
124 main(int argc, char *argv[]) {
125  const char *archive;
126  zip_source_t *src;
127  zip_t *za;
129  void *data;
130  size_t size;
131 
132  if (argc < 2) {
133  fprintf(stderr, "usage: %s archive\n", argv[0]);
134  return 1;
135  }
136  archive = argv[1];
137 
138  /* get buffer with zip archive inside */
139  if (get_data(&data, &size, archive) < 0) {
140  return 1;
141  }
142 
144  /* create source from buffer */
145  if ((src = zip_source_buffer_create(data, size, 1, &error)) == NULL) {
146  fprintf(stderr, "can't create source: %s\n", zip_error_strerror(&error));
147  free(data);
149  return 1;
150  }
151 
152  /* open zip archive from source */
153  if ((za = zip_open_from_source(src, 0, &error)) == NULL) {
154  fprintf(stderr, "can't open zip from source: %s\n", zip_error_strerror(&error));
157  return 1;
158  }
160 
161  /* we'll want to read the data back after zip_close */
163 
164  /* modify archive */
166 
167  /* close archive */
168  if (zip_close(za) < 0) {
169  fprintf(stderr, "can't close zip archive '%s': %s\n", archive, zip_strerror(za));
170  return 1;
171  }
172 
173 
174  /* copy new archive to buffer */
175 
176  if (zip_source_is_deleted(src)) {
177  /* new archive is empty, thus no data */
178  data = NULL;
179  }
180  else {
181  zip_stat_t zst;
182 
183  if (zip_source_stat(src, &zst) < 0) {
184  fprintf(stderr, "can't stat source: %s\n", zip_error_strerror(zip_source_error(src)));
185  return 1;
186  }
187 
188  size = zst.size;
189 
190  if (zip_source_open(src) < 0) {
191  fprintf(stderr, "can't open source: %s\n", zip_error_strerror(zip_source_error(src)));
192  return 1;
193  }
194  if ((data = malloc(size)) == NULL) {
195  fprintf(stderr, "malloc failed: %s\n", strerror(errno));
197  return 1;
198  }
199  if ((zip_uint64_t)zip_source_read(src, data, size) < size) {
200  fprintf(stderr, "can't read data from source: %s\n", zip_error_strerror(zip_source_error(src)));
202  free(data);
203  return 1;
204  }
206  }
207 
208  /* we're done with src */
210 
211  /* use new data */
212  use_data(data, size, archive);
213 
214  free(data);
215 
216  return 0;
217 }
lzma_index * src
Definition: index.h:567
#define NULL
Definition: cris-opc.c:27
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset fstat
Definition: sflib.h:107
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
int main(int argc, char *argv[])
Definition: in-memory.c:124
static int get_data(void **datap, size_t *sizep, const char *archive)
Definition: in-memory.c:43
static int modify_archive(zip_t *za)
Definition: in-memory.c:86
static int use_data(void *data, size_t size, const char *archive)
Definition: in-memory.c:93
voidpf void uLong size
Definition: ioapi.h:138
ZIP_EXTERN int zip_source_close(zip_source_t *_Nonnull)
ZIP_EXTERN int zip_source_is_deleted(zip_source_t *_Nonnull)
ZIP_EXTERN zip_t *_Nullable zip_open_from_source(zip_source_t *_Nonnull, int, zip_error_t *_Nullable)
Definition: zip_open.c:79
ZIP_EXTERN zip_int64_t zip_source_read(zip_source_t *_Nonnull, void *_Nonnull, zip_uint64_t)
ZIP_EXTERN zip_source_t *_Nullable zip_source_buffer_create(const void *_Nullable, zip_uint64_t, int, zip_error_t *_Nullable)
ZIP_EXTERN void zip_error_init(zip_error_t *_Nonnull)
Definition: zip_error.c:59
ZIP_EXTERN zip_error_t *_Nonnull zip_source_error(zip_source_t *_Nonnull)
ZIP_EXTERN int zip_source_stat(zip_source_t *_Nonnull, zip_stat_t *_Nonnull)
ZIP_EXTERN int zip_close(zip_t *_Nonnull)
Definition: zip_close.c:52
ZIP_EXTERN int zip_source_open(zip_source_t *_Nonnull)
ZIP_EXTERN void zip_error_fini(zip_error_t *_Nonnull)
Definition: zip_error.c:52
ZIP_EXTERN void zip_source_free(zip_source_t *_Nullable)
ZIP_EXTERN const char *_Nonnull zip_error_strerror(zip_error_t *_Nonnull)
ZIP_EXTERN void zip_source_keep(zip_source_t *_Nonnull)
ZIP_EXTERN const char *_Nonnull zip_strerror(zip_t *_Nonnull)
Definition: zip_strerror.c:39
void * malloc(size_t size)
Definition: malloc.c:123
static static fork const void static count static fd const char const char static newpath char char argv
Definition: sflib.h:40
string FILE
Definition: benchmark.py:21
#define ENOENT
Definition: sftypes.h:112
int size_t
Definition: sftypes.h:40
Definition: zipcmp.c:60
Definition: sftypes.h:80
Definition: zip.h:284
Definition: zip.h:300
zip_uint64_t size
Definition: zip.h:304
Definition: zipint.h:278
void error(const char *msg)
Definition: untgz.c:593
uint64_t zip_uint64_t
Definition: zipconf.h:39
zip_t * za
Definition: ziptool.c:79