Rizin
unix-like reverse engineering framework and cli tools
oabd.c File Reference
#include <system.h>
#include <oab.h>
#include <lzx.h>
#include <crc32.h>

Go to the source code of this file.

Classes

struct  oabd_file
 

Functions

static int oabd_decompress (struct msoab_decompressor *self, const char *input, const char *output)
 
static int oabd_decompress_incremental (struct msoab_decompressor *self, const char *input, const char *base, const char *output)
 
static int oabd_param (struct msoab_decompressor *base, int param, int value)
 
static int copy_fh (struct mspack_system *sys, struct mspack_file *infh, struct mspack_file *outfh, size_t bytes_to_copy, unsigned char *buf, int buf_size)
 
struct msoab_decompressormspack_create_oab_decompressor (struct mspack_system *sys)
 
void mspack_destroy_oab_decompressor (struct msoab_decompressor *base)
 
static int oabd_sys_read (struct mspack_file *base_file, void *buf, int size)
 
static int oabd_sys_write (struct mspack_file *base_file, void *buf, int size)
 

Function Documentation

◆ copy_fh()

static int copy_fh ( struct mspack_system sys,
struct mspack_file infh,
struct mspack_file outfh,
size_t  bytes_to_copy,
unsigned char *  buf,
int  buf_size 
)
static

Definition at line 375 of file oabd.c.

378 {
379  while (bytes_to_copy) {
380  int run = buf_size;
381  if ((size_t) run > bytes_to_copy) {
382  run = (int) bytes_to_copy;
383  }
384  if (sys->read(infh, buf, run) != run) {
385  return MSPACK_ERR_READ;
386  }
387  if (outfh && sys->write(outfh, buf, run) != run) {
388  return MSPACK_ERR_WRITE;
389  }
390  bytes_to_copy -= run;
391  }
392  return MSPACK_ERR_OK;
393 }
#define MSPACK_ERR_OK
Definition: mspack.h:485
#define MSPACK_ERR_WRITE
Definition: mspack.h:493
#define MSPACK_ERR_READ
Definition: mspack.h:491
static int buf_size
Definition: debug_qnx.c:35
voidpf void * buf
Definition: ioapi.h:138
static int run(int i, const char *arg)
Definition: rz-bb.c:19
static int
Definition: sfsocketcall.h:114
int(* read)(struct mspack_file *file, void *buffer, int bytes)
Definition: mspack.h:336
int(* write)(struct mspack_file *file, void *buffer, int bytes)
Definition: mspack.h:353

References buf_size, int, MSPACK_ERR_OK, MSPACK_ERR_READ, MSPACK_ERR_WRITE, mspack_system::read, run(), and mspack_system::write.

Referenced by oabd_decompress(), and oabd_decompress_incremental().

◆ mspack_create_oab_decompressor()

struct msoab_decompressor* mspack_create_oab_decompressor ( struct mspack_system sys)

Creates a new OAB decompressor.

Parameters
sysa custom mspack_system structure, or NULL to use the default
Returns
a msoab_decompressor or NULL

Definition at line 43 of file oabd.c.

44 {
45  struct msoab_decompressor_p *self = NULL;
46 
47  if (!sys) sys = mspack_default_system;
48  if (!mspack_valid_system(sys)) return NULL;
49 
50  if ((self = (struct msoab_decompressor_p *) sys->alloc(sys, sizeof(struct msoab_decompressor_p)))) {
51  self->base.decompress = &oabd_decompress;
52  self->base.decompress_incremental = &oabd_decompress_incremental;
53  self->base.set_param = &oabd_param;
54  self->system = sys;
55  self->buf_size = 4096;
56  }
57  return (struct msoab_decompressor *) self;
58 }
struct mspack_system * mspack_default_system
Definition: system.c:238
int mspack_valid_system(struct mspack_system *sys)
Definition: system.c:58
#define NULL
Definition: cris-opc.c:27
static int oabd_decompress_incremental(struct msoab_decompressor *self, const char *input, const char *base, const char *output)
Definition: oabd.c:234
static int oabd_decompress(struct msoab_decompressor *self, const char *input, const char *output)
Definition: oabd.c:103
static int oabd_param(struct msoab_decompressor *base, int param, int value)
Definition: oabd.c:395
void *(* alloc)(struct mspack_system *self, size_t bytes)
Definition: mspack.h:421

