Browse code

Mon Feb 2 12:43:55 GMT 2004 (trog) ----------------------------------- * libclamav: ole2_extract.c: Add checks for compiler packed struct support. Fix sbat table in xbats bug. Fixup some data types. Add function to read ole2 header with compilers we don't know how to pack structures.

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
Showing 2 changed files
... ...
@@ -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);