Browse code

Obey limits in unspin

git-svn: trunk@2418

aCaB authored on 2006/10/20 03:29:04
Showing 4 changed files
... ...
@@ -1,3 +1,7 @@
1
+Thu Oct 19 20:27:06 CEST 2006 (acab)
2
+------------------------------------
3
+  * libclamav: obey limits in unspin - closes bug#81 (thanks Trog)
4
+
1 5
 Thu Oct 19 18:34:43 BST 2006 (njh)
2 6
 ----------------------------------
3 7
   * libclamav:	Added JavaScript scanning
... ...
@@ -1892,7 +1892,19 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1892 1892
        EC32(optional_hdr32.AddressOfEntryPoint) < EC32(section_hdr[nsections - 1].VirtualAddress) + EC32(section_hdr[nsections - 1].SizeOfRawData) - 0x3217 - 4 &&
1893 1893
        memcmp(buff+4, "\xe8\x00\x00\x00\x00\x8b\x1c\x24\x83\xc3", 10) == 0)  {
1894 1894
 
1895
-	    char *spinned;
1895
+	char *spinned;
1896
+	int spinres;
1897
+	    
1898
+	if(ctx->limits && ctx->limits->maxfilesize && fsize > ctx->limits->maxfilesize) {
1899
+	    cli_dbgmsg("PEspin: Size exceeded (fsize: %u, max: %lu)\n", fsize, ctx->limits->maxfilesize);
1900
+            free(section_hdr);
1901
+	    if(BLOCKMAX) {
1902
+		*ctx->virname = "PE.Pespin.ExceededFileSize";
1903
+		return CL_VIRUS;
1904
+	    } else {
1905
+		return CL_CLEAN;
1906
+	    }
1907
+	}
1896 1908
 
1897 1909
 	if((spinned = (char *) cli_malloc(fsize)) == NULL) {
1898 1910
 	    free(section_hdr);
... ...
@@ -1921,36 +1933,47 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1921 1921
 	    return CL_EIO;
1922 1922
 	}
1923 1923
 
1924
-	if(!unspin(spinned, fsize, section_hdr, nsections - 1, EC32(optional_hdr32.AddressOfEntryPoint), ndesc)) {
1924
+	switch(unspin(spinned, fsize, section_hdr, nsections - 1, EC32(optional_hdr32.AddressOfEntryPoint), ndesc, ctx)) {
1925
+	case 0:
1925 1926
 	    free(spinned);
1926
-	    cli_dbgmsg("PESpin: Unpacked and rebuilt executable saved in %s\n", tempfile);
1927
+	    if(cli_leavetemps_flag)
1928
+		cli_dbgmsg("PESpin: Unpacked and rebuilt executable saved in %s\n", tempfile);
1929
+	    else
1930
+		cli_dbgmsg("PESpin: Unpacked and rebuilt executable\n");
1927 1931
 	    fsync(ndesc);
1928 1932
 	    lseek(ndesc, 0, SEEK_SET);
1929
-
1930 1933
 	    if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
1931
-		free(section_hdr);
1932 1934
 		close(ndesc);
1933
-		if(!cli_leavetemps_flag) {
1935
+		if(!cli_leavetemps_flag)
1934 1936
 		    unlink(tempfile);
1935
-		    free(tempfile);
1936
-		} else {
1937
-		    free(tempfile);
1938
-		}
1937
+	        free(tempfile);
1938
+		free(section_hdr);
1939 1939
 		return CL_VIRUS;
1940 1940
 	    }
1941
-
1942
-	} else {
1941
+	    close(ndesc);
1942
+   	    if(!cli_leavetemps_flag)
1943
+		unlink(tempfile);
1944
+	    break;
1945
+	case 1:
1943 1946
 	    free(spinned);
1947
+	    close(ndesc);
1948
+	    unlink(tempfile);
1944 1949
 	    cli_dbgmsg("PESpin: Rebuilding failed\n");
1945
-	}
1946
-
1947
-	close(ndesc);
1948
-	if(!cli_leavetemps_flag) {
1950
+	    break;
1951
+	case 2:
1952
+	    free(spinned);
1953
+	    close(ndesc);
1949 1954
 	    unlink(tempfile);
1950
-	    free(tempfile);
1951
-	} else {
1952
-	    free(tempfile);
1955
+	    cli_dbgmsg("PESpin: Size exceeded\n");
1956
+	    if(BLOCKMAX) {
1957
+		free(tempfile);
1958
+		free(section_hdr);
1959
+		*ctx->virname = "PE.Pespin.ExceededFileSize";
1960
+		return CL_VIRUS;
1961
+	    }
1953 1962
 	}
1963
+	free(tempfile);
1964
+	
1954 1965
     }
1955 1966
 
1956 1967
 
... ...
@@ -155,7 +155,7 @@ static uint32_t summit (char *src, int size)
155 155
 }
156 156
 
157 157
 
158
-int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sectcnt, uint32_t nep, int desc) {
158
+int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sectcnt, uint32_t nep, int desc, cli_ctx *ctx) {
159 159
   char *curr, *emu, *ep, *spinned;
160 160
   char **sects;
161 161
   int blobsz=0, j;
... ...
@@ -371,6 +371,21 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect
371 371
 
372 372
   bitmap = cli_readint32(ep+0x3061);
373 373
   bitman = bitmap;
374
+
375
+  if(ctx->limits && ctx->limits->maxfilesize) {
376
+    unsigned long int filesize = 0;
377
+    
378
+    for (j=0; j<sectcnt; j++) {
379
+      if (bitmap&1) {
380
+	if ( filesize > ctx->limits->maxfilesize || (uint32_t)EC32(sections[j].VirtualSize) > ctx->limits->maxfilesize - filesize ) return 2;
381
+	filesize += (uint32_t)EC32(sections[j].VirtualSize);
382
+      }
383
+      bitmap>>=1;
384
+    }
385
+    
386
+    bitmap = bitman;
387
+  }
388
+
374 389
   cli_dbgmsg("spin: Compression bitmap is %x\n", bitmap);
375 390
   if ( (sects= (char **) cli_malloc(sectcnt*sizeof(char *))) == NULL )
376 391
     return 1;
... ...
@@ -395,7 +410,7 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect
395 395
       sects[j] = src + EC32(sections[j].PointerToRawData);
396 396
       cli_dbgmsg("spin: Not growing sect%d\n", j);
397 397
     }
398
-    bitmap = bitmap >>1 & 0x7fffffff;
398
+    bitmap>>=1;
399 399
   }
400 400
   
401 401
   cli_dbgmsg("spin: decompression complete\n");
... ...
@@ -23,6 +23,6 @@
23 23
 #include "cltypes.h"
24 24
 #include "rebuildpe.h"
25 25
 
26
-int unspin(char *, int, struct pe_image_section_hdr *, int, uint32_t, int);
26
+int unspin(char *, int, struct pe_image_section_hdr *, int, uint32_t, int, cli_ctx *);
27 27
 
28 28
 #endif