References mspack_system::alloc, mspack_default_system, mspack_valid_system(), NULL, oabd_decompress(), oabd_decompress_incremental(), and oabd_param().

Referenced by main().

◆ mspack_destroy_oab_decompressor()

void mspack_destroy_oab_decompressor ( struct msoab_decompressor self)

Destroys an existing OAB decompressor.

Parameters
selfthe msoab_decompressor to destroy

Definition at line 60 of file oabd.c.

60  {
61  struct msoab_decompressor_p *self = (struct msoab_decompressor_p *)base;
62  if (self) {
63  struct mspack_system *sys = self->system;
64  sys->free(self);
65  }
66 }
struct msoab_decompressor base
Definition: oab.h:28
void(* free)(void *ptr)
Definition: mspack.h:430

References msoab_decompressor_p::base, and mspack_system::free.

Referenced by main().

◆ oabd_decompress()

static int oabd_decompress ( struct msoab_decompressor self,
const char *  input,
const char *  output 
)
static

Definition at line 103 of file oabd.c.

105 {
106  struct msoab_decompressor_p *self = (struct msoab_decompressor_p *) _self;
107  struct mspack_system *sys;
108  struct mspack_file *infh = NULL;
109  struct mspack_file *outfh = NULL;
110  unsigned char *buf = NULL;
111  unsigned char hdrbuf[oabhead_SIZEOF];
112  unsigned int block_max, target_size;
113  struct lzxd_stream *lzx = NULL;
114  struct mspack_system oabd_sys;
115  struct oabd_file in_ofh, out_ofh;
116  unsigned int window_bits;
117  int ret = MSPACK_ERR_OK;
118 
119  if (!self) return MSPACK_ERR_ARGS;
120  sys = self->system;
121 
122  infh = sys->open(sys, input, MSPACK_SYS_OPEN_READ);
123  if (!infh) {
124  ret = MSPACK_ERR_OPEN;
125  goto out;
126  }
127 
128  if (sys->read(infh, hdrbuf, oabhead_SIZEOF) != oabhead_SIZEOF) {
129  ret = MSPACK_ERR_READ;
130  goto out;
131  }
132 
133  if (EndGetI32(&hdrbuf[oabhead_VersionHi]) != 3 ||
134  EndGetI32(&hdrbuf[oabhead_VersionLo]) != 1) {
135  ret = MSPACK_ERR_SIGNATURE;
136  goto out;
137  }
138 
139  block_max = EndGetI32(&hdrbuf[oabhead_BlockMax]);
140  target_size = EndGetI32(&hdrbuf[oabhead_TargetSize]);
141 
142  outfh = sys->open(sys, output, MSPACK_SYS_OPEN_WRITE);
143  if (!outfh) {
144  ret = MSPACK_ERR_OPEN;
145  goto out;
146  }
147 
148  buf = sys->alloc(sys, self->buf_size);
149  if (!buf) {
150  ret = MSPACK_ERR_NOMEMORY;
151  goto out;
152  }
153 
154  oabd_sys = *sys;
155  oabd_sys.read = oabd_sys_read;
156  oabd_sys.write = oabd_sys_write;
157 
158  in_ofh.orig_sys = sys;
159  in_ofh.orig_file = infh;
160 
161  out_ofh.orig_sys = sys;
162  out_ofh.orig_file = outfh;
163 
164  while (target_size) {
165  unsigned int blk_csize, blk_dsize, blk_crc, blk_flags;
166 
167  if (sys->read(infh, buf, oabblk_SIZEOF) != oabblk_SIZEOF) {
168  ret = MSPACK_ERR_READ;
169  goto out;
170  }
171  blk_flags = EndGetI32(&buf[oabblk_Flags]);
172  blk_csize = EndGetI32(&buf[oabblk_CompSize]);
173  blk_dsize = EndGetI32(&buf[oabblk_UncompSize]);
174  blk_crc = EndGetI32(&buf[oabblk_CRC]);
175 
176  if (blk_dsize > block_max || blk_dsize > target_size || blk_flags > 1) {
177  ret = MSPACK_ERR_DATAFORMAT;
178  goto out;
179  }
180 
181  if (!blk_flags) {
182  /* Uncompressed block */
183  if (blk_dsize != blk_csize) {
184  ret = MSPACK_ERR_DATAFORMAT;
185  goto out;
186  }
187  ret = copy_fh(sys, infh, outfh, blk_dsize, buf, self->buf_size);
188  if (ret) goto out;
189  } else {
190  /* LZX compressed block */
191  window_bits = 17;
192 
193  while (window_bits < 25 && (1U << window_bits) < blk_dsize)
194  window_bits++;
195 
196  in_ofh.available = blk_csize;
197  out_ofh.crc = 0xffffffff;
198 
199  lzx = lzxd_init(&oabd_sys, (void *)&in_ofh, (void *)&out_ofh, window_bits,
200  0, self->buf_size, blk_dsize, 1);
201  if (!lzx) {
202  ret = MSPACK_ERR_NOMEMORY;
203  goto out;
204  }
205 
206  ret = lzxd_decompress(lzx, blk_dsize);
207  if (ret != MSPACK_ERR_OK)
208  goto out;
209 
210  lzxd_free(lzx);
211  lzx = NULL;
212 
213  /* Consume any trailing padding bytes before the next block */
214  ret = copy_fh(sys, infh, NULL, in_ofh.available, buf, self->buf_size);
215  if (ret) goto out;
216 
217  if (out_ofh.crc != blk_crc) {
218  ret = MSPACK_ERR_CHECKSUM;
219  goto out;
220  }
221  }
222  target_size -= blk_dsize;
223  }
224 
225  out:
226  if (lzx) lzxd_free(lzx);
227  if (outfh) sys->close(outfh);
228  if (infh) sys->close(infh);
229  sys->free(buf);
230 
231  return ret;
232 }
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
struct lzxd_stream * lzxd_init(struct mspack_system *system, struct mspack_file *input, struct mspack_file *output, int window_bits, int reset_interval, int input_buffer_size, off_t output_length, char is_delta)
Definition: lzxd.c:279
void lzxd_free(struct lzxd_stream *lzx)
Definition: lzxd.c:800
int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes)
Definition: lzxd.c:393
#define MSPACK_ERR_OPEN
Definition: mspack.h:489
#define MSPACK_SYS_OPEN_WRITE
Definition: mspack.h:460
#define MSPACK_SYS_OPEN_READ
Definition: mspack.h:458
#define MSPACK_ERR_CHECKSUM
Definition: mspack.h:503
#define MSPACK_ERR_SIGNATURE
Definition: mspack.h:499
#define MSPACK_ERR_ARGS
Definition: mspack.h:487
#define MSPACK_ERR_DATAFORMAT
Definition: mspack.h:501
#define MSPACK_ERR_NOMEMORY
Definition: mspack.h:497
#define EndGetI32(a)
Definition: macros.h:37
#define oabhead_TargetSize
Definition: oab.h:37
#define oabhead_VersionHi
Definition: oab.h:34
#define oabhead_VersionLo
Definition: oab.h:35
#define oabhead_BlockMax
Definition: oab.h:36
#define oabblk_CRC
Definition: oab.h:43
#define oabblk_SIZEOF
Definition: oab.h:44
#define oabhead_SIZEOF
Definition: oab.h:38
#define oabblk_Flags
Definition: oab.h:40
#define oabblk_CompSize
Definition: oab.h:41
#define oabblk_UncompSize
Definition: oab.h:42
static int oabd_sys_write(struct mspack_file *base_file, void *buf, int size)
Definition: oabd.c:92
static int oabd_sys_read(struct mspack_file *base_file, void *buf, int size)
Definition: oabd.c:76
static int copy_fh(struct mspack_system *sys, struct mspack_file *infh, struct mspack_file *outfh, size_t bytes_to_copy, unsigned char *buf, int buf_size)
Definition: oabd.c:375
void(* close)(struct mspack_file *file)
Definition: mspack.h:321
struct mspack_file *(* open)(struct mspack_system *self, const char *filename, int mode)
Definition: mspack.h:310
Definition: oabd.c:68
static bool input(void *ud, zip_uint8_t *data, zip_uint64_t length)
diff_output_t output
Definition: zipcmp.c:237

