git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@227 77e5149b-7576-45b1-b177-96237e5ba77b
Trog authored on 2004/02/02 21:51:46... | ... |
@@ -1,3 +1,10 @@ |
1 |
+Mon Feb 2 12:43:55 GMT 2004 (trog) |
|
2 |
+----------------------------------- |
|
3 |
+ * libclamav: ole2_extract.c: Add checks for compiler packed struct |
|
4 |
+ support. Fix sbat table in xbats bug. Fixup some data types. |
|
5 |
+ Add function to read ole2 header with compilers we don't know |
|
6 |
+ how to pack structures. |
|
7 |
+ |
|
1 | 8 |
Mon Feb 2 09:55:12 GMT 2004 (njh) |
2 | 9 |
---------------------------------- |
3 | 10 |
* libclamav: Some instances of Worm.Dumaru.Y got through the net |
... | ... |
@@ -31,6 +31,7 @@ |
31 | 31 |
#include <clamav.h> |
32 | 32 |
|
33 | 33 |
#include "cltypes.h" |
34 |
+#include "others.h" |
|
34 | 35 |
|
35 | 36 |
#define FALSE (0) |
36 | 37 |
#define TRUE (1) |
... | ... |
@@ -39,13 +40,11 @@ |
39 | 39 |
|
40 | 40 |
#ifdef WORDS_LITTLEENDIAN |
41 | 41 |
#define ole2_endian_convert_16(v) (v) |
42 |
-#warning Little Endian |
|
43 | 42 |
#else |
44 | 43 |
static uint16_t ole2_endian_convert_16(uint16_t v) |
45 | 44 |
{ |
46 | 45 |
return ((v >> 8) + (v << 8)); |
47 | 46 |
} |
48 |
-#warning Big Endian |
|
49 | 47 |
#endif |
50 | 48 |
|
51 | 49 |
#ifdef WORDS_LITTLEENDIAN |
... | ... |
@@ -58,6 +57,14 @@ static uint32_t ole2_endian_convert_32(uint32_t v) |
58 | 58 |
} |
59 | 59 |
#endif |
60 | 60 |
|
61 |
+#ifndef HAVE_ATTRIB_PACKED |
|
62 |
+#define __attribute__(x) |
|
63 |
+#endif |
|
64 |
+ |
|
65 |
+#ifdef HAVE_PRAGMA_PACK |
|
66 |
+#pragma pack(1) |
|
67 |
+#endif |
|
68 |
+ |
|
61 | 69 |
typedef struct ole2_header_tag |
62 | 70 |
{ |
63 | 71 |
unsigned char magic[8]; /* should be: 0xd0cf11e0a1b11ae1 */ |
... | ... |
@@ -85,7 +92,7 @@ typedef struct ole2_header_tag |
85 | 85 |
/* not part of the ole2 header, but stuff we need in order to decode */ |
86 | 86 |
/* must take account of the size of variables below here when |
87 | 87 |
reading the header */ |
88 |
- int sbat_root_start; |
|
88 |
+ int32_t sbat_root_start; |
|
89 | 89 |
} ole2_header_t __attribute__ ((packed)); |
90 | 90 |
|
91 | 91 |
typedef struct property_tag |
... | ... |
@@ -110,7 +117,11 @@ typedef struct property_tag |
110 | 110 |
unsigned char reserved[4]; |
111 | 111 |
} property_t __attribute__ ((packed)); |
112 | 112 |
|
113 |
-char magic_id[] = { 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1}; |
|
113 |
+#ifdef HAVE_PRAGMA_PACK |
|
114 |
+#pragma pack() |
|
115 |
+#endif |
|
116 |
+ |
|
117 |
+unsigned char magic_id[] = { 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1}; |
|
114 | 118 |
|
115 | 119 |
|
116 | 120 |
/* Function: readn |
... | ... |
@@ -286,9 +297,9 @@ void print_ole2_header(ole2_header_t *hdr) |
286 | 286 |
return; |
287 | 287 |
} |
288 | 288 |
|
289 |
-int ole2_read_block(int fd, ole2_header_t *hdr, void *buff, int blockno) |
|
289 |
+int ole2_read_block(int fd, ole2_header_t *hdr, void *buff, int32_t blockno) |
|
290 | 290 |
{ |
291 |
- int offset; |
|
291 |
+ off_t offset; |
|
292 | 292 |
|
293 | 293 |
// other methods: (blockno+1) * 512 or (blockno * block_size) + 512; |
294 | 294 |
offset = (blockno << hdr->log2_big_block_size) + 512; /* 512 is header size */ |
... | ... |
@@ -301,9 +312,9 @@ int ole2_read_block(int fd, ole2_header_t *hdr, void *buff, int blockno) |
301 | 301 |
return TRUE; |
302 | 302 |
} |
303 | 303 |
|
304 |
-int ole2_get_next_bat_block(int fd, ole2_header_t *hdr, int current_block) |
|
304 |
+int32_t ole2_get_next_bat_block(int fd, ole2_header_t *hdr, int32_t current_block) |
|
305 | 305 |
{ |
306 |
- int bat_array_index; |
|
306 |
+ int32_t bat_array_index; |
|
307 | 307 |
uint32_t bat[128]; |
308 | 308 |
|
309 | 309 |
bat_array_index = current_block / 128; |
... | ... |
@@ -315,24 +326,9 @@ int ole2_get_next_bat_block(int fd, ole2_header_t *hdr, int current_block) |
315 | 315 |
return ole2_endian_convert_32(bat[current_block-(bat_array_index * 128)]); |
316 | 316 |
} |
317 | 317 |
|
318 |
-int ole2_get_next_sbat_block(int fd, ole2_header_t *hdr, int current_block) |
|
319 |
-{ |
|
320 |
- int iter, current_bat_block; |
|
321 |
- uint32_t sbat[128]; |
|
322 |
- |
|
323 |
- current_bat_block = hdr->sbat_start; |
|
324 |
- iter = current_block / 128; |
|
325 |
- while (iter > 0) { |
|
326 |
- current_bat_block = ole2_get_next_bat_block(fd, hdr, current_bat_block); |
|
327 |
- iter--; |
|
328 |
- } |
|
329 |
- ole2_read_block(fd, hdr, &sbat, current_bat_block); |
|
330 |
- return ole2_endian_convert_32(sbat[current_block % 128]); |
|
331 |
-} |
|
332 |
- |
|
333 |
-int ole2_get_next_xbat_block(int fd, ole2_header_t *hdr, int current_block) |
|
318 |
+int32_t ole2_get_next_xbat_block(int fd, ole2_header_t *hdr, int32_t current_block) |
|
334 | 319 |
{ |
335 |
- int xbat_index, xbat_block_index, bat_index, bat_blockno; |
|
320 |
+ int32_t xbat_index, xbat_block_index, bat_index, bat_blockno; |
|
336 | 321 |
uint32_t xbat[128], bat[128]; |
337 | 322 |
|
338 | 323 |
xbat_index = current_block / 128; |
... | ... |
@@ -358,7 +354,7 @@ int ole2_get_next_xbat_block(int fd, ole2_header_t *hdr, int current_block) |
358 | 358 |
return ole2_endian_convert_32(bat[bat_index]); |
359 | 359 |
} |
360 | 360 |
|
361 |
-int ole2_get_next_block_number(int fd, ole2_header_t *hdr, int current_block) |
|
361 |
+int32_t ole2_get_next_block_number(int fd, ole2_header_t *hdr, int32_t current_block) |
|
362 | 362 |
{ |
363 | 363 |
if ((current_block / 128) > 108) { |
364 | 364 |
return ole2_get_next_xbat_block(fd, hdr, current_block); |
... | ... |
@@ -367,11 +363,25 @@ int ole2_get_next_block_number(int fd, ole2_header_t *hdr, int current_block) |
367 | 367 |
} |
368 | 368 |
} |
369 | 369 |
|
370 |
+int32_t ole2_get_next_sbat_block(int fd, ole2_header_t *hdr, int32_t current_block) |
|
371 |
+{ |
|
372 |
+ int32_t iter, current_bat_block; |
|
373 |
+ uint32_t sbat[128]; |
|
374 |
+ |
|
375 |
+ current_bat_block = hdr->sbat_start; |
|
376 |
+ iter = current_block / 128; |
|
377 |
+ while (iter > 0) { |
|
378 |
+ current_bat_block = ole2_get_next_block_number(fd, hdr, current_bat_block); |
|
379 |
+ iter--; |
|
380 |
+ } |
|
381 |
+ ole2_read_block(fd, hdr, &sbat, current_bat_block); |
|
382 |
+ return ole2_endian_convert_32(sbat[current_block % 128]); |
|
383 |
+} |
|
384 |
+ |
|
370 | 385 |
/* Retrieve the block containing the data for the given sbat index */ |
371 |
-int ole2_get_sbat_data_block(int fd, ole2_header_t *hdr, void *buff, int sbat_index) |
|
386 |
+int32_t ole2_get_sbat_data_block(int fd, ole2_header_t *hdr, void *buff, int32_t sbat_index) |
|
372 | 387 |
{ |
373 |
- int block_count; |
|
374 |
- int current_block; |
|
388 |
+ int32_t block_count, current_block; |
|
375 | 389 |
|
376 | 390 |
if (hdr->sbat_root_start < 0) { |
377 | 391 |
cli_errmsg("No root start block\n"); |
... | ... |
@@ -381,7 +391,7 @@ int ole2_get_sbat_data_block(int fd, ole2_header_t *hdr, void *buff, int sbat_in |
381 | 381 |
block_count = sbat_index / 8; // 8 small blocks per big block |
382 | 382 |
current_block = hdr->sbat_root_start; |
383 | 383 |
while (block_count > 0) { |
384 |
- current_block = ole2_get_next_bat_block(fd, hdr, current_block); |
|
384 |
+ current_block = ole2_get_next_block_number(fd, hdr, current_block); |
|
385 | 385 |
block_count--; |
386 | 386 |
} |
387 | 387 |
/* current_block now contains the block number of the sbat array |
... | ... |
@@ -397,7 +407,7 @@ void ole2_read_property_tree(int fd, ole2_header_t *hdr, const char *dir, |
397 | 397 |
void (*handler)(int fd, ole2_header_t *hdr, property_t *prop, const char *dir)) |
398 | 398 |
{ |
399 | 399 |
property_t prop_block[4]; |
400 |
- int index, current_block; |
|
400 |
+ int32_t index, current_block; |
|
401 | 401 |
|
402 | 402 |
current_block = hdr->prop_start; |
403 | 403 |
|
... | ... |
@@ -441,7 +451,7 @@ void handler_null(int fd, ole2_header_t *hdr, property_t *prop, const char *dir) |
441 | 441 |
void handler_writefile(int fd, ole2_header_t *hdr, property_t *prop, const char *dir) |
442 | 442 |
{ |
443 | 443 |
unsigned char buff[(1 << hdr->log2_big_block_size)]; |
444 |
- int current_block, ofd, len, offset; |
|
444 |
+ int32_t current_block, ofd, len, offset; |
|
445 | 445 |
char *name, *newname; |
446 | 446 |
|
447 | 447 |
if (prop->type != 2) { |
... | ... |
@@ -510,14 +520,86 @@ void handler_writefile(int fd, ole2_header_t *hdr, property_t *prop, const char |
510 | 510 |
return; |
511 | 511 |
} |
512 | 512 |
|
513 |
+int ole2_read_header(int fd, ole2_header_t *hdr) |
|
514 |
+{ |
|
515 |
+ int i; |
|
516 |
+ |
|
517 |
+ fprintf(stderr, "Slow header read\n"); |
|
518 |
+ if (readn(fd, &hdr->magic, 8) != 8) { |
|
519 |
+ return FALSE; |
|
520 |
+ } |
|
521 |
+ if (readn(fd, &hdr->clsid, 16) != 16) { |
|
522 |
+ return FALSE; |
|
523 |
+ } |
|
524 |
+ if (readn(fd, &hdr->minor_version, 2) != 2) { |
|
525 |
+ return FALSE; |
|
526 |
+ } |
|
527 |
+ if (readn(fd, &hdr->dll_version, 2) != 2) { |
|
528 |
+ return FALSE; |
|
529 |
+ } |
|
530 |
+ if (readn(fd, &hdr->byte_order, 2) != 2) { |
|
531 |
+ return FALSE; |
|
532 |
+ } |
|
533 |
+ if (readn(fd, &hdr->log2_big_block_size, 2) != 2) { |
|
534 |
+ return FALSE; |
|
535 |
+ } |
|
536 |
+ if (readn(fd, &hdr->log2_small_block_size, 4) != 4) { |
|
537 |
+ return FALSE; |
|
538 |
+ } |
|
539 |
+ if (readn(fd, &hdr->reserved, 8) != 8) { |
|
540 |
+ return FALSE; |
|
541 |
+ } |
|
542 |
+ if (readn(fd, &hdr->bat_count, 4) != 4) { |
|
543 |
+ return FALSE; |
|
544 |
+ } |
|
545 |
+ if (readn(fd, &hdr->prop_start, 4) != 4) { |
|
546 |
+ return FALSE; |
|
547 |
+ } |
|
548 |
+ if (readn(fd, &hdr->signature, 4) != 4) { |
|
549 |
+ return FALSE; |
|
550 |
+ } |
|
551 |
+ if (readn(fd, &hdr->sbat_cutoff, 4) != 4) { |
|
552 |
+ return FALSE; |
|
553 |
+ } |
|
554 |
+ if (readn(fd, &hdr->sbat_start, 4) != 4) { |
|
555 |
+ return FALSE; |
|
556 |
+ } |
|
557 |
+ if (readn(fd, &hdr->sbat_block_count, 4) != 4) { |
|
558 |
+ return FALSE; |
|
559 |
+ } |
|
560 |
+ if (readn(fd, &hdr->xbat_start, 4) != 4) { |
|
561 |
+ return FALSE; |
|
562 |
+ } |
|
563 |
+ if (readn(fd, &hdr->xbat_count, 4) != 4) { |
|
564 |
+ return FALSE; |
|
565 |
+ } |
|
566 |
+ for (i=0 ; i < 109 ; i++) { |
|
567 |
+ if (readn(fd, &hdr->bat_array[i], 4) != 4) { |
|
568 |
+ return FALSE; |
|
569 |
+ } |
|
570 |
+ } |
|
571 |
+ return TRUE; |
|
572 |
+} |
|
573 |
+ |
|
513 | 574 |
int cli_ole2_extract(int fd, const char *dirname) |
514 | 575 |
{ |
515 | 576 |
ole2_header_t hdr; |
516 |
- |
|
577 |
+ int hdr_size; |
|
578 |
+ |
|
517 | 579 |
cli_dbgmsg("in cli_ole2_extract()\n"); |
518 |
- |
|
580 |
+ |
|
519 | 581 |
/* size of header - size of other values in struct */ |
520 |
- readn(fd, &hdr, sizeof(struct ole2_header_tag) - sizeof(int)); |
|
582 |
+ hdr_size = sizeof(struct ole2_header_tag) - sizeof(int32_t); |
|
583 |
+ |
|
584 |
+#if defined(HAVE_ATTRIB_PACKED) || defined(HAVE_PRAGMA_PACK) |
|
585 |
+ if (readn(fd, &hdr, hdr_size) != hdr_size) { |
|
586 |
+ return 0; |
|
587 |
+ } |
|
588 |
+#else |
|
589 |
+ if (!ole2_read_header(fd, &hdr)) { |
|
590 |
+ return 0; |
|
591 |
+ } |
|
592 |
+#endif |
|
521 | 593 |
|
522 | 594 |
hdr.minor_version = ole2_endian_convert_16(hdr.minor_version); |
523 | 595 |
hdr.dll_version = ole2_endian_convert_16(hdr.dll_version); |