70
110
return le32_to_host(value);
73
typedef struct byte_array_tag {
78
#define NUM_VBA_VERSIONS 14
79
vba_version_t vba_version[] = {
80
{ { 0x5e, 0x00, 0x00, 0x01 }, "Office 97", 5, FALSE},
81
{ { 0x5f, 0x00, 0x00, 0x01 }, "Office 97 SR1", 5, FALSE },
82
{ { 0x65, 0x00, 0x00, 0x01 }, "Office 2000 alpha?", 6, FALSE },
83
{ { 0x6b, 0x00, 0x00, 0x01 }, "Office 2000 beta?", 6, FALSE },
84
{ { 0x6d, 0x00, 0x00, 0x01 }, "Office 2000", 6, FALSE },
85
{ { 0x6f, 0x00, 0x00, 0x01 }, "Office 2000", 6, FALSE },
86
{ { 0x70, 0x00, 0x00, 0x01 }, "Office XP beta 1/2", 6, FALSE },
87
{ { 0x73, 0x00, 0x00, 0x01 }, "Office XP", 6, FALSE },
88
{ { 0x76, 0x00, 0x00, 0x01 }, "Office 2003", 6, FALSE },
89
{ { 0x79, 0x00, 0x00, 0x01 }, "Office 2003", 6, FALSE },
90
{ { 0x60, 0x00, 0x00, 0x0e }, "MacOffice 98", 5, TRUE },
91
{ { 0x62, 0x00, 0x00, 0x0e }, "MacOffice 2001", 5, TRUE },
92
{ { 0x63, 0x00, 0x00, 0x0e }, "MacOffice X", 6, TRUE },
93
{ { 0x64, 0x00, 0x00, 0x0e }, "MacOffice 2004", 6, TRUE },
113
static const vba_version_t vba_version[NUM_VBA_VERSIONS] = {
114
{ { 0x5e, 0x00, 0x00, 0x01 }, "Office 97", FALSE},
115
{ { 0x5f, 0x00, 0x00, 0x01 }, "Office 97 SR1", FALSE },
116
{ { 0x65, 0x00, 0x00, 0x01 }, "Office 2000 alpha?", FALSE },
117
{ { 0x6b, 0x00, 0x00, 0x01 }, "Office 2000 beta?", FALSE },
118
{ { 0x6d, 0x00, 0x00, 0x01 }, "Office 2000", FALSE },
119
{ { 0x6f, 0x00, 0x00, 0x01 }, "Office 2000", FALSE },
120
{ { 0x70, 0x00, 0x00, 0x01 }, "Office XP beta 1/2", FALSE },
121
{ { 0x73, 0x00, 0x00, 0x01 }, "Office XP", FALSE },
122
{ { 0x76, 0x00, 0x00, 0x01 }, "Office 2003", FALSE },
123
{ { 0x79, 0x00, 0x00, 0x01 }, "Office 2003", FALSE },
124
{ { 0x60, 0x00, 0x00, 0x0e }, "MacOffice 98", TRUE },
125
{ { 0x62, 0x00, 0x00, 0x0e }, "MacOffice 2001", TRUE },
126
{ { 0x63, 0x00, 0x00, 0x0e }, "MacOffice X", TRUE },
127
{ { 0x64, 0x00, 0x00, 0x0e }, "MacOffice 2004", TRUE },
96
#define VBA56_DIRENT_RECORD_COUNT (2 + /* magic */ \
100
#define VBA56_DIRENT_HEADER_SIZE (VBA56_DIRENT_RECORD_COUNT + \
101
2 + /* type1 record count */ \
104
static char *get_unicode_name(char *name, int size, int is_mac)
131
get_unicode_name(const char *name, int size, int is_mac)
109
if (!name || *name == 0 || size <= 0) {
113
newname = (char *) cli_malloc(size*7);
118
for (i=0 ; i < size; i += (is_mac ? 1 : 2) ) {
119
if (isprint(name[i])) {
120
newname[j++] = name[i];
122
if (name[i] < 10 && name[i] >= 0) {
124
newname[j++] = name[i] + '0';
127
const uint16_t x = (((uint16_t)name[i]) << 8) | name[i+1];
129
newname[j++] = 'a'+((x&0xF));
130
newname[j++] = 'a'+((x>>4)&0xF);
131
newname[j++] = 'a'+((x>>8)&0xF);
132
newname[j++] = 'a'+((x>>16)&0xF);
133
newname[j++] = 'a'+((x>>24)&0xF);
136
if((name == NULL) || (*name == '\0') || (size <= 0))
139
newname = (char *)cli_malloc(size * 7);
143
if((!is_mac) && (size & 0x1)) {
144
cli_dbgmsg("get_unicode_name: odd number of bytes %d\n", size);
148
increment = (is_mac) ? 1 : 2;
151
for(i = 0; i < size; i += increment) {
155
if(name[i] < 10 && name[i] >= 0) {
157
*ret++ = (char)(name[i] + '0');
159
const uint16_t x = (uint16_t)(((name[i]) << 8) | name[i + 1]);
162
*ret++ = (char)('a'+((x&0xF)));
163
*ret++ = (char)('a'+((x>>4)&0xF));
164
*ret++ = (char)('a'+((x>>8)&0xF));
166
*ret++ = (char)('a'+((x>>16)&0xF)); /* FIXME: x>>16 MUST == 0 */
167
*ret++ = (char)('a'+((x>>24)&0xF)); /* FIXME: x>>24 MUST == 0 */
183
221
lseek(fd, -2, SEEK_CUR);
186
cli_dbgmsg ("length: %d, ", length);
187
224
buff = (unsigned char *) cli_malloc(length);
189
226
cli_errmsg("cli_malloc failed\n");
192
229
offset = lseek(fd, 0, SEEK_CUR);
193
if (cli_readn(fd, buff, length) != length) {
231
if (cli_readn(fd, buff, length) != (int)length) {
194
232
cli_dbgmsg("read name failed - rewinding\n");
195
233
lseek(fd, offset, SEEK_SET);
199
name = get_unicode_name(buff, length, is_mac);
201
cli_dbgmsg("name: %s\n", name);
203
cli_dbgmsg("name: [null]\n");
237
name = get_unicode_name((const char *)buff, length, is_mac);
239
cli_dbgmsg("length: %d, name: %s\n", length, name);
241
cli_dbgmsg("length: %d, name: [null]\n", length);
207
244
/* Ignore twelve bytes from entries of type 'G'.
208
245
Type 'C' entries come in pairs, the second also
209
246
having a 12 byte trailer */
210
247
/* TODO: Need to check if types H(same as G) and D(same as C) exist */
211
if (name && (!strncmp ("*\\G", name, 3) || !strncmp ("*\\H", name, 3)
212
|| !strncmp("*\\C", name, 3) || !strncmp("*\\D", name, 3))) {
213
if (cli_readn(fd, &length, 2) != 2) {
216
length = vba_endian_convert_16(length, is_mac);
217
if ((length != 0) && (length != 65535)) {
218
lseek(fd, -2, SEEK_CUR);
222
buff = (unsigned char *) cli_malloc(10);
228
if (cli_readn(fd, buff, 10) != 10) {
229
cli_errmsg("failed to read blob\n");
248
if((name == NULL) || (memcmp("*\\", name, 2) != 0) ||
249
(strchr("GCHD", name[2]) == NULL)) {
237
250
/* Unknown type - probably ran out of strings - rewind */
238
251
lseek(fd, -(length+2), SEEK_CUR);
245
offset = lseek(fd, 0, SEEK_CUR);
258
if (cli_readn(fd, &length, 2) != 2)
261
length = vba_endian_convert_16(length, is_mac);
262
if ((length != 0) && (length != 65535)) {
263
lseek(fd, -2, SEEK_CUR);
266
offset = lseek(fd, 10, SEEK_CUR);
246
267
cli_dbgmsg("offset: %u\n", offset);
247
268
vba56_test_middle(fd);
252
273
vba_project_t *vba56_dir_read(const char *dir)
254
unsigned char magic[2];
255
unsigned char version[4];
256
275
unsigned char *buff;
257
unsigned char vba56_signature[] = { 0xcc, 0x61 };
276
const unsigned char vba56_signature[] = { 0xcc, 0x61 };
258
277
uint16_t record_count, length;
260
279
uint16_t byte_count;
262
uint32_t LidA; /* Language identifiers */
271
int i, j, fd, is_mac;
272
282
vba_project_t *vba_project;
283
struct vba56_header v56h;
284
char fullname[NAME_MAX + 1];
275
286
cli_dbgmsg("in vba56_dir_read()\n");
277
fullname = (char *) cli_malloc(strlen(dir) + 14);
281
sprintf(fullname, "%s/_VBA_PROJECT", dir);
288
snprintf(fullname, sizeof(fullname) - 1, "%s/_VBA_PROJECT", dir);
282
289
fd = open(fullname, O_RDONLY|O_BINARY);
285
292
cli_dbgmsg("Can't open %s\n", fullname);
287
293
/* vba56_old_dir_read(dir); */
292
if (cli_readn(fd, &magic, 2) != 2) {
296
if (memcmp(magic, vba56_signature, 2) != 0) {
301
if (cli_readn(fd, &version, 4) != 4) {
305
for (i=0 ; i < NUM_VBA_VERSIONS ; i++) {
306
if (memcmp(version, vba_version[i].signature, 4) == 0) {
297
if(cli_readn(fd, &v56h, sizeof(struct vba56_header)) != sizeof(struct vba56_header)) {
301
if (memcmp(v56h.magic, vba56_signature, sizeof(v56h.magic)) != 0) {
306
for(i = 0; i < NUM_VBA_VERSIONS; i++)
307
if(memcmp(v56h.version, vba_version[i].signature, sizeof(vba_version[i].signature)) == 0)
311
310
if (i == NUM_VBA_VERSIONS) {
312
311
cli_warnmsg("Unknown VBA version signature %x %x %x %x\n",
313
version[0], version[1], version[2], version[3]);
314
if (version[3] == 0x01) {
315
cli_warnmsg("Guessing little-endian\n");
317
} else if (version[3] == 0x0e) {
318
cli_warnmsg("Guessing big-endian\n");
321
cli_warnmsg("Unable to guess VBA type\n");
312
v56h.version[0], v56h.version[1],
313
v56h.version[2], v56h.version[3]);
314
switch(v56h.version[3]) {
316
cli_warnmsg("Guessing little-endian\n");
320
cli_warnmsg("Guessing big-endian\n");
324
cli_warnmsg("Unable to guess VBA type\n");
326
cli_dbgmsg("VBA Project: %s, VBA Version=%d\n", vba_version[i].name,
327
vba_version[i].vba_version);
329
cli_dbgmsg("VBA Project: %s\n", vba_version[i].name);
328
330
is_mac = vba_version[i].is_mac;
331
/*****************************************/
333
/* two bytes, should be equal to 0x00ff */
334
if (cli_readn(fd, &ooff, 2) != 2) {
339
if (cli_readn(fd, &LidA, 4) != 4) {
344
if (cli_readn(fd, &LidB, 4) != 4) {
349
if (cli_readn(fd, &CharSet, 2) != 2) {
353
if (cli_readn(fd, &LenA, 2) != 2) {
358
if (cli_readn(fd, &UnknownB, 4) != 4) {
362
if (cli_readn(fd, &UnknownC, 4) != 4) {
367
if (cli_readn(fd, &LenB, 2) != 2) {
371
if (cli_readn(fd, &LenC, 2) != 2) {
375
if (cli_readn(fd, &LenD, 2) != 2) {
380
LidA = vba_endian_convert_32(LidA, is_mac);
381
LidB = vba_endian_convert_32(LidB, is_mac);
382
CharSet = vba_endian_convert_16(CharSet, is_mac);
383
LenA = vba_endian_convert_16(LenA, is_mac);
384
LenB = vba_endian_convert_16(LenB, is_mac);
385
LenC = vba_endian_convert_16(LenC, is_mac);
386
LenD = vba_endian_convert_16(LenD, is_mac);
388
cli_dbgmsg(" LidA: %d\n LidB: %d\n CharSet: %d\n", LidA, LidB, CharSet);
389
cli_dbgmsg(" LenA: %d\n UnknownB: %d\n UnknownC: %d\n", LenA, UnknownB, UnknownC);
390
cli_dbgmsg(" LenB: %d\n LenC: %d\n LenD: %d\n", LenB, LenC, LenD);
394
333
if (!vba_read_project_strings(fd, is_mac)) {
399
338
/* junk some more stuff */
401
if (cli_readn(fd, &ooff, 2) != 2) {
340
if (cli_readn(fd, &ffff, 2) != 2) {
405
} while(ooff != 0xFFFF);
344
} while(ffff != 0xFFFF);
407
346
/* check for alignment error */
408
347
lseek(fd, -3, SEEK_CUR);
409
if (cli_readn(fd, &ooff, 2) != 2) {
348
if (cli_readn(fd, &ffff, 2) != 2) {
413
if (ooff != 0xFFFF) {
352
if (ffff != 0xFFFF) {
414
353
lseek(fd, 1, SEEK_CUR);
417
if (cli_readn(fd, &ooff, 2) != 2) {
356
if (cli_readn(fd, &ffff, 2) != 2) {
422
361
/* no idea what this stuff is */
423
if (ooff != 0xFFFF) {
424
ooff = vba_endian_convert_16(ooff, is_mac);
425
lseek(fd, ooff, SEEK_CUR);
362
if (ffff != 0xFFFF) {
363
ffff = vba_endian_convert_16(ffff, is_mac);
364
lseek(fd, ffff, SEEK_CUR);
427
if (cli_readn(fd, &ooff, 2) != 2) {
366
if (cli_readn(fd, &ffff, 2) != 2) {
431
if (ooff != 0xFFFF) {
432
ooff = vba_endian_convert_16(ooff, is_mac);
433
lseek(fd, ooff, SEEK_CUR);
370
if (ffff != 0xFFFF) {
371
ffff = vba_endian_convert_16(ffff, is_mac);
372
lseek(fd, ffff, SEEK_CUR);
435
374
lseek(fd, 100, SEEK_CUR);
475
414
vba_project->count = record_count;
476
for (i=0 ; i < record_count ; i++) {
477
if (cli_readn(fd, &length, 2) != 2) {
415
for(i = 0; i < record_count; i++) {
416
if(cli_readn(fd, &length, 2) != 2)
480
419
length = vba_endian_convert_16(length, is_mac);
481
420
if (length == 0) {
482
421
cli_dbgmsg("zero name length\n");
485
424
buff = (unsigned char *) cli_malloc(length);
487
426
cli_dbgmsg("cli_malloc failed\n");
490
429
if (cli_readn(fd, buff, length) != length) {
491
430
cli_dbgmsg("read name failed\n");
495
vba_project->name[i] = get_unicode_name(buff, length, is_mac);
434
vba_project->name[i] = get_unicode_name((const char *)buff, length, is_mac);
496
436
if (!vba_project->name[i]) {
497
437
offset = lseek(fd, 0, SEEK_CUR);
498
438
vba_project->name[i] = (char *) cli_malloc(18);
499
snprintf(vba_project->name[i], 18, "clamav-%.10d", offset);
439
if(vba_project->name[i] == NULL) {
442
snprintf(vba_project->name[i], 18, "clamav-%.10d", (int)offset);
501
444
cli_dbgmsg("project name: %s, ", vba_project->name[i]);
504
446
/* some kind of string identifier ?? */
505
447
if (cli_readn(fd, &length, 2) != 2) {
506
448
free(vba_project->name[i]);
509
451
length = vba_endian_convert_16(length, is_mac);
510
452
lseek(fd, length, SEEK_CUR);
512
454
/* unknown stuff */
513
if (cli_readn(fd, &ooff, 2) != 2) {
455
if (cli_readn(fd, &ffff, 2) != 2) {
514
456
free(vba_project->name[i]);
517
ooff = vba_endian_convert_16(ooff, is_mac);
518
if (ooff == 0xFFFF) {
459
ffff = vba_endian_convert_16(ffff, is_mac);
460
if (ffff == 0xFFFF) {
519
461
lseek(fd, 2, SEEK_CUR);
520
if (cli_readn(fd, &ooff, 2) != 2) {
462
if (cli_readn(fd, &ffff, 2) != 2) {
521
463
free(vba_project->name[i]);
524
ooff = vba_endian_convert_16(ooff, is_mac);
525
lseek(fd, ooff, SEEK_CUR);
466
ffff = vba_endian_convert_16(ffff, is_mac);
467
lseek(fd, ffff, SEEK_CUR);
527
lseek(fd, 2 + ooff, SEEK_CUR);
469
lseek(fd, 2 + ffff, SEEK_CUR);
530
472
lseek(fd, 8, SEEK_CUR);
531
473
if (cli_readn(fd, &byte_count, 2) != 2) {
532
474
free(vba_project->name[i]);
535
477
byte_count = vba_endian_convert_16(byte_count, is_mac);
536
for (j=0 ; j<byte_count; j++) {
537
lseek(fd, 8, SEEK_CUR);
539
lseek(fd, 5, SEEK_CUR);
478
lseek(fd, (8 * byte_count) + 5, SEEK_CUR);
540
479
if (cli_readn(fd, &offset, 4) != 4) {
541
480
free(vba_project->name[i]);
544
483
offset = vba_endian_convert_32(offset, is_mac);
545
484
vba_project->offset[i] = offset;
546
485
cli_dbgmsg("offset:%u\n", offset);
547
486
lseek(fd, 2, SEEK_CUR);
551
{ /* There appears to be some code in here */
555
foffset = lseek(fd, 0, SEEK_CUR);
556
cli_dbgmsg("\nOffset: 0x%x\n", (unsigned int)foffset);
491
if(i < record_count) {
492
/* above loop failed */
494
free(vba_project->name[i]);
496
free(vba_project->name);
497
free(vba_project->dir);
498
free(vba_project->offset);
559
503
return vba_project;
562
/* Note: only to be called from the above loop
563
when i == number of allocated stings */
564
for (j=0 ; j<i ; j++) {
565
free(vba_project->name[j]);
567
free(vba_project->name);
568
free(vba_project->dir);
569
free(vba_project->offset);
575
#define VBA_COMPRESSION_WINDOW 4096
577
static void byte_array_append(byte_array_t *array, unsigned char *src, unsigned int len)
579
if (array->length == 0) {
580
array->data = (unsigned char *) cli_malloc(len);
585
memcpy(array->data, src, len);
587
array->data = realloc(array->data, array->length+len);
591
memcpy(array->data+array->length, src, len);
592
array->length += len;
596
506
unsigned char *vba_decompress(int fd, uint32_t offset, int *size)
1007
909
struct macro_entry_tag *macro_entry;
1010
typedef struct macro_extname_tag {
1012
unsigned char *extname;
1016
typedef struct macro_extnames_tag {
1018
struct macro_extname_tag *macro_extname;
1021
typedef struct macro_intnames_tag {
1023
struct macro_intname_tag *macro_intname;
1026
typedef struct macro_intname_tag {
1029
unsigned char *intname;
1032
typedef struct menu_entry_tag {
1041
typedef struct menu_info_tag {
1043
struct menu_entry_tag *menu_entry;
1046
typedef struct mac_token_tag {
1047
unsigned char token;
1051
typedef struct mac_token2_tag {
912
static void wm_free_macro_info(macro_info_t *macro_info);
1057
914
static void wm_print_fib(mso_fib_t *fib)
1059
cli_dbgmsg("magic: 0x%.4x\n", fib->magic);
1060
cli_dbgmsg("version: 0x%.4x\n", fib->version);
1061
cli_dbgmsg("product: 0x%.4x\n", fib->product);
1062
cli_dbgmsg("lid: 0x%.4x\n", fib->lid);
1063
916
cli_dbgmsg("macro offset: 0x%.4x\n", fib->macro_offset);
1064
917
cli_dbgmsg("macro len: 0x%.4x\n\n", fib->macro_len);
1067
920
static int wm_read_fib(int fd, mso_fib_t *fib)
1069
if (cli_readn(fd, &fib->magic, 2) != 2) {
1070
cli_dbgmsg("read wm_fib failed\n");
1073
if (cli_readn(fd, &fib->version, 2) != 2) {
1074
cli_dbgmsg("read wm_fib failed\n");
1077
if (cli_readn(fd, &fib->product, 2) != 2) {
1078
cli_dbgmsg("read wm_fib failed\n");
1081
if (cli_readn(fd, &fib->lid, 2) != 2) {
1082
cli_dbgmsg("read wm_fib failed\n");
1085
if (cli_readn(fd, &fib->next, 2) != 2) {
1086
cli_dbgmsg("read wm_fib failed\n");
1089
if (cli_readn(fd, &fib->status, 2) != 2) {
1090
cli_dbgmsg("read wm_fib failed\n");
1094
922
/* don't need the information is this block, so seek forward */
1095
923
if (lseek(fd, 0x118, SEEK_SET) != 0x118) {
1096
924
cli_dbgmsg("lseek wm_fib failed\n");
1100
928
if (cli_readn(fd, &fib->macro_offset, 4) != 4) {
1101
929
cli_dbgmsg("read wm_fib failed\n");
1244
1065
cli_dbgmsg("lseek oxo3 failed\n");
1248
1069
cli_dbgmsg("oxo3 records2: %d\n", count);
1252
static menu_info_t *wm_read_menu_info(int fd)
1074
wm_skip_menu_info(int fd)
1255
menu_info_t *menu_info;
1256
menu_entry_t *menu_entry;
1258
menu_info = (menu_info_t *) cli_malloc(sizeof(menu_info_t));
1263
if (cli_readn(fd, &menu_info->count, 2) != 2) {
1078
if (cli_readn(fd, &count, sizeof(uint16_t)) != sizeof(uint16_t)) {
1264
1079
cli_dbgmsg("read menu_info failed\n");
1268
menu_info->count = vba_endian_convert_16(menu_info->count, FALSE);
1269
cli_dbgmsg("menu_info count: %d\n", menu_info->count);
1271
menu_info->menu_entry =
1272
(menu_entry_t *) cli_malloc(sizeof(menu_entry_t) * menu_info->count);
1273
if (!menu_info->menu_entry) {
1278
for (i=0 ; i < menu_info->count ; i++) {
1279
menu_entry = &menu_info->menu_entry[i];
1280
if (cli_readn(fd, &menu_entry->context, 2) != 2) {
1283
if (cli_readn(fd, &menu_entry->menu, 2) != 2) {
1286
if (cli_readn(fd, &menu_entry->extname_i, 2) != 2) {
1289
if (cli_readn(fd, &menu_entry->unknown, 2) != 2) {
1292
if (cli_readn(fd, &menu_entry->intname_i, 2) != 2) {
1295
if (cli_readn(fd, &menu_entry->pos, 2) != 2) {
1298
menu_entry->context = vba_endian_convert_16(menu_entry->context, FALSE);
1299
menu_entry->menu = vba_endian_convert_16(menu_entry->menu, FALSE);
1300
menu_entry->extname_i = vba_endian_convert_16(menu_entry->extname_i, FALSE);
1301
menu_entry->intname_i = vba_endian_convert_16(menu_entry->intname_i, FALSE);
1302
menu_entry->pos = vba_endian_convert_16(menu_entry->pos, FALSE);
1303
cli_dbgmsg("menu entry: %d.%d\n", menu_entry->menu, menu_entry->pos);
1308
cli_dbgmsg("read menu_entry failed\n");
1309
free(menu_info->menu_entry);
1314
static void wm_free_menu_info(menu_info_t *menu_info)
1317
free(menu_info->menu_entry);
1323
static macro_extnames_t *wm_read_macro_extnames(int fd)
1325
int i, is_unicode=0;
1082
count = vba_endian_convert_16(count, FALSE);
1083
cli_dbgmsg("menu_info count: %d\n", count);
1086
if(lseek(fd, count * 12, SEEK_CUR) == -1)
1092
wm_skip_macro_extnames(int fd)
1328
macro_extnames_t *macro_extnames;
1329
macro_extname_t *macro_extname;
1330
unsigned char *name_tmp;
1332
macro_extnames = (macro_extnames_t *) cli_malloc(sizeof(macro_extnames_t));
1333
if (!macro_extnames) {
1336
macro_extnames->count = 0;
1337
macro_extnames->macro_extname = NULL;
1339
offset_end = lseek(fd, 0, SEEK_CUR);
1340
if (cli_readn(fd, &size, 2) != 2) {
1096
off_t offset_end = lseek(fd, 0, SEEK_CUR);
1098
if(cli_readn(fd, &size, sizeof(int16_t)) != sizeof(int16_t)) {
1341
1099
cli_dbgmsg("read macro_extnames failed\n");
1342
free(macro_extnames);
1345
1102
size = vba_endian_convert_16(size, FALSE);
1346
1103
if (size == -1) { /* Unicode flag */
1348
if (cli_readn(fd, &size, 2) != 2) {
1104
if(cli_readn(fd, &size, sizeof(int16_t)) != sizeof(int16_t)) {
1349
1105
cli_dbgmsg("read macro_extnames failed\n");
1350
free(macro_extnames);
1353
1108
size = vba_endian_convert_16(size, FALSE);
1355
1113
cli_dbgmsg("ext names size: 0x%x\n", size);
1357
1115
offset_end += size;
1358
while (lseek(fd, 0, SEEK_CUR) < offset_end) {
1359
macro_extnames->count++;
1360
macro_extnames->macro_extname = (macro_extname_t *)
1361
cli_realloc2(macro_extnames->macro_extname,
1362
sizeof(macro_extname_t) * macro_extnames->count);
1363
if (macro_extnames->macro_extname == NULL) {
1364
cli_dbgmsg("read macro_extnames failed\n");
1368
macro_extname = ¯o_extnames->macro_extname[macro_extnames->count-1];
1370
if (cli_readn(fd, ¯o_extname->length, 1) != 1) {
1371
cli_dbgmsg("read macro_extnames failed\n");
1374
lseek(fd, 1, SEEK_CUR);
1375
if (macro_extname->length > 0) {
1376
name_tmp = (char *) cli_malloc(macro_extname->length*2);
1377
if (name_tmp == NULL) {
1380
if (cli_readn(fd, name_tmp, macro_extname->length*2) !=
1381
macro_extname->length*2) {
1382
cli_dbgmsg("read macro_extnames failed\n");
1386
macro_extname->extname =
1387
get_unicode_name(name_tmp, macro_extname->length*2, FALSE);
1390
macro_extname->extname = cli_strdup("[no name]");
1391
macro_extname->length = 10;
1394
if (cli_readn(fd, ¯o_extname->length, 1) != 1) {
1395
cli_dbgmsg("read macro_extnames failed\n");
1398
if (macro_extname->length > 0) {
1399
macro_extname->extname = (char *) cli_malloc(macro_extname->length+1);
1400
if (!macro_extname->extname) {
1403
if (cli_readn(fd, macro_extname->extname, macro_extname->length) !=
1404
macro_extname->length) {
1405
cli_dbgmsg("read macro_extnames failed\n");
1406
free(macro_extname->extname);
1409
macro_extname->extname[macro_extname->length] = '\0';
1411
macro_extname->extname = cli_strdup("[no name]");
1412
macro_extname->length = 10;
1415
if (cli_readn(fd, ¯o_extname->numref, 2) != 2) {
1416
cli_dbgmsg("read macro_extnames failed\n");
1419
macro_extname->numref = vba_endian_convert_16(macro_extname->numref, FALSE);
1420
cli_dbgmsg("ext name: %s\n", macro_extname->extname);
1422
return macro_extnames;
1425
if (macro_extnames->macro_extname != NULL) {
1426
for (i=0 ; i < macro_extnames->count-1 ; i++) {
1427
free(macro_extnames->macro_extname[i].extname);
1429
free(macro_extnames->macro_extname);
1431
free(macro_extnames);
1435
static void wm_free_extnames(macro_extnames_t *macro_extnames)
1439
if (macro_extnames) {
1440
for (i=0 ; i < macro_extnames->count ; i++) {
1441
free(macro_extnames->macro_extname[i].extname);
1443
free(macro_extnames->macro_extname);
1444
free(macro_extnames);
1449
static macro_intnames_t *wm_read_macro_intnames(int fd)
1452
macro_intnames_t *macro_intnames;
1453
macro_intname_t *macro_intname;
1456
macro_intnames = (macro_intnames_t *) cli_malloc(sizeof(macro_intnames_t));
1457
if (!macro_intnames) {
1461
if (cli_readn(fd, ¯o_intnames->count, 2) != 2) {
1116
while(lseek(fd, 0, SEEK_CUR) < offset_end) {
1120
if (cli_readn(fd, &length, 1) != 1) {
1121
cli_dbgmsg("read macro_extnames failed\n");
1126
offset = (off_t)length * 2 + 1;
1128
offset = (off_t)length;
1130
offset += sizeof(uint16_t); /* numref */
1131
if(lseek(fd, offset, SEEK_CUR) == -1) {
1132
cli_dbgmsg("read macro_extnames failed to seek\n");
1140
wm_skip_macro_intnames(int fd)
1144
if (cli_readn(fd, &count, sizeof(uint16_t)) != sizeof(uint16_t)) {
1462
1145
cli_dbgmsg("read macro_intnames failed\n");
1465
macro_intnames->count = vba_endian_convert_16(macro_intnames->count, FALSE);
1466
cli_dbgmsg("int names count: %d\n", macro_intnames->count);
1468
macro_intnames->macro_intname =
1469
(macro_intname_t *) cli_malloc(sizeof(macro_intname_t) * macro_intnames->count);
1470
if (!macro_intnames->macro_intname) {
1471
free(macro_intnames);
1474
for (i=0 ; i < macro_intnames->count ; i++) {
1475
macro_intname = ¯o_intnames->macro_intname[i];
1476
if (cli_readn(fd, ¯o_intname->id, 2) != 2) {
1477
cli_dbgmsg("read macro_intnames failed\n");
1478
macro_intnames->count = i;
1481
macro_intname->id = vba_endian_convert_16(macro_intname->id, FALSE);
1482
if (cli_readn(fd, ¯o_intname->length, 1) != 1) {
1483
cli_dbgmsg("read macro_intnames failed\n");
1484
macro_intnames->count = i;
1487
macro_intname->intname = (char *) cli_malloc(macro_intname->length+1);
1488
if (!macro_intname->intname) {
1489
macro_intnames->count = i;
1492
if (cli_readn(fd, macro_intname->intname, macro_intname->length) != macro_intname->length) {
1493
cli_dbgmsg("read macro_intnames failed\n");
1494
macro_intnames->count = i+1;
1497
macro_intname->intname[macro_intname->length] = '\0';
1498
if (cli_readn(fd, &junk, 1) != 1) {
1499
cli_dbgmsg("read macro_intnames failed\n");
1500
macro_intnames->count = i+1;
1503
cli_dbgmsg("int name: %s\n", macro_intname->intname);
1505
return macro_intnames;
1507
for (i=0 ; i < macro_intnames->count ; i++) {
1508
free(macro_intnames->macro_intname[i].intname);
1510
free(macro_intnames->macro_intname);
1511
free(macro_intnames);
1515
static void wm_free_intnames(macro_intnames_t *macro_intnames)
1519
if (macro_intnames) {
1520
for (i=0 ; i < macro_intnames->count ; i++) {
1521
free(macro_intnames->macro_intname[i].intname);
1523
free(macro_intnames->macro_intname);
1524
free(macro_intnames);
1148
count = vba_endian_convert_16(count, FALSE);
1149
cli_dbgmsg("int names count: %u\n", count);
1151
for(i = 0; i < count; i++) {
1155
if(lseek(fd, sizeof(uint16_t), SEEK_CUR) == -1) {
1156
cli_dbgmsg("skip_macro_intnames failed\n");
1160
if(cli_readn(fd, &length, sizeof(uint8_t)) != sizeof(uint8_t)) {
1161
cli_dbgmsg("skip_macro_intnames failed\n");
1165
/* Internal name, plus one byte of unknown data */
1166
if(lseek(fd, length + 1, SEEK_CUR) == -1) {
1167
cli_dbgmsg("skip_macro_intnames failed\n");
1529
1174
vba_project_t *wm_dir_read(const char *dir)
1531
int fd, done=FALSE, i;
1533
1177
off_t end_offset;
1534
unsigned char start_id, info_id;
1178
unsigned char info_id;
1535
1179
macro_info_t *macro_info=NULL;
1536
menu_info_t *menu_info=NULL;
1537
macro_extnames_t *macro_extnames=NULL;
1538
macro_intnames_t *macro_intnames=NULL;
1539
vba_project_t *vba_project=NULL;
1542
fullname = (char *) cli_malloc(strlen(dir) + 14);
1546
sprintf(fullname, "%s/WordDocument", dir);
1180
vba_project_t *vba_project;
1182
char fullname[NAME_MAX + 1];
1184
snprintf(fullname, sizeof(fullname) - 1, "%s/WordDocument", dir);
1547
1185
fd = open(fullname, O_RDONLY|O_BINARY);
1549
1186
if (fd == -1) {
1550
1187
cli_dbgmsg("Open WordDocument failed\n");
1554
1191
if (!wm_read_fib(fd, &fib)) {
1195
if(fib.macro_len == 0) {
1196
cli_dbgmsg("No macros detected\n");
1558
1201
wm_print_fib(&fib);
1560
if (lseek(fd, fib.macro_offset, SEEK_SET) != (int64_t)fib.macro_offset) {
1203
/* Go one past the start to ignore start_id */
1204
if (lseek(fd, fib.macro_offset + 1, SEEK_SET) != (off_t)(fib.macro_offset + 1)) {
1561
1205
cli_dbgmsg("lseek macro_offset failed\n");
1566
1210
end_offset = fib.macro_offset + fib.macro_len;
1568
if (cli_readn(fd, &start_id, 1) != 1) {
1569
cli_dbgmsg("read start_id failed\n");
1573
cli_dbgmsg("start_id: %d\n", start_id);
1575
1213
while ((lseek(fd, 0, SEEK_CUR) < end_offset) && !done) {
1576
1214
if (cli_readn(fd, &info_id, 1) != 1) {
1577
1215
cli_dbgmsg("read macro_info failed\n");