References mspack_system::alloc, oabd_file::available, mspack_system::close, copy_fh(), oabd_file::crc, EndGetI32, mspack_system::free, input(), lzxd_decompress(), lzxd_free(), lzxd_init(), MSPACK_ERR_ARGS, MSPACK_ERR_CHECKSUM, MSPACK_ERR_DATAFORMAT, MSPACK_ERR_NOMEMORY, MSPACK_ERR_OK, MSPACK_ERR_OPEN, MSPACK_ERR_READ, MSPACK_ERR_SIGNATURE, MSPACK_SYS_OPEN_READ, MSPACK_SYS_OPEN_WRITE, NULL, oabblk_CompSize, oabblk_CRC, oabblk_Flags, oabblk_SIZEOF, oabblk_UncompSize, oabd_sys_read(), oabd_sys_write(), oabhead_BlockMax, oabhead_SIZEOF, oabhead_TargetSize, oabhead_VersionHi, oabhead_VersionLo, mspack_system::open, oabd_file::orig_file, oabd_file::orig_sys, out, output, mspack_system::read, and mspack_system::write.

Referenced by mspack_create_oab_decompressor().

◆ oabd_decompress_incremental()

static int oabd_decompress_incremental ( struct msoab_decompressor self,
const char *  input,
const char *  base,
const char *  output 
)
static

