Browse code

Merge remote-tracking branch 'origin/0.97' into 0.97

Shawn Webb authored on 2013/02/14 23:54:24
Showing 3 changed files
... ...
@@ -876,6 +876,17 @@ static void handle_pdfname(struct pdf_struct *pdf, struct pdf_obj *obj,
876 876
 static char *pdf_readstring(const char *q0, int len, const char *key, unsigned *slen);
877 877
 static int pdf_readint(const char *q0, int len, const char *key);
878 878
 static const char *pdf_getdict(const char *q0, int* len, const char *key);
879
+
880
+static void pdf_parse_trailer(struct pdf_struct *pdf, const char *s, long length)
881
+{
882
+    char *newID;
883
+    newID = pdf_readstring(s, length, "/ID", &pdf->fileIDlen);
884
+    if (newID) {
885
+        free(pdf->fileID);
886
+        pdf->fileID = newID;
887
+    }
888
+}
889
+
879 890
 static void pdf_parseobj(struct pdf_struct *pdf, struct pdf_obj *obj)
880 891
 {
881 892
     /* enough to hold common pdf names, we don't need all the names */
... ...
@@ -960,9 +971,9 @@ static void pdf_parseobj(struct pdf_struct *pdf, struct pdf_obj *obj)
960 960
 		if (trailer < 0) trailer = 0;
961 961
 		q2 = pdf->map + trailer;
962 962
 		cli_dbgmsg("cli_pdf: looking for trailer in linearized pdf: %ld - %ld\n", trailer, trailer_end);
963
-		pdf->fileID = pdf_readstring(q2, trailer_end - trailer, "/ID", &pdf->fileIDlen);
963
+		pdf_parse_trailer(pdf, q2, trailer_end - trailer);
964 964
 		if (pdf->fileID)
965
-		    cli_dbgmsg("found fileID\n");
965
+		    cli_dbgmsg("cli_pdf: found fileID\n");
966 966
 	    }
967 967
 	}
968 968
 	if (objstate == STATE_LAUNCHACTION)
... ...
@@ -1281,7 +1292,7 @@ static void check_user_password(struct pdf_struct *pdf, int R, const char *O,
1281 1281
 	if (!pdf->key)
1282 1282
 	    return;
1283 1283
 	memcpy(pdf->key, result, pdf->keylen);
1284
-	dbg_printhex("md5", result, 32);
1284
+	dbg_printhex("md5", result, 16);
1285 1285
 	dbg_printhex("Candidate encryption key", pdf->key, pdf->keylen);
1286 1286
 
1287 1287
 	/* 7.6.3.3 Algorithm 6 */
... ...
@@ -1521,7 +1532,7 @@ int cli_pdf(const char *dir, cli_ctx *ctx, off_t offset)
1521 1521
 		pdf.flags |= 1 << ENCRYPTED_PDF;
1522 1522
 		cli_dbgmsg("cli_pdf: encrypted pdf found, stream will probably fail to decompress!\n");
1523 1523
 		pdf_parse_encrypt(&pdf, enc, eof - enc);
1524
-		pdf.fileID = pdf_readstring(eofmap, bytesleft, "/ID", &pdf.fileIDlen);
1524
+		pdf_parse_trailer(&pdf, eofmap, bytesleft);
1525 1525
 	    }
1526 1526
 	    q += 9;
1527 1527
 	    while (q < eof && (*q == ' ' || *q == '\n' || *q == '\r')) { q++; }
... ...
@@ -1553,7 +1564,7 @@ int cli_pdf(const char *dir, cli_ctx *ctx, off_t offset)
1553 1553
     /* parse PDF and find obj offsets */
1554 1554
     while ((rc = pdf_findobj(&pdf)) > 0) {
1555 1555
 	struct pdf_obj *obj = &pdf.objs[pdf.nobjs-1];
1556
-	cli_dbgmsg("found %d %d obj @%ld\n", obj->id >> 8, obj->id&0xff, obj->start + offset);
1556
+	cli_dbgmsg("cli_pdf: found %d %d obj @%ld\n", obj->id >> 8, obj->id&0xff, obj->start + offset);
1557 1557
     }
1558 1558
     if (pdf.nobjs)
1559 1559
 	pdf.nobjs--;
... ...
@@ -2276,7 +2287,7 @@ ascii85decode(const char *buf, off_t len, unsigned char *output)
2276 2276
 			}
