Browse code

handle pseudo-archives generated by installers

git-svn: trunk@1902

Tomasz Kojm authored on 2006/04/10 08:11:43
Showing 2 changed files
... ...
@@ -1,3 +1,8 @@
1
+Mon Apr 10 01:05:28 CEST 2006 (tk)
2
+----------------------------------
3
+  * libclamav/sis.c: handle pseudo-archives generated by installers
4
+		     Samples provided by aCaB
5
+
1 6
 Sun Apr  9 21:49:22 CEST 2006 (tk)
2 7
 ----------------------------------
3 8
   * update GPL headers with new address for FSF
... ...
@@ -93,7 +93,7 @@ static char *sis_utf16_decode(const char *str, uint32_t length)
93 93
     return decoded;
94 94
 }
95 95
 
96
-static int sis_extract_simple(int fd, char *mfile, uint32_t length, uint32_t offset, uint16_t nlangs, uint8_t compressed, const char *dir, cli_ctx *ctx)
96
+static int sis_extract_simple(int fd, char *mfile, uint32_t length, uint32_t offset, uint16_t nlangs, uint8_t compressed, uint8_t *ifile, const char *dir, cli_ctx *ctx)
97 97
 {
98 98
 	const char *typedir = NULL;
99 99
 	char *sname = NULL, *dname = NULL, *subdir, *fname, *buff;
... ...
@@ -163,7 +163,7 @@ static int sis_extract_simple(int fd, char *mfile, uint32_t length, uint32_t off
163 163
 	cli_warnmsg("SIS: sis_extract_simple: Source name too long and will not be decoded\n");
164 164
     } else {
165 165
 	nameoff = cli_readint32(mfile + offset + 12);
166
-	if(nameoff >= length ||  nameoff + namelen >= length) {
166
+	if(nameoff >= length || nameoff + namelen >= length) {
167 167
 	    cli_errmsg("SIS: sis_extract_simple: Broken source name data\n");
168 168
 	    return CL_EFORMAT;
169 169
 	}
... ...
@@ -223,7 +223,22 @@ static int sis_extract_simple(int fd, char *mfile, uint32_t length, uint32_t off
223 223
 	filelen = cli_readint32(mfile + offset + 24 + 4 * i);
224 224
 	fileoff = cli_readint32(mfile + offset + 24 + 4 * i + 4 * nlangs);
225 225
 
226
-	if(filelen >= length || fileoff >= length || filelen + fileoff > length) {
226
+	if(fileoff == length) {
227
+	    cli_dbgmsg("SIS: Null file (installation record)\n");
228
+	    *ifile = 1;
229
+	    continue;
230
+	} else if (fileoff > length) {
231
+	    if(!*ifile) {
232
+		cli_errmsg("SIS: sis_extract_simple: Broken file data (fileoff)\n");
233
+		free(subdir);
234
+		return CL_EFORMAT;
235
+	    } else {
236
+		cli_dbgmsg("SIS: Null file (installation track)\n");
237
+		continue;
238
+	    }
239
+	}
240
+
241
+	if(filelen >= length || filelen + fileoff > length) {
227 242
 	    cli_errmsg("SIS: sis_extract_simple: Broken file data (filelen, fileoff)\n");
228 243
 	    free(subdir);
229 244
 	    return CL_EFORMAT;
... ...
@@ -319,14 +334,14 @@ static int sis_extract_simple(int fd, char *mfile, uint32_t length, uint32_t off
319 319
     }
320 320
 
321 321
     free(subdir);
322
-    return 0;
322
+    return CL_SUCCESS;
323 323
 }
324 324
 
325 325
 int cli_scansis(int desc, cli_ctx *ctx)
326 326
 {
327 327
 	struct sis_file_hdr file_hdr;
328 328
 	struct sis_file_hdr6 file_hdr6;
329
-	uint8_t release = 0, compressed;
329
+	uint8_t release = 0, compressed, ifile = 0;
330 330
 	uint16_t opts, nlangs, *langrecs, nfiles;
331 331
 	uint32_t recp, frecord, n;
332 332
 	size_t length;
... ...
@@ -378,7 +393,7 @@ int cli_scansis(int desc, cli_ctx *ctx)
378 378
 	    break;
379 379
 	case 0x100039ce:
380 380
 	case 0x10003a38:
381
-	    cli_dbgmsg("SIS: Application(???)\n");
381
+	    cli_dbgmsg("SIS: Application(?)\n");
382 382
 	    return CL_CLEAN;
383 383
 	default:
384 384
 	    cli_warnmsg("SIS: Unknown value of UID 2 (EPOC release == 0x%x) -> not a real SIS file??\n", EC32(file_hdr.uid2));
... ...
@@ -538,7 +553,7 @@ int cli_scansis(int desc, cli_ctx *ctx)
538 538
 	switch(cli_readint32(mfile + frecord)) {
539 539
 	    case 0x00000000:
540 540
 		cli_dbgmsg("SIS: Simple file record\n");
541
-		if((ret = sis_extract_simple(desc, mfile, sb.st_size, frecord + 4, 1, compressed, dir, ctx))) {
541
+		if((ret = sis_extract_simple(desc, mfile, sb.st_size, frecord + 4, 1, compressed, &ifile, dir, ctx))) {
542 542
 		    munmap(mfile, length);
543 543
 		    if(!cli_leavetemps_flag)
544 544
 			cli_rmdirs(dir);
... ...
@@ -555,7 +570,7 @@ int cli_scansis(int desc, cli_ctx *ctx)
555 555
 	    case 0x00000001:
556 556
 		cli_dbgmsg("SIS: Multiple languages file record\n");
557 557
 		/* TODO: Pass language strings into sis_extract */
558
-		if((ret = sis_extract_simple(desc, mfile, sb.st_size, frecord + 4, nlangs, compressed, dir, ctx))) {
558
+		if((ret = sis_extract_simple(desc, mfile, sb.st_size, frecord + 4, nlangs, compressed, &ifile, dir, ctx))) {
559 559
 		    munmap(mfile, length);
560 560
 		    if(!cli_leavetemps_flag)
561 561
 			cli_rmdirs(dir);