Definition at line 234 of file oabd.c.

237 {
238  struct msoab_decompressor_p *self = (struct msoab_decompressor_p *) _self;
239  struct mspack_system *sys;
240  struct mspack_file *infh = NULL;
241  struct mspack_file *basefh = NULL;
242  struct mspack_file *outfh = NULL;
243  unsigned char *buf = NULL;
244  unsigned char hdrbuf[patchhead_SIZEOF];
245  unsigned int block_max, target_size;
246  struct lzxd_stream *lzx = NULL;
247  struct mspack_system oabd_sys;
248  struct oabd_file in_ofh, out_ofh;
249  unsigned int window_bits, window_size;
250  int ret = MSPACK_ERR_OK;
251 
252  if (!self) return MSPACK_ERR_ARGS;
253  sys = self->system;
254 
255  infh = sys->open(sys, input, MSPACK_SYS_OPEN_READ);
256  if (!infh) {
257  ret = MSPACK_ERR_OPEN;
258  goto out;
259  }
260 
261  if (sys->read(infh, hdrbuf, patchhead_SIZEOF) != patchhead_SIZEOF) {
262  ret = MSPACK_ERR_READ;
263  goto out;
264  }
265 
266  if (EndGetI32(&hdrbuf[patchhead_VersionHi]) != 3 ||
267  EndGetI32(&hdrbuf[patchhead_VersionLo]) != 2) {
268  ret = MSPACK_ERR_SIGNATURE;
269  goto out;
270  }
271 
272  block_max = EndGetI32(&hdrbuf[patchhead_BlockMax]);
273  target_size = EndGetI32(&hdrbuf[patchhead_TargetSize]);
274 
275  /* We use it for reading block headers too */
276  if (block_max < patchblk_SIZEOF)
277  block_max = patchblk_SIZEOF;
278 
279  basefh = sys->open(sys, base, MSPACK_SYS_OPEN_READ);
280  if (!basefh) {
281  ret = MSPACK_ERR_OPEN;
282  goto out;
283  }
284 
285  outfh = sys->open(sys, output, MSPACK_SYS_OPEN_WRITE);
286  if (!outfh) {
287  ret = MSPACK_ERR_OPEN;
288  goto out;
289  }
290 
291  buf = sys->alloc(sys, self->buf_size);
292  if (!buf) {
293  ret = MSPACK_ERR_NOMEMORY;
294  goto out;
295  }
296 
297  oabd_sys = *sys;
298  oabd_sys.read = oabd_sys_read;
299  oabd_sys.write = oabd_sys_write;
300 
301  in_ofh.orig_sys = sys;
302  in_ofh.orig_file = infh;
303 
304  out_ofh.orig_sys = sys;
305  out_ofh.orig_file = outfh;
306 
307  while (target_size) {
308  unsigned int blk_csize, blk_dsize, blk_ssize, blk_crc;
309 
310  if (sys->read(infh, buf, patchblk_SIZEOF) != patchblk_SIZEOF) {
311  ret = MSPACK_ERR_READ;
312  goto out;
313  }
314  blk_csize = EndGetI32(&buf[patchblk_PatchSize]);
315  blk_dsize = EndGetI32(&buf[patchblk_TargetSize]);
316  blk_ssize = EndGetI32(&buf[patchblk_SourceSize]);
317  blk_crc = EndGetI32(&buf[patchblk_CRC]);
318 
319  if (blk_dsize > block_max || blk_dsize > target_size ||
320  blk_ssize > block_max) {
321  ret = MSPACK_ERR_DATAFORMAT;
322  goto out;
323  }
324 
325 
326  window_size = (blk_ssize + 32767) & ~32767;
327  window_size += blk_dsize;
328  window_bits = 17;
329 
330  while (window_bits < 25 && (1U << window_bits) < window_size)
331  window_bits++;
332 
333  in_ofh.available = blk_csize;
334  out_ofh.crc = 0xffffffff;
335 
336  lzx = lzxd_init(&oabd_sys, (void *)&in_ofh, (void *)&out_ofh, window_bits,
337  0, 4096, blk_dsize, 1);
338  if (!lzx) {
339  ret = MSPACK_ERR_NOMEMORY;
340  goto out;
341  }
342  ret = lzxd_set_reference_data(lzx, sys, basefh, blk_ssize);
343  if (ret != MSPACK_ERR_OK)
344  goto out;
345 
346  ret = lzxd_decompress(lzx, blk_dsize);
347  if (ret != MSPACK_ERR_OK)
348  goto out;
349 
350  lzxd_free(lzx);
351  lzx = NULL;
352 
353  /* Consume any trailing padding bytes before the next block */
354  ret = copy_fh(sys, infh, NULL, in_ofh.available, buf, self->buf_size);
355  if (ret) goto out;
356 
357  if (out_ofh.crc != blk_crc) {
358  ret = MSPACK_ERR_CHECKSUM;
359  goto out;
360  }
361 
362  target_size -= blk_dsize;
363  }
364 
365  out:
366  if (lzx) lzxd_free(lzx);
367  if (outfh) sys->close(outfh);
368  if (basefh) sys->close(basefh);
369  if (infh) sys->close(infh);
370  sys->free(buf);
371 
372  return ret;
373 }
int lzxd_set_reference_data(struct lzxd_stream *lzx, struct mspack_system *system, struct mspack_file *input, unsigned int length)
Definition: lzxd.c:353
#define patchhead_VersionHi
Definition: oab.h:46
#define patchblk_CRC
Definition: oab.h:58
#define patchblk_SIZEOF
Definition: oab.h:59
#define patchhead_TargetSize
Definition: oab.h:50
#define patchblk_SourceSize
Definition: oab.h:57
#define patchblk_PatchSize
Definition: oab.h:55
#define patchhead_SIZEOF
Definition: oab.h:53
#define patchblk_TargetSize
Definition: oab.h:56
#define patchhead_BlockMax
Definition: oab.h:48
#define patchhead_VersionLo
Definition: oab.h:47