2277 2277
 		} else if(byte == 'z') {
2278 2278
 			if(quintet) {
2279
-				cli_dbgmsg("ascii85decode: unexpected 'z'\n");
2279
+				cli_dbgmsg("cli_pdf: ascii85decode: unexpected 'z'\n");
2280 2280
 				return -1;
2281 2281
 			}
2282 2282
 			*output++ = '\0';
... ...
@@ -2285,12 +2296,12 @@ ascii85decode(const char *buf, off_t len, unsigned char *output)
2285 2285
 			*output++ = '\0';
2286 2286
 			ret += 4;
2287 2287
 		} else if(byte == EOF) {
2288
-			cli_dbgmsg("ascii85decode: quintet %d\n", quintet);
2288
+			cli_dbgmsg("cli_pdf: ascii85decode: quintet %d\n", quintet);
2289 2289
 			if(quintet) {
2290 2290
 				int i;
2291 2291
 
2292 2292
 				if(quintet == 1) {
2293
-					cli_dbgmsg("ascii85Decode: only 1 byte in last quintet\n");
2293
+					cli_dbgmsg("cli_pdf: ascii85Decode: only 1 byte in last quintet\n");
2294 2294
 					return -1;
2295 2295
 				}
2296 2296
 				for(i = quintet; i < 5; i++)
... ...
@@ -2304,7 +2315,7 @@ ascii85decode(const char *buf, off_t len, unsigned char *output)
2304 2304
 			}
2305 2305
 			break;
2306 2306
 		} else if(!isspace(byte)) {
2307
-			cli_dbgmsg("ascii85Decode: invalid character 0x%x, len %lu\n",
2307
+			cli_dbgmsg("cli_pdf: ascii85Decode: invalid character 0x%x, len %lu\n",
2308 2308
 				byte & 0xFF, (unsigned long)len);
2309 2309
 			return -1;
2310 2310
 		}
... ...
@@ -2085,23 +2085,23 @@ int cli_scanpe(cli_ctx *ctx)
2085 2085
 	    !memcmp(epbuff+0x63+offset, "\xaa\xe2\xcc", 3) &&
2086 2086
 	    (fsize >= exe_sections[nsections-1].raw + 0xC6 + ecx + offset)) {
2087 2087
 
2088
-	char *spinned;
2088
+	    char *spinned;
2089 2089
 
2090
-	if((spinned = (char *) cli_malloc(fsize)) == NULL) {
2091
-	    free(exe_sections);
2092
-	    return CL_EMEM;
2093
-	}
2090
+	    if((spinned = (char *) cli_malloc(fsize)) == NULL) {
2091
+	      free(exe_sections);
2092
+	      return CL_EMEM;
2093
+	    }
2094 2094
 
2095
-	if((size_t) fmap_readn(map, spinned, 0, fsize) != fsize) {
2096
-	    cli_dbgmsg("yC: Can't read %lu bytes\n", (unsigned long)fsize);
2097
-	    free(spinned);
2098
-	    free(exe_sections);
2099
-	    return CL_EREAD;
2100
-	}
2095
+	    if((size_t) fmap_readn(map, spinned, 0, fsize) != fsize) {
2096
+	      cli_dbgmsg("yC: Can't read %lu bytes\n", (unsigned long)fsize);
2097
+	      free(spinned);
2098
+	      free(exe_sections);
2099
+	      return CL_EREAD;
2100
+	    }
2101 2101
 
2102
-	cli_dbgmsg("%d,%d,%d,%d\n", nsections-1, e_lfanew, ecx, offset);
2103
-	CLI_UNPTEMP("yC",(spinned,exe_sections,0));
2104
-	CLI_UNPRESULTS("yC",(yc_decrypt(spinned, fsize, exe_sections, nsections-1, e_lfanew, ndesc, ecx, offset)),0,(spinned,0));
2102
+	    cli_dbgmsg("%d,%d,%d,%d\n", nsections-1, e_lfanew, ecx, offset);
2103
+	    CLI_UNPTEMP("yC",(spinned,exe_sections,0));
2104
+	    CLI_UNPRESULTS("yC",(yc_decrypt(spinned, fsize, exe_sections, nsections-1, e_lfanew, ndesc, ecx, offset)),0,(spinned,0));
2105 2105
 	}
2106 2106
     }
2107 2107
 
... ...
@@ -40,7 +40,7 @@
40 40
 /* ========================================================================== */
41 41
 /* "Emulates" the poly decryptors */
42 42
 
