Browse code

Fix for cli_rebuildpe call in mew unpacker. Code is not yet 100% ready. Please only use for debugging purposes.

git-svn: trunk@2611

aCaB authored on 2007/01/13 05:22:13
Showing 6 changed files
... ...
@@ -1,3 +1,7 @@
1
+Fri Jan 12 21:20:00 CET 2007 (acab)
2
+-----------------------------------
3
+  * libclamav: Fix for cli_rebuildpe call in mew unpacker.
4
+
1 5
 Fri Jan 12 19:25:21 GMT 2007 (njh)
2 6
 ----------------------------------
3 7
   * clamav-milter:	Remove -b option (enable BOUNCE compile time option
... ...
@@ -44,6 +44,7 @@
44 44
 #include "others.h"
45 45
 #include "mew.h"
46 46
 #include "packlibs.h"
47
+#include "rebuildpe.h"
47 48
 
48 49
 #define EC32(x) le32_to_host(x) /* Convert little endian to host */
49 50
 #define CE32(x) be32_to_host(x) /* Convert big endian to host */
... ...
@@ -760,5 +761,109 @@ uint32_t lzma_upack_esi_54(struct lzmastate *p, uint32_t old_eax, uint32_t *old_
760 760
 }
761 761
 
762 762
 
763
-#endif
763
+int unmew11(struct pe_image_section_hdr *section_hdr, int sectnum, char *src, int off, int ssize, int dsize, uint32_t base, uint32_t vadd, int uselzma, char **endsrc, char **enddst, int filedesc)
764
+{
765
+	uint32_t entry_point, newedi, loc_ds=dsize, loc_ss=ssize;
766
+	char *source = src + dsize + off; /*EC32(section_hdr[sectnum].VirtualSize) + off;*/
767
+	char *lesi = source + 12, *ledi;
768
+	char *f1, *f2;
769
+	int i;
770
+	struct cli_exe_section *section = NULL;
771
+	uint32_t vma = base + vadd, size_sum = ssize + dsize;
772
+
773
+	entry_point  = cli_readint32(source + 4); /* 2vGiM: ate these safe enough?
774
+						   * yup, if (EC32(section_hdr[i + 1].SizeOfRawData) < ...
775
+						   * ~line #879 in pe.c
776
+						   */
777
+	newedi = cli_readint32(source + 8);
778
+	ledi = src + (newedi - vma);
779
+
780
+	i = 0;
781
+	ssize -= 12;
782
+	while (1)
783
+	{
784
+  		cli_dbgmsg("MEW unpacking section %d (%08x->%08x)\n", i, lesi, ledi);
785
+		if (!CLI_ISCONTAINED(src, size_sum, lesi, 4) || !CLI_ISCONTAINED(src, size_sum, ledi, 4))
786
+		{
787
+			cli_dbgmsg("Possibly programmer error or hand-crafted PE file, report to clamav team\n");
788
+			return -1;
789
+		}
790
+		if (unmew(lesi, ledi, loc_ss, loc_ds, &f1, &f2))
791
+		{
792
+			free(section);
793
+			return -1;
794
+		}
795
+
796
+		/* we don't need last section in sections since this is information for fixing imptbl */
797
+		if (!CLI_ISCONTAINED(src, size_sum, f1, 4))
798
+		{
799
+			free(section);
800
+			return -1;
801
+		}
802
+
803
+		/* XXX */
804
+		loc_ss -= (f1+4-lesi);
805
+		loc_ds -= (f2-ledi);
806
+		ledi = src + (cli_readint32(f1) - vma);
807
+		lesi = f1+4;
808
+
809
+		if (!uselzma)
810
+		{
811
+			uint32_t val = f2 - src;
812
+			/* round-up to 4k boundary, I'm not sure of this XXX */
813
+			val >>= 12;
814
+			val <<= 12;
815
+			val += 0x1000;
816
+
817
+			/* eeevil XXX */
818
+			section = cli_realloc(section, (i+2)*sizeof(struct cli_exe_section));
819
+			section[0].raw = 0; section[0].rva = vadd;
820
+			section[i+1].raw = val;
821
+			section[i+1].rva = val + vadd;
822
+			section[i].rsz = section[i].vsz = i?val - section[i].raw:val;
823
+		}
824
+		i++;
825
+
826
+		if (!cli_readint32(f1))
827
+			break;
828
+	}
829
+
830
+	/* LZMA stuff */
831
+	if (uselzma) {
832
+		/* put everything in one section */
833
+		i = 1;
834
+		if (!CLI_ISCONTAINED(src, size_sum, src+uselzma+8, 1))
835
+		{
836
+			cli_dbgmsg("MEW: couldn't access lzma 'special' tag\n");
837
+			free(section);
838
+			return -1;
839
+		}
840
+		/* 0x50 -> push eax */
841
+		cli_dbgmsg("MEW: lzma %swas used, unpacking\n", (*(src + uselzma+8) == '\x50')?"special ":"");
842
+		if (!CLI_ISCONTAINED(src, size_sum, f1+4, 20 + 4 + 5))
843
+		{
844
+			cli_dbgmsg("MEW: lzma initialization data not available!\n");
845
+			free(section);
846
+			return -1;
847
+		}
848
+		if(mew_lzma(&(section_hdr[sectnum]), src, f1+4, size_sum, vma, *(src + uselzma+8) == '\x50'))
849
+		{
850
+			free(section);
851
+			return -1;
852
+		}
853
+		loc_ds >>= 12; loc_ds <<= 12; loc_ds += 0x1000;
854
+		/* I have EP but no section's information, so I weren't sure what to do with that */ /* 2vGiM: sounds fair */
855
+		section = cli_calloc(1, sizeof(struct cli_exe_section));
856
+		section[0].raw = 0; section[0].rva = vadd;
857
+		section[0].rsz = section[0].vsz = dsize;
858
+	}
859
+	if (!cli_rebuildpe(src, section, i, base, entry_point - base, 0, 0, filedesc))
860
+	{
861
+		cli_dbgmsg("MEW: Rebuilding failed\n");
862
+		return -1;
863
+	}
864
+
865
+	return 1;
866
+}
764 867
 
868
+#endif /* CL_EXPERIMENTAL */
... ...
@@ -20,6 +20,11 @@
20 20
 #ifndef __MEW_H
21 21
 #define __MEW_H
22 22
 
23
+#if HAVE_CONFIG_H
24
+#include "clamav-config.h"
25
+#endif
26
+
27
+#ifdef CL_EXPERIMENTAL
23 28
 struct lzmastate {
24 29
 	char *p0;
25 30
 	uint32_t p1, p2;
... ...
@@ -30,9 +35,7 @@ int mew_lzma(struct pe_image_section_hdr *, char *, char *, uint32_t, uint32_t,
30 30
 uint32_t lzma_upack_esi_00(struct lzmastate *, char *, char *, uint32_t);
31 31
 uint32_t lzma_upack_esi_50(struct lzmastate *, uint32_t, uint32_t, char **, char *, uint32_t *, char *, uint32_t);
32 32
 uint32_t lzma_upack_esi_54(struct lzmastate *, uint32_t, uint32_t *, char **, uint32_t *, char *, uint32_t);
33
-
33
+int unmew11(struct pe_image_section_hdr *, int, char *, int, int, int, uint32_t, uint32_t, int, char **, char **, int);
34 34
 #endif
35 35
 
36
-
37
-
38
-
36
+#endif
... ...
@@ -25,7 +25,6 @@
25 25
 #include "others.h"
26 26
 #include "execs.h"
27 27
 #include "pe.h"
28
-#include "rebuildpe.h"
29 28
 
30 29
 static int doubledl(char **scur, uint8_t *mydlptr, char *buffer, uint32_t buffersize)
31 30
 {
... ...
@@ -171,7 +170,7 @@ int cli_unfsg(char *source, char *dest, int ssize, int dsize, char **endsrc, cha
171 171
 }
172 172
 
173 173
 #ifdef CL_EXPERIMENTAL
174
-static int unmew(char *source, char *dest, int ssize, int dsize, char **endsrc, char **enddst) {
174
+int unmew(char *source, char *dest, int ssize, int dsize, char **endsrc, char **enddst) {
175 175
   uint8_t mydl=0x80;
176 176
   uint32_t myeax_backbytes, myecx_backsize, oldback = 0;
177 177
   char *csrc = source, *cdst = dest;
... ...
@@ -310,115 +309,4 @@ static int unmew(char *source, char *dest, int ssize, int dsize, char **endsrc,
310 310
   return 0;
311 311
 }
312 312
 
313
-
314
-int unmew11(struct pe_image_section_hdr *section_hdr, int sectnum, char *src, int off, int ssize, int dsize, uint32_t base, uint32_t vadd, int uselzma, char **endsrc, char **enddst, int filedesc)
315
-{
316
-	uint32_t entry_point, newedi, loc_ds=dsize, loc_ss=ssize;
317
-	char *source = src + dsize + off; /*EC32(section_hdr[sectnum].VirtualSize) + off;*/
318
-	char *lesi = source + 12, *ledi;
319
-	char *f1, *f2;
320
-	int i;
321
-	struct cli_exe_section *section = NULL;
322
-	uint32_t vma = base + vadd, size_sum = ssize + dsize;
323
-
324
-	entry_point  = cli_readint32(source + 4); /* 2vGiM: ate these safe enough?
325
-						   * yup, if (EC32(section_hdr[i + 1].SizeOfRawData) < ...
326
-						   * ~line #879 in pe.c
327
-						   */
328
-	newedi = cli_readint32(source + 8);
329
-	ledi = src + (newedi - vma);
330
-
331
-	i = 0;
332
-	ssize -= 12;
333
-	while (1)
334
-	{
335
-  		cli_dbgmsg("MEW unpacking section %d (%08x->%08x)\n", i, lesi, ledi);
336
-		if (!CLI_ISCONTAINED(src, size_sum, lesi, 4) || !CLI_ISCONTAINED(src, size_sum, ledi, 4))
337
-		{
338
-			cli_dbgmsg("Possibly programmer error or hand-crafted PE file, report to clamav team\n");
339
-			return -1;
340
-		}
341
-		if (unmew(lesi, ledi, loc_ss, loc_ds, &f1, &f2))
342
-		{
343
-			free(section);
344
-			return -1;
345
-		}
346
-
347
-		/* we don't need last section in sections since this is information for fixing imptbl */
348
-		if (!CLI_ISCONTAINED(src, size_sum, f1, 4))
349
-		{
350
-			free(section);
351
-			return -1;
352
-		}
353
-
354
-		/* XXX */
355
-		loc_ss -= (f1+4-lesi);
356
-		loc_ds -= (f2-ledi);
357
-		ledi = src + (cli_readint32(f1) - vma);
358
-		lesi = f1+4;
359
-
360
-		if (!uselzma)
361
-		{
362
-			uint32_t val = f2 - src;
363
-			/* round-up to 4k boundary, I'm not sure of this XXX */
364
-			val >>= 12;
365
-			val <<= 12;
366
-			val += 0x1000;
367
-
368
-			/* eeevil XXX */
369
-			section = cli_realloc(section, (i+2)*sizeof(struct cli_exe_section));
370
-			section[0].raw = 0; section[0].rva = vadd;
371
-			section[i+1].raw = val;
372
-			section[i+1].rva = val + vadd;
373
-			section[i].rsz = section[i].vsz = i?val - section[i].raw:val;
374
-		}
375
-		i++;
376
-
377
-		if (!cli_readint32(f1))
378
-			break;
379
-	}
380
-
381
-	/* LZMA stuff */
382
-	if (uselzma) {
383
-		/* put everything in one section */
384
-		i = 1;
385
-		if (!CLI_ISCONTAINED(src, size_sum, src+uselzma+8, 1))
386
-		{
387
-			cli_dbgmsg("MEW: couldn't access lzma 'special' tag\n");
388
-			free(section);
389
-			return -1;
390
-		}
391
-		/* 0x50 -> push eax */
392
-		cli_dbgmsg("MEW: lzma %swas used, unpacking\n", (*(src + uselzma+8) == '\x50')?"special ":"");
393
-		if (!CLI_ISCONTAINED(src, size_sum, f1+4, 20 + 4 + 5))
394
-		{
395
-			cli_dbgmsg("MEW: lzma initialization data not available!\n");
396
-			free(section);
397
-			return -1;
398
-		}
399
-		if(mew_lzma(&(section_hdr[sectnum]), src, f1+4, size_sum, vma, *(src + uselzma+8) == '\x50'))
400
-		{
401
-			free(section);
402
-			return -1;
403
-		}
404
-		loc_ds >>= 12; loc_ds <<= 12; loc_ds += 0x1000;
405
-		/* I have EP but no section's information, so I weren't sure what to do with that */ /* 2vGiM: sounds fair */
406
-		section = cli_calloc(1, sizeof(struct cli_exe_section));
407
-		section[0].raw = 0; section[0].rva = vadd;
408
-		section[0].rsz = section[0].vsz = dsize;
409
-	}
410
-	if ((f1 = cli_rebuildpe(src, section, i, base, entry_point - base, 0, 0, filedesc)))
411
-	{
412
-		if (cli_writen(filedesc, f1, 0x148+0x80+0x28*i+dsize) == -1) {
413
-			free(f1);
414
-			return -1;
415
-		}
416
-	} else {
417
-		cli_dbgmsg("MEW: Rebuilding failed\n");
418
-		return -1;
419
-	}
420
-
421
-	return 1;
422
-}
423 313
 #endif
424
-
... ...
@@ -20,10 +20,17 @@
20 20
 #ifndef __PACKLIBS_H
21 21
 #define __PACKLIBS_H
22 22
 
23
+#if HAVE_CONFIG_H
24
+#include "clamav-config.h"
25
+#endif
26
+
23 27
 #include "cltypes.h"
24 28
 #include "rebuildpe.h"
25 29
 
26 30
 int cli_unfsg(char *, char *, int, int, char **, char **);
27
-int unmew11(struct pe_image_section_hdr *, int, char *, int, int, int, uint32_t, uint32_t, int, char **, char **, int);
31
+
32
+#ifdef CL_EXPERIMENTAL
33
+int unmew(char *, char *, int, int, char **, char **);
34
+#endif
28 35
 
29 36
 #endif
... ...
@@ -1165,6 +1165,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1165 1165
 		    free(section_hdr);
1166 1166
 		    return CL_EMEM;
1167 1167
 		}
1168
+		cli_dbgmsg ("MY FUCKING src IS AT %x\n", src);
1168 1169
 
1169 1170
 		if (EC32(section_hdr[i + 1].SizeOfRawData) < offdiff + 12 || EC32(section_hdr[i + 1].SizeOfRawData) > ssize)
1170 1171
 		{