References mspack_system::alloc, oabd_file::available, mspack_system::close, copy_fh(), oabd_file::crc, EndGetI32, mspack_system::free, input(), lzxd_decompress(), lzxd_free(), lzxd_init(), lzxd_set_reference_data(), MSPACK_ERR_ARGS, MSPACK_ERR_CHECKSUM, MSPACK_ERR_DATAFORMAT, MSPACK_ERR_NOMEMORY, MSPACK_ERR_OK, MSPACK_ERR_OPEN, MSPACK_ERR_READ, MSPACK_ERR_SIGNATURE, MSPACK_SYS_OPEN_READ, MSPACK_SYS_OPEN_WRITE, NULL, oabd_sys_read(), oabd_sys_write(), mspack_system::open, oabd_file::orig_file, oabd_file::orig_sys, out, output, patchblk_CRC, patchblk_PatchSize, patchblk_SIZEOF, patchblk_SourceSize, patchblk_TargetSize, patchhead_BlockMax, patchhead_SIZEOF, patchhead_TargetSize, patchhead_VersionHi, patchhead_VersionLo, mspack_system::read, and mspack_system::write.

Referenced by mspack_create_oab_decompressor().

◆ oabd_param()

static int oabd_param ( struct msoab_decompressor base,
int  param,
int  value 
)
static