43
-static int yc_poly_emulator(char* decryptor_offset, char* code, unsigned int ecx)
43
+static int yc_poly_emulator(char* decryptor_offset, char* code, unsigned int ecx, uint32_t max_emu)
44 44
 {
45 45
 
46 46
   /* 
... ...
@@ -64,7 +64,7 @@ static int yc_poly_emulator(char* decryptor_offset, char* code, unsigned int ecx
64 64
   unsigned char cl = ecx & 0xff;
65 65
   unsigned int j,i;
66 66
 
67
-  for(i=0;i<ecx;i++) /* Byte looper - Decrypts every byte and write it back */
67
+  for(i=0;i<ecx&&i<max_emu;i++) /* Byte looper - Decrypts every byte and write it back */
68 68
     {
69 69
       al = code[i];
70 70
 
... ...
@@ -168,7 +168,7 @@ int yc_decrypt(char *fbuf, unsigned int filesize, struct cli_exe_section *sectio
168 168
   unsigned int i;
169 169
   struct pe_image_file_hdr *pe = (struct pe_image_file_hdr*) (fbuf + peoffset);
170 170
   char *sname = (char *)pe + EC16(pe->SizeOfOptionalHeader) + 0x18;
171
-
171
+  uint32_t max_emu;
172 172
   /* 
173 173
 
174 174
   First layer (decryptor of the section decryptor) in last section 
... ...
@@ -180,7 +180,7 @@ int yc_decrypt(char *fbuf, unsigned int filesize, struct cli_exe_section *sectio
180 180
   */
181 181
   cli_dbgmsg("yC: offset: %x, length: %x\n", offset, ecx);
182 182
   cli_dbgmsg("yC: decrypting decryptor on sect %d\n", sectcount);
183
-  if (yc_poly_emulator(fbuf + ycsect + 0x93, fbuf + ycsect + 0xc6, ecx))
183
+  if (yc_poly_emulator(fbuf + ycsect + 0x93, fbuf + ycsect + 0xc6, ecx, ecx))
184 184
     return 1;
185 185
   filesize-=sections[sectcount].ursz;
186 186
 
... ...
@@ -190,31 +190,38 @@ int yc_decrypt(char *fbuf, unsigned int filesize, struct cli_exe_section *sectio
190 190
 
191 191
   Start offset for analyze: Start of yC Section + 0x457
192 192
   End offset for analyze: Start of yC Section + 0x487
193
-  Lenght to decrypt - ECX = Raw Size of Section
193
+  Length to decrypt - ECX = Raw Size of Section
194 194
 
195 195
   */
196 196
 
197 197
 
198 198
   /* Loop through all sections and decrypt them... */
199
-  for(i=0;i<sectcount;i++)
200
-    {
201
-      uint32_t name = (uint32_t) cli_readint32(sname+i*0x28);
202
-      if (!sections[i].raw ||
203
-	  !sections[i].rsz ||
204
-	   name == 0x63727372 || /* rsrc */
205
-	   name == 0x7273722E || /* .rsr */
206
-	   name == 0x6F6C6572 || /* relo */
207
-	   name == 0x6C65722E || /* .rel */
208
-	   name == 0x6164652E || /* .eda */
209
-	   name == 0x6164722E || /* .rda */
210
-	   name == 0x6164692E || /* .ida */
211
-	   name == 0x736C742E || /* .tls */
212
-	   (name&0xffff) == 0x4379  /* yC */
199
+  for(i=0;i<sectcount;i++) {
200
+    uint32_t name = (uint32_t) cli_readint32(sname+i*0x28);
201
+    if (!sections[i].raw ||
202
+	!sections[i].rsz ||
203
+	name == 0x63727372 || /* rsrc */
204
+	name == 0x7273722E || /* .rsr */
205
+	name == 0x6F6C6572 || /* relo */
206
+	name == 0x6C65722E || /* .rel */
207
+	name == 0x6164652E || /* .eda */
208
+	name == 0x6164722E || /* .rda */
209
+	name == 0x6164692E || /* .ida */
210
+	name == 0x736C742E || /* .tls */
211
+	(name&0xffff) == 0x4379  /* yC */
213 212
 	) continue;
214
-      cli_dbgmsg("yC: decrypting sect%d\n",i);
215
-      if (yc_poly_emulator(fbuf + ycsect + (offset == -0x18 ? 0x3ea : 0x457), fbuf + sections[i].raw, sections[i].ursz))
216
-	  return 1;
213
+    cli_dbgmsg("yC: decrypting sect%d\n",i);
214
+    max_emu = filesize - sections[i].raw;
215
+    if (max_emu > filesize) {
216
+      cli_dbgmsg("yC: bad emulation length limit %u\n", max_emu);
217
+      return 1;
217 218
     }
219
+    if (yc_poly_emulator(fbuf + ycsect + (offset == -0x18 ? 0x3ea : 0x457), 
220
+			 fbuf + sections[i].raw, 
221
+			 sections[i].ursz, 
222
+			 max_emu))
223
+      return 1;
224
+  }
218 225
 
219 226
   /* Remove yC section */
220 227
   pe->NumberOfSections=EC16(sectcount);