35 const unsigned char **result,
const unsigned char **result_end);
37 const char *
s1,
const char *
s2,
int l1,
int l2);
66 static const char *
content_name =
"::DataSpace/Storage/MSCompressed/Content";
67 static const char *
control_name =
"::DataSpace/Storage/MSCompressed/ControlData";
68 static const char *
spaninfo_name =
"::DataSpace/Storage/MSCompressed/SpanInfo";
69 static const char *
rtable_name =
"::DataSpace/Storage/MSCompressed/Transform/"
70 "{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}/InstanceData/ResetTable";
109 if (self->d->infh) sys->
close(self->d->infh);
110 if (self->d->state)
lzxd_free(self->d->state);
157 if (!base)
return NULL;
168 sys->
message(
fh,
"WARNING; contents are corrupt");
208 for (fi = chm->
files; fi; fi = nfi) {
212 for (fi = chm->
sysfiles; fi; fi = nfi) {
218 if (self->d && (self->d->chm == chm)) {
219 if (self->d->infh) sys->
close(self->d->infh);
220 if (self->d->state)
lzxd_free(self->d->state);
243 static const unsigned char guids[32] = {
245 0x10, 0xFD, 0x01, 0x7C, 0xAA, 0x7B, 0xD0, 0x11,
246 0x9E, 0x0C, 0x00, 0xA0, 0xC9, 0x22, 0xE6, 0xEC,
248 0x11, 0xFD, 0x01, 0x7C, 0xAA, 0x7B, 0xD0, 0x11,
249 0x9E, 0x0C, 0x00, 0xA0, 0xC9, 0x22, 0xE6, 0xEC
254 #define READ_ENCINT(var) do { \
257 if (p >= end) goto chunk_end; \
258 (var) = ((var) << 7) | (*p & 0x7F); \
259 } while (*p++ & 0x80); \
265 unsigned int section, name_len,
x, errors, num_chunks;
296 D((
"incorrect GUIDs"))
304 sys->
message(
fh,
"WARNING; CHM version > 3");
361 D((
"content section begins after file has ended"))
368 D((
"chunk size not large enough"))
381 D((
"more than 100,000 chunks"))
385 D((
"chunk size over 8192 (get in touch if this is valid)"))
389 D((
"chunks larger than entire file"))
395 sys->
message(
fh,
"WARNING; chunk size is not 4096");
398 sys->
message(
fh,
"WARNING; first PMGL chunk is not zero");
401 D((
"first pmgl chunk is after last pmgl chunk"))
405 D((
"index_root outside valid range"))
428 while (num_chunks--) {
439 sys->
message(
fh,
"WARNING; PMGL quickref area is too small");
444 sys->
message(
fh,
"WARNING; PMGL quickref area is too large");
451 while (num_entries--) {
453 if (name_len > (
unsigned int) (
end -
p))
goto chunk_end;
460 if (name_len < 2 || !
name[0] || !
name[1])
continue;
466 if ((name_len > 0) && (
name[name_len-1] ==
'/'))
continue;
488 if (
name[0] ==
':' &&
name[1] ==
':') {
515 if (num_entries >= 0) {
516 D((
"chunk ended before all entries could be read"))
548 if (!
self || !chm || !f_ptr || (f_size !=
sizeof(
struct mschmd_file))) {
608 else if (result < 0) {
613 return self->error =
err;
616 D((
"read beyond end of chunk entries"))
627 unsigned int chunk_num)
669 if (!((
buf[0] == 0x50) && (
buf[1] == 0x4D) && (
buf[2] == 0x47) &&
670 ((
buf[3] == 0x4C) || (
buf[3] == 0x49))))
692 const unsigned char *
chunk,
694 const unsigned char **result,
695 const unsigned char **result_end)
698 unsigned int qr_size, num_entries, qr_entries, qr_density, name_len;
699 unsigned int L,
R,
M, fname_len, entries_off, is_pmgl;
706 if (
chunk[3] == 0x4C) {
729 qr_density = 1 + (1 << chm->
density);
730 qr_entries = (num_entries + qr_density-1) / qr_density;
732 if (num_entries == 0) {
733 D((
"chunk has no entries"))
738 D((
"quickref size > chunk size"))
744 if (((
int)qr_entries * 2) > (
start -
end)) {
745 D((
"WARNING; more quickrefs than quickref space"))
749 if (qr_entries > 0) {
759 if (name_len > (
unsigned int) (
end -
p))
goto chunk_end;
763 else if (
cmp < 0) {
if (
M)
R =
M - 1;
else return 0; }
764 else if (
cmp > 0)
L =
M + 1;
777 num_entries -= (
M * qr_density);
778 if (num_entries > qr_density) num_entries = qr_density;
794 while (num_entries-- > 0) {
796 if (name_len > (
unsigned int) (
end -
p))
goto chunk_end;
824 return (is_pmgl) ? 0 : (*result ? 1 : 0);
827 D((
"reached end of chunk data while searching"))
833 # define TOLOWER(x) towlower(x)
836 # define TOLOWER(x) tolower(x)
843 #define GET_UTF8_CHAR(s, e, c) do { \
844 unsigned char x = *s++; \
845 if (x < 0x80) c = x; \
846 else if (x >= 0xC2 && x < 0xE0 && s < e) { \
847 c = (x & 0x1F) << 6 | (*s++ & 0x3F); \
849 else if (x >= 0xE0 && x < 0xF0 && s+1 < e) { \
850 c = (x & 0x0F) << 12 | (s[0] & 0x3F) << 6 | (s[1] & 0x3F); \
853 else if (x >= 0xF0 && x <= 0xF5 && s+2 < e) { \
854 c = (x & 0x07) << 18 | (s[0] & 0x3F) << 12 | \
855 (s[1] & 0x3F) << 6 | (s[2] & 0x3F); \
856 if (c > 0x10FFFF) c = 0xFFFD; \
864 static inline int compare(
const char *
s1,
const char *
s2,
int l1,
int l2) {
865 register const unsigned char *p1 = (
const unsigned char *)
s1;
866 register const unsigned char *p2 = (
const unsigned char *)
s2;
867 register const unsigned char *e1 = p1 + l1, *e2 = p2 + l2;
870 while (p1 < e1 && p2 < e2) {
873 if (
c1 ==
c2)
continue;
899 chm =
file->section->chm;
907 self->d->state =
NULL;
910 self->d->infh =
NULL;
911 self->d->outfh =
NULL;
915 if (!self->d->infh || (self->d->chm !=
chm)) {
916 if (self->d->infh)
sys->
close(self->d->infh);
917 if (self->d->state)
lzxd_free(self->d->state);
920 self->d->state =
NULL;
938 switch (
file->section->id) {
941 if (
sys->
seek(self->d->infh,
file->section->chm->sec0.offset
947 unsigned char buf[512];
969 if (!self->d->state || (
file->offset < self->d->offset)) {
970 if (self->d->state) {
972 self->d->state =
NULL;
984 self->d->outfh =
NULL;
985 if ((
bytes =
file->offset - self->d->offset)) {
997 self->d->inoffset =
sys->
tell(self->d->infh);
1001 if (self->d->state)
lzxd_free(self->d->state);
1002 self->d->state =
NULL;
1021 self->d->offset +=
bytes;
1022 if (self->d->outfh) {
1023 return self->system->write(self->d->outfh,
buffer,
bytes);
1038 int window_size = 0, window_bits = 0, reset_interval = 0,
entry = 0,
err = 0;
1041 unsigned char *data =
NULL;
1048 if (
err)
return self->error =
err;
1052 if (
err)
return self->error =
err;
1056 D((
"ControlData file is wrong size"))
1060 D((
"can't read mscompressed control data file"))
1081 D((
"bad controldata version"))
1090 switch (window_size) {
1091 case 0x008000: window_bits = 15;
break;
1092 case 0x010000: window_bits = 16;
break;
1093 case 0x020000: window_bits = 17;
break;
1094 case 0x040000: window_bits = 18;
break;
1095 case 0x080000: window_bits = 19;
break;
1096 case 0x100000: window_bits = 20;
break;
1097 case 0x200000: window_bits = 21;
break;
1099 D((
"bad controldata window size"))
1105 D((
"bad controldata reset interval"))
1119 length += reset_interval - 1;
1120 length &= -reset_interval;
1129 if (
err)
return self->error =
err;
1139 length -=
self->d->offset;
1142 self->d->state =
lzxd_init(&self->d->sys, self->d->infh,
1163 unsigned char *data;
1164 unsigned int pos, entrysize;
1172 D((
"ResetTable file is too short"))
1176 D((
"ResetTable >1MB (%"LD"), report if genuine", sec->
rtable->
length))
1181 D((
"can't read reset table"))
1187 D((
"bad reset table frame length"))
1205 switch (entrysize) {
1214 D((
"reset table entry size neither 4 nor 8"))
1220 D((
"bad reset interval"))
1242 unsigned char *data;
1250 D((
"SpanInfo file is wrong size"))
1256 D((
"can't read SpanInfo file"))
1265 if (*length_ptr <= 0) {
1266 D((
"output length is invalid"))
1293 name, &result, (
int)
sizeof(result)) || !result.
section)
1322 unsigned char *data =
NULL;
1325 if (!
file || !
file->section || (
file->section->id != 0)) {
1332 if (!(data = (
unsigned char *) sys->
alloc(sys, (
size_t)
len))) {
1336 if (sys->
seek(self->d->infh,
file->section->chm->sec0.offset
1343 if (sys->
read(self->d->infh, data,
len) !=
len) {
1372 #if SIZEOF_OFF_T >= 8
1377 sys->
message(
fh,
"library not compiled to support large files.");
static RzILOpEffect * cmp(cs_insn *insn, bool is_thumb)
lsl lsr asr ror lsl lsr asr ror lsl lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror c1
lsl lsr asr ror lsl lsr asr ror lsl lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror c2
#define chmhst3_OffsetCS0
#define chmhead_LanguageID
#define chmhead_Timestamp
#define lzxcd_ResetInterval
#define pmgl_QuickRefSize
#define lzxrt_headerSIZEOF
#define chmhead_Signature
#define lzxrt_TableOffset
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 struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void start
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 struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
static static fork const void static count static fd link
return memset(p, 0, total)
static int compare(const char *s1, const char *s2, int l1, int l2)
static const char * control_name
static int chmd_extract(struct mschm_decompressor *base, struct mschmd_file *file, const char *filename)
static unsigned char * read_sys_file(struct mschm_decompressor_p *self, struct mschmd_file *file)
static const char * rtable_name
void mspack_destroy_chm_decompressor(struct mschm_decompressor *base)
static int chmd_init_decomp(struct mschm_decompressor_p *self, struct mschmd_file *file)
static int chmd_error(struct mschm_decompressor *base)
static void chmd_close(struct mschm_decompressor *base, struct mschmd_header *chm)
static const char * spaninfo_name
struct mschm_decompressor * mspack_create_chm_decompressor(struct mspack_system *sys)
static int read_reset_table(struct mschm_decompressor_p *self, struct mschmd_sec_mscompressed *sec, unsigned int entry, off_t *length_ptr, off_t *offset_ptr)
static int search_chunk(struct mschmd_header *chm, const unsigned char *chunk, const char *filename, const unsigned char **result, const unsigned char **result_end)
static int chmd_fast_find(struct mschm_decompressor *base, struct mschmd_header *chm, const char *filename, struct mschmd_file *f_ptr, int f_size)
static int read_spaninfo(struct mschm_decompressor_p *self, struct mschmd_sec_mscompressed *sec, off_t *length_ptr)
static int read_off64(off_t *var, unsigned char *mem, struct mspack_system *sys, struct mspack_file *fh)
static struct mschmd_header * chmd_real_open(struct mschm_decompressor *base, const char *filename, int entire)
static const char * content_name
static const unsigned char guids[32]
static struct mschmd_header * chmd_fast_open(struct mschm_decompressor *base, const char *filename)
static struct mschmd_header * chmd_open(struct mschm_decompressor *base, const char *filename)
#define GET_UTF8_CHAR(s, e, c)
static unsigned char * read_chunk(struct mschm_decompressor_p *self, struct mschmd_header *chm, struct mspack_file *fh, unsigned int chunk)
static int chmd_sys_write(struct mspack_file *file, void *buffer, int bytes)
static int find_sys_file(struct mschm_decompressor_p *self, struct mschmd_sec_mscompressed *sec, struct mschmd_file **f_ptr, const char *name)
static int chmd_read_headers(struct mspack_system *sys, struct mspack_file *fh, struct mschmd_header *chm, int entire)
static int run(int i, const char *arg)
struct mschm_decompressor base
struct mschmd_header * chm
struct mschmd_file * next
struct mschmd_section * section
struct mschmd_file * content
struct mschmd_file * rtable
struct mschmd_file * spaninfo
struct mschmd_section base
struct mschmd_file * control
struct mschmd_section base
struct mschmd_header * chm
void(* copy)(void *src, void *dest, size_t bytes)
void(* close)(struct mspack_file *file)
struct mspack_file *(* open)(struct mspack_system *self, const char *filename, int mode)
void(* message)(struct mspack_file *file, const char *format,...)
int(* seek)(struct mspack_file *file, off_t offset, int mode)
int(* read)(struct mspack_file *file, void *buffer, int bytes)
int(* write)(struct mspack_file *file, void *buffer, int bytes)
off_t(* tell)(struct mspack_file *file)
void *(* alloc)(struct mspack_system *self, size_t bytes)
void error(const char *msg)
if(dbg->bits==RZ_SYS_BITS_64)