Definition at line 395 of file oabd.c.

395  {
396  struct msoab_decompressor_p *self = (struct msoab_decompressor_p *) base;
397  if (self && param == MSOABD_PARAM_DECOMPBUF && value >= 16) {
398  /* must be at least 16 bytes (patchblk_SIZEOF, oabblk_SIZEOF) */
399  self->buf_size = value;
400  return MSPACK_ERR_OK;
401  }
402  return MSPACK_ERR_ARGS;
403 }
#define MSOABD_PARAM_DECOMPBUF
Definition: mspack.h:2379
static int value
Definition: cmd_api.c:93

References msoab_decompressor_p::base, MSOABD_PARAM_DECOMPBUF, MSPACK_ERR_ARGS, MSPACK_ERR_OK, and value.

Referenced by mspack_create_oab_decompressor().

◆ oabd_sys_read()

static int oabd_sys_read ( struct mspack_file base_file,
void *  buf,
int  size 
)
static

Definition at line 76 of file oabd.c.

77 {
78  struct oabd_file *file = (struct oabd_file *)base_file;
79  int bytes_read;
80 
81  if ((size_t)size > file->available)
82  size = file->available;
83 
84  bytes_read = file->orig_sys->read(file->orig_file, buf, size);
85  if (bytes_read < 0)
86  return bytes_read;
87 
88  file->available -= bytes_read;
89  return bytes_read;
90 }
voidpf void uLong size
Definition: ioapi.h:138
Definition: gzappend.c:170

Referenced by oabd_decompress(), and oabd_decompress_incremental().

◆ oabd_sys_write()

static int oabd_sys_write ( struct mspack_file base_file,
void *  buf,
int  size 
)
static

Definition at line 92 of file oabd.c.

93 {
94  struct oabd_file *file = (struct oabd_file *)base_file;
95  int bytes_written = file->orig_sys->write(file->orig_file, buf, size);
96 
97  if (bytes_written > 0)
98  file->crc = crc32(file->crc, buf, bytes_written);
99 
100  return bytes_written;
101 }
unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, uInt len)
Definition: crc32.c:1063

References crc32().

Referenced by oabd_decompress(), and oabd_decompress_incremental().