Browse code

packers review

git-svn: trunk@2155

aCaB authored on 2006/07/31 20:03:20
Showing 3 changed files
... ...
@@ -1,3 +1,7 @@
1
+Mon Jul 31 12:59:30 CEST 2006 (acab)
2
+------------------------------------
3
+  * libclamav: packers review
4
+
1 5
 Mon Jul 31 10:24:35 BST 2006 (njh)
2 6
 ----------------------------------
3 7
   * libclamav/pdf.c, binhex.c:	Fixed compilation error under MSVC
... ...
@@ -138,7 +138,7 @@ static int cli_ddump(int desc, int offset, int size, const char *file)
138 138
 	return -1;
139 139
     }
140 140
 
141
-    while((bread = read(desc, buff, FILEBUFF)) > 0) {
141
+    while((bread = cli_readn(desc, buff, FILEBUFF)) > 0) {
142 142
 	if(sum + bread >= size) {
143 143
 	    if(write(ndesc, buff, size - sum) == -1) {
144 144
 		cli_dbgmsg("Can't write to file\n");
... ...
@@ -190,7 +190,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
190 190
 	size_t fsize;
191 191
 
192 192
 
193
-    if(read(desc, &e_magic, sizeof(e_magic)) != sizeof(e_magic)) {
193
+    if(cli_readn(desc, &e_magic, sizeof(e_magic)) != sizeof(e_magic)) {
194 194
 	cli_dbgmsg("Can't read DOS signature\n");
195 195
 	return CL_CLEAN;
196 196
     }
... ...
@@ -202,7 +202,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
202 202
 
203 203
     lseek(desc, 58, SEEK_CUR); /* skip to the end of the DOS header */
204 204
 
205
-    if(read(desc, &e_lfanew, sizeof(e_lfanew)) != sizeof(e_lfanew)) {
205
+    if(cli_readn(desc, &e_lfanew, sizeof(e_lfanew)) != sizeof(e_lfanew)) {
206 206
 	cli_dbgmsg("Can't read new header address\n");
207 207
 	/* truncated header? */
208 208
 	if(DETECT_BROKEN) {
... ...
@@ -226,7 +226,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
226 226
 	return CL_CLEAN;
227 227
     }
228 228
 
229
-    if(read(desc, &file_hdr, sizeof(struct pe_image_file_hdr)) != sizeof(struct pe_image_file_hdr)) {
229
+    if(cli_readn(desc, &file_hdr, sizeof(struct pe_image_file_hdr)) != sizeof(struct pe_image_file_hdr)) {
230 230
 	/* bad information in e_lfanew - probably not a PE file */
231 231
 	cli_dbgmsg("Can't read file header\n");
232 232
 	return CL_CLEAN;
... ...
@@ -374,7 +374,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
374 374
 
375 375
     if(!pe_plus) { /* PE */
376 376
 
377
-	if(read(desc, &optional_hdr32, sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr32)) {
377
+	if(cli_readn(desc, &optional_hdr32, sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr32)) {
378 378
 	    cli_dbgmsg("Can't read optional file header\n");
379 379
 	    if(DETECT_BROKEN) {
380 380
 		if(ctx->virname)
... ...
@@ -411,7 +411,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
411 411
 
412 412
     } else { /* PE+ */
413 413
 
414
-	if(read(desc, &optional_hdr64, sizeof(struct pe_image_optional_hdr64)) != sizeof(struct pe_image_optional_hdr64)) {
414
+	if(cli_readn(desc, &optional_hdr64, sizeof(struct pe_image_optional_hdr64)) != sizeof(struct pe_image_optional_hdr64)) {
415 415
 	    cli_dbgmsg("Can't optional file header\n");
416 416
 	    if(DETECT_BROKEN) {
417 417
 		if(ctx->virname)
... ...
@@ -503,7 +503,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
503 503
 
504 504
     for(i = 0; i < nsections; i++) {
505 505
 
506
-	if(read(desc, &section_hdr[i], sizeof(struct pe_image_section_hdr)) != sizeof(struct pe_image_section_hdr)) {
506
+	if(cli_readn(desc, &section_hdr[i], sizeof(struct pe_image_section_hdr)) != sizeof(struct pe_image_section_hdr)) {
507 507
 	    cli_dbgmsg("Can't read section header\n");
508 508
 	    cli_dbgmsg("Possibly broken PE file\n");
509 509
 	    free(section_hdr);
... ...
@@ -600,7 +600,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
600 600
     /* W32.Parite.B */
601 601
     if(SCAN_ALGO && !dll && ep == EC32(section_hdr[nsections - 1].PointerToRawData)) {
602 602
 	lseek(desc, ep, SEEK_SET);
603
-	if(read(desc, buff, 4096) == 4096) {
603
+	if(cli_readn(desc, buff, 4096) == 4096) {
604 604
 		const char *pt = cli_memstr(buff, 4040, "\x47\x65\x74\x50\x72\x6f\x63\x41\x64\x64\x72\x65\x73\x73\x00", 15);
605 605
 	    if(pt) {
606 606
 		    uint32_t dw1, dw2;
... ...
@@ -619,7 +619,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
619 619
     if(SCAN_ALGO && CLI_ISCONTAINED(EC32(section_hdr[nsections - 1].PointerToRawData), EC32(section_hdr[nsections - 1].SizeOfRawData), ep, 0x0fd2)) {
620 620
 	cli_dbgmsg("in kriz\n");
621 621
 	lseek(desc, ep, SEEK_SET);
622
-	if(read(desc, buff, 200) == 200) {
622
+	if(cli_readn(desc, buff, 200) == 200) {
623 623
 		while (1) {
624 624
 			char *krizpos=buff+3;
625 625
 			char *krizmov, *krizxor;
... ...
@@ -687,7 +687,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
687 687
 		int bw = rsize < 0x7000 ? rsize : 0x7000;
688 688
 
689 689
 	    lseek(desc, EC32(section_hdr[nsections - 1].PointerToRawData) + rsize - bw, SEEK_SET);
690
-	    if(read(desc, buff, 4096) == 4096) {
690
+	    if(cli_readn(desc, buff, 4096) == 4096) {
691 691
 		if(cli_memstr(buff, 4091, "\xe8\x2c\x61\x00\x00", 5)) {
692 692
 		    *ctx->virname = "W32.Magistr.A";
693 693
 		    free(section_hdr);
... ...
@@ -699,7 +699,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
699 699
 		int bw = rsize < 0x8000 ? rsize : 0x8000;
700 700
 
701 701
 	    lseek(desc, EC32(section_hdr[nsections - 1].PointerToRawData) + rsize - bw, SEEK_SET);
702
-	    if(read(desc, buff, 4096) == 4096) {
702
+	    if(cli_readn(desc, buff, 4096) == 4096) {
703 703
 		if(cli_memstr(buff, 4091, "\xe8\x04\x72\x00\x00", 5)) {
704 704
 		    *ctx->virname = "W32.Magistr.B";
705 705
 		    free(section_hdr);
... ...
@@ -833,7 +833,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
833 833
 	    return CL_EIO;
834 834
 	}
835 835
 
836
-        if(read(desc, buff, 168) != 168) {
836
+        if(cli_readn(desc, buff, 168) != 168) {
837 837
 	    cli_dbgmsg("UPX/FSG: Can't read 168 bytes at 0x%x (%d)\n", ep, ep);
838 838
 	    cli_dbgmsg("UPX/FSG: Broken or not UPX/FSG compressed file\n");
839 839
             free(section_hdr);
... ...
@@ -878,7 +878,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
878 878
 		}
879 879
 
880 880
 		lseek(desc, EC32(section_hdr[i + 1].PointerToRawData), SEEK_SET);
881
-		if((unsigned int) read(desc, src, ssize) != ssize) {
881
+		if((unsigned int) cli_readn(desc, src, ssize) != ssize) {
882 882
 		    cli_dbgmsg("Can't read raw data of section %d\n", i);
883 883
 		    free(section_hdr);
884 884
 		    free(src);
... ...
@@ -1053,7 +1053,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1053 1053
 		    return CL_EMEM;
1054 1054
 		}
1055 1055
 
1056
-		if(read(desc, support, gp) != gp) {
1056
+		if(cli_readn(desc, support, gp) != gp) {
1057 1057
 		    cli_dbgmsg("Can't read %d bytes from padding area\n", gp); 
1058 1058
 		    free(section_hdr);
1059 1059
 		    free(support);
... ...
@@ -1120,7 +1120,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1120 1120
 		}
1121 1121
 
1122 1122
 		lseek(desc, EC32(section_hdr[i + 1].PointerToRawData), SEEK_SET);
1123
-		if((unsigned int) read(desc, src, ssize) != ssize) {
1123
+		if((unsigned int) cli_readn(desc, src, ssize) != ssize) {
1124 1124
 		    cli_dbgmsg("Can't read raw data of section %d\n", i);
1125 1125
 		    free(section_hdr);
1126 1126
 		    free(sections);
... ...
@@ -1280,7 +1280,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1280 1280
 		    return CL_EMEM;
1281 1281
 		}
1282 1282
 
1283
-		if(read(desc, support, gp) != gp) {
1283
+		if(cli_readn(desc, support, gp) != gp) {
1284 1284
 		    cli_dbgmsg("Can't read %d bytes from padding area\n", gp); 
1285 1285
 		    free(section_hdr);
1286 1286
 		    free(support);
... ...
@@ -1328,7 +1328,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1328 1328
 		}
1329 1329
 
1330 1330
 		lseek(desc, EC32(section_hdr[i + 1].PointerToRawData), SEEK_SET);
1331
-		if((unsigned int) read(desc, src, ssize) != ssize) {
1331
+		if((unsigned int) cli_readn(desc, src, ssize) != ssize) {
1332 1332
 		    cli_dbgmsg("Can't read raw data of section %d\n", i);
1333 1333
 		    free(section_hdr);
1334 1334
 		    free(sections);
... ...
@@ -1473,7 +1473,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1473 1473
 	    }
1474 1474
 
1475 1475
 	    lseek(desc, EC32(section_hdr[i + 1].PointerToRawData), SEEK_SET);
1476
-	    if((unsigned int) read(desc, src, ssize) != ssize) {
1476
+	    if((unsigned int) cli_readn(desc, src, ssize) != ssize) {
1477 1477
 		cli_dbgmsg("Can't read raw data of section %d\n", i);
1478 1478
 		free(section_hdr);
1479 1479
 		free(src);
... ...
@@ -1491,7 +1491,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1491 1491
 		return CL_EIO;
1492 1492
 	    }
1493 1493
 
1494
-	    if(read(desc, buff, 126) != 126) { /* i.e. 0x69 + 13 + 8 */
1494
+	    if(cli_readn(desc, buff, 126) != 126) { /* i.e. 0x69 + 13 + 8 */
1495 1495
 		cli_dbgmsg("UPX: Can't read 126 bytes at 0x%x (%d)\n", ep, ep);
1496 1496
 		cli_dbgmsg("UPX/FSG: Broken or not UPX/FSG compressed file\n");
1497 1497
 		free(section_hdr);
... ...
@@ -1620,7 +1620,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1620 1620
     found = 2;
1621 1621
 
1622 1622
     lseek(desc, ep, SEEK_SET);
1623
-    if(read(desc, buff, 200) != 200) {
1623
+    if(cli_readn(desc, buff, 200) != 200) {
1624 1624
 	cli_dbgmsg("Can't read 200 bytes\n");
1625 1625
 	free(section_hdr);
1626 1626
 	return CL_EIO;
... ...
@@ -1662,7 +1662,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1662 1662
 		if(section_hdr[i].SizeOfRawData) {
1663 1663
 			uint32_t offset = cli_rawaddr(EC32(section_hdr[i].VirtualAddress), section_hdr, nsections, &err);
1664 1664
 
1665
-		    if(err || lseek(desc, offset, SEEK_SET) == -1 || (unsigned int) read(desc, dest + EC32(section_hdr[i].VirtualAddress) - min, EC32(section_hdr[i].SizeOfRawData)) != EC32(section_hdr[i].SizeOfRawData)) {
1665
+		    if(err || lseek(desc, offset, SEEK_SET) == -1 || (unsigned int) cli_readn(desc, dest + EC32(section_hdr[i].VirtualAddress) - min, EC32(section_hdr[i].SizeOfRawData)) != EC32(section_hdr[i].SizeOfRawData)) {
1666 1666
 			free(section_hdr);
1667 1667
 			free(dest);
1668 1668
 			return CL_EIO;
... ...
@@ -1745,7 +1745,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1745 1745
 	}
1746 1746
 
1747 1747
 	lseek(desc, 0, SEEK_SET);
1748
-	if((size_t) read(desc, spinned, fsize) != fsize) {
1748
+	if((size_t) cli_readn(desc, spinned, fsize) != fsize) {
1749 1749
 	    cli_dbgmsg("PESpin: Can't read %d bytes\n", fsize);
1750 1750
 	    free(spinned);
1751 1751
 	    free(section_hdr);
... ...
@@ -1814,7 +1814,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1814 1814
 	  }
1815 1815
 
1816 1816
 	  lseek(desc, 0, SEEK_SET);
1817
-	  if((size_t) read(desc, spinned, fsize) != fsize) {
1817
+	  if((size_t) cli_readn(desc, spinned, fsize) != fsize) {
1818 1818
 	    cli_dbgmsg("yC: Can't read %d bytes\n", fsize);
1819 1819
 	    free(spinned);
1820 1820
 	    free(section_hdr);
... ...
@@ -1907,7 +1907,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1907 1907
       memset(dest, 0, dsize);
1908 1908
 
1909 1909
       lseek(desc, 0, SEEK_SET);
1910
-      if((size_t) read(desc, dest, headsize) != headsize) {
1910
+      if((size_t) cli_readn(desc, dest, headsize) != headsize) {
1911 1911
 	cli_dbgmsg("WWPack: Can't read %d bytes from headers\n", headsize);
1912 1912
 	free(dest);
1913 1913
 	free(section_hdr);
... ...
@@ -1918,7 +1918,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1918 1918
 	if(section_hdr[i].SizeOfRawData) {
1919 1919
 	  uint32_t offset = cli_rawaddr(EC32(section_hdr[i].VirtualAddress), section_hdr, nsections, &err);
1920 1920
 	  
1921
-	  if(err || lseek(desc, offset, SEEK_SET) == -1 || (unsigned int) read(desc, dest + headsize + EC32(section_hdr[i].VirtualAddress) - min, EC32(section_hdr[i].SizeOfRawData)) != EC32(section_hdr[i].SizeOfRawData)) {
1921
+	  if(err || lseek(desc, offset, SEEK_SET) == -1 || (unsigned int) cli_readn(desc, dest + headsize + EC32(section_hdr[i].VirtualAddress) - min, EC32(section_hdr[i].SizeOfRawData)) != EC32(section_hdr[i].SizeOfRawData)) {
1922 1922
 	    free(dest);
1923 1923
 	    free(section_hdr);
1924 1924
 	    return CL_EIO;
... ...
@@ -1934,7 +1934,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1934 1934
       }
1935 1935
 
1936 1936
       lseek(desc, EC32(section_hdr[nsections - 1].PointerToRawData), SEEK_SET);      
1937
-      if((size_t) read(desc, wwp, EC32(section_hdr[nsections - 1].SizeOfRawData)) != EC32(section_hdr[nsections - 1].SizeOfRawData)) {
1937
+      if((size_t) cli_readn(desc, wwp, EC32(section_hdr[nsections - 1].SizeOfRawData)) != EC32(section_hdr[nsections - 1].SizeOfRawData)) {
1938 1938
 	cli_dbgmsg("WWPack: Can't read %d bytes from wwpack sect\n", EC32(section_hdr[nsections - 1].SizeOfRawData));
1939 1939
 	free(dest);
1940 1940
 	free(wwp);
... ...
@@ -2017,7 +2017,7 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo)
2017 2017
 
2018 2018
     cli_dbgmsg("in cli_peheader\n");
2019 2019
 
2020
-    if(read(desc, &e_magic, sizeof(e_magic)) != sizeof(e_magic)) {
2020
+    if(cli_readn(desc, &e_magic, sizeof(e_magic)) != sizeof(e_magic)) {
2021 2021
 	cli_dbgmsg("Can't read DOS signature\n");
2022 2022
 	return -1;
2023 2023
     }
... ...
@@ -2029,7 +2029,7 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo)
2029 2029
 
2030 2030
     lseek(desc, 58, SEEK_CUR); /* skip to the end of the DOS header */
2031 2031
 
2032
-    if(read(desc, &e_lfanew, sizeof(e_lfanew)) != sizeof(e_lfanew)) {
2032
+    if(cli_readn(desc, &e_lfanew, sizeof(e_lfanew)) != sizeof(e_lfanew)) {
2033 2033
 	cli_dbgmsg("Can't read new header address\n");
2034 2034
 	/* truncated header? */
2035 2035
 	return -1;
... ...
@@ -2047,7 +2047,7 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo)
2047 2047
 	return -1;
2048 2048
     }
2049 2049
 
2050
-    if(read(desc, &file_hdr, sizeof(struct pe_image_file_hdr)) != sizeof(struct pe_image_file_hdr)) {
2050
+    if(cli_readn(desc, &file_hdr, sizeof(struct pe_image_file_hdr)) != sizeof(struct pe_image_file_hdr)) {
2051 2051
 	/* bad information in e_lfanew - probably not a PE file */
2052 2052
 	cli_dbgmsg("Can't read file header\n");
2053 2053
 	return -1;
... ...
@@ -2072,7 +2072,7 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo)
2072 2072
     if(!pe_plus) { /* PE */
2073 2073
 	cli_dbgmsg("File format: PE\n");
2074 2074
 
2075
-	if(read(desc, &optional_hdr32, sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr32)) {
2075
+	if(cli_readn(desc, &optional_hdr32, sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr32)) {
2076 2076
 	    cli_dbgmsg("Can't optional file header\n");
2077 2077
 	    return -1;
2078 2078
 	}
... ...
@@ -2080,7 +2080,7 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo)
2080 2080
     } else { /* PE+ */
2081 2081
 	cli_dbgmsg("File format: PE32+\n");
2082 2082
 
2083
-	if(read(desc, &optional_hdr64, sizeof(struct pe_image_optional_hdr64)) != sizeof(struct pe_image_optional_hdr64)) {
2083
+	if(cli_readn(desc, &optional_hdr64, sizeof(struct pe_image_optional_hdr64)) != sizeof(struct pe_image_optional_hdr64)) {
2084 2084
 	    cli_dbgmsg("Can't optional file header\n");
2085 2085
 	    return -1;
2086 2086
 	}
... ...
@@ -2109,7 +2109,7 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo)
2109 2109
 
2110 2110
     for(i = 0; i < peinfo->nsections; i++) {
2111 2111
 
2112
-	if(read(desc, &section_hdr[i], sizeof(struct pe_image_section_hdr)) != sizeof(struct pe_image_section_hdr)) {
2112
+	if(cli_readn(desc, &section_hdr[i], sizeof(struct pe_image_section_hdr)) != sizeof(struct pe_image_section_hdr)) {
2113 2113
 	    cli_dbgmsg("Can't read section header\n");
2114 2114
 	    cli_dbgmsg("Possibly broken PE file\n");
2115 2115
 	    free(section_hdr);
... ...
@@ -314,7 +314,7 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect
314 314
   memcpy(spinned, src + EC32(sections[sectcnt].PointerToRawData), EC32(sections[sectcnt].SizeOfRawData)); 
315 315
   ep = spinned + nep - sections[sectcnt].VirtualAddress;
316 316
 
317
-  curr = ep+0xdb; /* HELP: as a general rule, can i do char* math or should use monsters like "&ep[0xdb]" instead? */
317
+  curr = ep+0xdb;
318 318
   if ( *curr != '\xbb' ) {
319 319
     free(spinned);
320 320
     cli_dbgmsg("spin: Not spinned or bad version\n");
... ...
@@ -337,26 +337,30 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect
337 337
 
338 338
   cli_dbgmsg("spin: Key8 is %x, Len is %x\n", key8, len);
339 339
 
340
-  if ( (uint32_t)(ep - spinned) >= EC32(sections[sectcnt].SizeOfRawData) - len - 0x1fe5 ) {
340
+  if (!CLI_ISCONTAINED(spinned, EC32(sections[sectcnt].SizeOfRawData), ep, len+0x1fe5-1)) {
341 341
     free(spinned);
342 342
     cli_dbgmsg("spin: len out of bounds, giving up\n");
343
-    return 1; /* Outta bounds - HELP: i suppose i should check for wraps.. not sure though */
343
+    return 1;
344 344
   }
345 345
 
346
-
347 346
   if ( ep[0x1e0]!='\xb8' )
348 347
     cli_dbgmsg("spin: prolly not spinned, expect failure\n");
349 348
   
350 349
   if ( (cli_readint32(ep+0x1e1) & 0x00200000) )
351 350
     cli_dbgmsg("spin: password protected, expect failure\n");
352 351
 
353
-
354 352
   curr = ep+0x1fe5+len-1;
355 353
   while ( len-- ) {
356 354
     *curr=(*curr)^(key8--);
357 355
     curr--;
358 356
   }
359 357
 
358
+  if (!CLI_ISCONTAINED(spinned, EC32(sections[sectcnt].SizeOfRawData), ep+0x3217, 4)) {
359
+    free(spinned);
360
+    cli_dbgmsg("spin: key out of bounds, giving up\n");
361
+    return 1;
362
+  }
363
+
360 364
   curr = ep+0x26eb;
361 365
   key32 = cli_readint32(curr);
362 366
   if ( (len = cli_readint32(curr+5)) != 0x5a0) {
... ...
@@ -365,15 +369,15 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect
365 365
     return 1;
366 366
   }
367 367
 
368
-  curr = ep+0x2d5; /* 0x2d5+5a0 < 0x3217 - still within bounds (checked by caller) */
368
+  curr = ep+0x2d5;
369 369
   cli_dbgmsg("spin: Key is %x, Len is %x\n", key32, len);
370 370
 
371 371
   while ( len-- ) {
372 372
     if ( key32 & 1 ) {
373
-      key32 = key32>>1&0x7fffffff;
373
+      key32 = key32>>1;
374 374
       key32 ^= 0x8c328834;
375 375
     } else {
376
-      key32 = key32>>1 & 0x7fffffff;
376
+      key32 = key32>>1;
377 377
     }
378 378
     *curr = *curr ^ (key32 & 0xff);
379 379
     curr++;
... ...
@@ -383,7 +387,7 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect
383 383
   if ( len >= (uint32_t)ssize ) {
384 384
     free(spinned);
385 385
     cli_dbgmsg("spin: crc out of bounds, giving up\n");
386
-    return 1; /* We wrapped */
386
+    return 1;
387 387
   }
388 388
   key32 = cli_readint32(ep+0x3217) - summit(src,len);
389 389
 
... ...
@@ -391,6 +395,10 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect
391 391
   free(spinned); /* done CRC'ing - can have a dirty buffer now */
392 392
   ep = src + nep + sections[sectcnt].PointerToRawData - sections[sectcnt].VirtualAddress; /* Fix the helper */
393 393
 
394
+  if (!CLI_ISCONTAINED(src, ssize, ep+0x3207, 4)) { /* this one holds all ep based checks */
395
+    cli_dbgmsg("spin: key out of bounds, giving up\n");
396
+    return 1;
397
+  }
394 398
   bitmap = cli_readint32(ep+0x3207);
395 399
   cli_dbgmsg("spin: Key32 is %x - XORbitmap is %x\n", key32, bitmap);
396 400
   
... ...
@@ -402,29 +410,29 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect
402 402
       char *ptr = src + EC32(sections[j].PointerToRawData);
403 403
       uint32_t keydup = key32;
404 404
       
405
-      if ( EC32(sections[j].PointerToRawData) + size >=  (uint32_t)ssize ) {
405
+      if (!CLI_ISCONTAINED(src, ssize, ptr, size)) {
406 406
 	cli_dbgmsg("spin: sect %d out of file, giving up\n", j);
407
-	return 1; /* sect outta bounds - HELP: i suppose i should check for wraps.. not sure though */
407
+	return 1; /* FIXME: Already checked in pe.c? */
408 408
       }
409 409
 
410 410
       while (size--) {
411 411
 	if (! (keydup & 1)) {
412
-	  keydup = keydup>>1&0x7fffffff; /* HELP: clear sign bit for unsigned values too? */
412
+	  keydup = keydup>>1;
413 413
 	  keydup ^= 0xed43af31;
414 414
 	} else {
415
-	  keydup = keydup>>1 & 0x7fffffff; /* HELP: clear sign bit for unsigned values too? */
415
+	  keydup = keydup>>1;
416 416
 	}
417 417
 	*ptr = *ptr ^ (keydup & 0xff);
418 418
 	ptr++;
419 419
       }
420 420
     } 
421
-    bitmap = bitmap >>1 & 0x7fffffff; /* HELP: clear sign bit for unsigned values too? */
421
+    bitmap = bitmap >>1;
422 422
   }
423 423
   
424 424
   cli_dbgmsg("spin: done\n");
425 425
 
426 426
   
427
-  curr = ep+0x644; /* 0x28d3+0x180 < 0x3217 - still within bounds (checked by caller) */
427
+  curr = ep+0x644;
428 428
   if ( (len = cli_readint32(curr)) != 0x180) {
429 429
     cli_dbgmsg("spin: Not spinned or bad version\n");
430 430
     return 1;
... ...
@@ -434,12 +442,16 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect
434 434
   cli_dbgmsg("spin: Key is %x, Len is %x\n", key32, len);
435 435
   curr = ep+0x28d3;
436 436
 
437
+  if (!CLI_ISCONTAINED(src, ssize, curr, len)) { /* always true but i may decide to remove the previous check */
438
+    cli_dbgmsg("spin: key out of bounds, giving up\n");
439
+    return 1;
440
+  }
437 441
   while ( len-- ) {
438 442
     if ( key32 & 1 ) {
439
-      key32 = key32>>1&0x7fffffff;
443
+      key32 = key32>>1;
440 444
       key32 ^= 0xed43af32;
441 445
     } else {
442
-      key32 = key32>>1 & 0x7fffffff;
446
+      key32 = key32>>1;
443 447
     }
444 448
     *curr = *curr ^ (key32 & 0xff);
445 449
     curr++;
... ...
@@ -454,8 +466,11 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect
454 454
 
455 455
   cli_dbgmsg("spin: POLY1 len is %x\n", len);
456 456
   curr+=0xf; /* POLY1 */
457
-  emu = ep+0x6d4; /* Still within bounds */
458
-
457
+  emu = ep+0x6d4;
458
+  if (!CLI_ISCONTAINED(src, ssize, emu, len)) {
459
+    cli_dbgmsg("spin: poly1 out of bounds\n");
460
+    return 1;
461
+  }
459 462
   while (len) {
460 463
     *emu=exec86(*emu, len-- & 0xff, curr); /* unlame POLY1 */
461 464
     emu++;
... ...
@@ -472,8 +487,8 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect
472 472
 
473 473
       emu = src + EC32(sections[j].PointerToRawData);
474 474
 
475
-      if ( emu < src || EC32(sections[j].PointerToRawData) + notthesamelen >= (uint32_t)ssize) { /* HELP: Is this enough for me to be within bounds? */
476
-	cli_dbgmsg("spin: code to exec is out of file?\n");
475
+      if (!CLI_ISCONTAINED(src,ssize,curr,0x24)) { /* section bounds already checked twice now */
476
+	cli_dbgmsg("spin: poly1 emucode is out of file?\n");
477 477
 	return 1;
478 478
       }
479 479
 
... ...
@@ -482,7 +497,7 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect
482 482
         emu++;
483 483
       }
484 484
     }
485
-      bitmap = bitmap >>1 & 0x7fffffff;
485
+      bitmap = bitmap >>1;
486 486
   }
487 487
   
488 488
   cli_dbgmsg("spin: done\n");
... ...
@@ -496,7 +511,7 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect
496 496
   len = 0;
497 497
   for (j=0; j<sectcnt; j++) {
498 498
     if (bitmap&1) {
499
-       if ( (sects[j] = (char *) cli_malloc(EC32(sections[j].VirtualSize)) ) == NULL ) { /* FIXME: use "static" maxmalloc @4380b6 instead??? */
499
+       if ( (sects[j] = (char *) cli_malloc(EC32(sections[j].VirtualSize)) ) == NULL ) {
500 500
 	 cli_dbgmsg("spin: malloc(%d) failed\n", EC32(sections[j].VirtualSize));
501 501
 	 len = 1;
502 502
 	 break;
... ...
@@ -508,7 +523,6 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect
508 508
 	 len++;
509 509
          cli_dbgmsg("spin: Unpack failure\n");
510 510
        }
511
-       /* sections[j].rsz = sections[j].vsz; FIXME: can't hack the caller, gotta find a better way! */
512 511
     } else {
513 512
       blobsz+=EC32(sections[j].SizeOfRawData);
514 513
       sects[j] = src + EC32(sections[j].PointerToRawData);
... ...
@@ -536,7 +550,7 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect
536 536
     /*    len = cli_readint32(ep+0x2fc8); -- Using vsizes instead */
537 537
 
538 538
     for (j=0; j<sectcnt; j++) {
539
-      if (EC32(sections[j].VirtualAddress) <= key32 && EC32(sections[j].VirtualAddress)+EC32(sections[j].SizeOfRawData) > key32) /* HELP: wraps? */
539
+      if (EC32(sections[j].VirtualAddress) <= key32 && EC32(sections[j].VirtualAddress)+EC32(sections[j].SizeOfRawData) > key32)
540 540
 	break;
541 541
     }
542 542
 
... ...
@@ -546,19 +560,19 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect
546 546
       if ( (curr=(char *)cli_malloc(EC32(sections[j].VirtualSize))) != NULL ) {
547 547
 	memcpy(curr, src + EC32(sections[j].PointerToRawData), key32 - EC32(sections[j].VirtualAddress)); /* Uncompressed part */
548 548
 	memset(curr + key32 - EC32(sections[j].VirtualAddress), 0, EC32(sections[j].VirtualSize) - (key32 - EC32(sections[j].VirtualAddress))); /* bzero */
549
-	if ( unfsg(src + EC32(sections[j].PointerToRawData) + key32 - EC32(sections[j].VirtualAddress), curr + key32 - EC32(sections[j].VirtualAddress), EC32(sections[j].SizeOfRawData) - (key32 - EC32(sections[j].VirtualAddress)), EC32(sections[j].VirtualSize) - (key32 - EC32(sections[j].VirtualAddress))) ) { /* HELP: i can't read my own line - hope's ok :( */
549
+	if ( unfsg(src + EC32(sections[j].PointerToRawData) + key32 - EC32(sections[j].VirtualAddress), curr + key32 - EC32(sections[j].VirtualAddress), EC32(sections[j].SizeOfRawData) - (key32 - EC32(sections[j].VirtualAddress)), EC32(sections[j].VirtualSize) - (key32 - EC32(sections[j].VirtualAddress))) ) {
550 550
       
551 551
 	  free(curr);
552 552
 	  cli_dbgmsg("spin: Failed to grow resources, continuing anyway\n");
553 553
 	  blobsz+=EC32(sections[j].SizeOfRawData);
554 554
 	} else {
555
-	  sects[j]=curr; /* FIXME: bitman check above should save me from leaks */
555
+	  sects[j]=curr;
556 556
 	  bitman|=1<<j;
557 557
 	  cli_dbgmsg("spin: Resources grown\n");
558 558
 	  blobsz+=EC32(sections[j].VirtualSize);
559 559
 	}
560 560
       } else {
561
-	/* HELP: malloc failed but i'm too deep into this crap to worry... what to do next? */
561
+	/* malloc failed but i'm too deep into this crap to quit without leaking more :( */
562 562
 	blobsz+=EC32(sections[j].SizeOfRawData);
563 563
       }
564 564
     } else {
... ...
@@ -584,10 +598,10 @@ int unspin(char *src, int ssize, struct pe_image_section_hdr *sections, int sect
584 584
 	memcpy(to, sects[j], rebhlp[j].rsz);
585 585
 	to+=rebhlp[j].rsz;
586 586
 	if ( bitmap & 1 ) free(sects[j]);
587
-	bitmap = bitmap >>1 & 0x7fffffff;
587
+	bitmap = bitmap >>1;
588 588
       }
589 589
 
590
-      if ( (to = rebuildpe(ep, rebhlp, sectcnt, 0x400000, 0x1000, 0, 0))) { /* HELP: should i bother fixing those values? the rebuilt exe is completely broken anyway. */
590
+      if ( (to = rebuildpe(ep, rebhlp, sectcnt, 0x400000, 0x1000, 0, 0))) { /* can't be bothered fixing those values: the rebuilt exe is completely broken anyway. */
591 591
 	if (cli_writen(desc, to, 0x148+0x80+0x28*j+rebhlp[j-1].raw+rebhlp[j-1].rsz)==-1) {
592 592
 	  cli_dbgmsg("spin: Cannot write unpacked file\n");
593 593
 	  retval = 1;