Browse code

macho to fmap

aCaB authored on 2009/10/02 00:56:35
Showing 3 changed files
... ...
@@ -176,7 +176,7 @@ struct macho_fat_arch
176 176
     if(DETECT_BROKEN) {					    \
177 177
 	if(ctx->virname)				    \
178 178
 	    *ctx->virname = "Broken.Executable";	    \
179
-	return cli_checkfp(fd, ctx) ? CL_CLEAN : CL_VIRUS;  \
179
+	return cli_checkfp(map->fd, ctx) ? CL_CLEAN : CL_VIRUS;  \
180 180
     }							    \
181 181
     return CL_EFORMAT
182 182
 
... ...
@@ -201,7 +201,7 @@ static uint32_t cli_rawaddr(uint32_t vaddr, struct cli_exe_section *sects, uint1
201 201
     return vaddr - sects[i].rva + sects[i].raw;
202 202
 }
203 203
 
204
-int cli_scanmacho(int fd, cli_ctx *ctx, struct cli_exe_info *fileinfo)
204
+int cli_scanmacho(cli_ctx *ctx, struct cli_exe_info *fileinfo)
205 205
 {
206 206
 	struct macho_hdr hdr;
207 207
 	struct macho_load_cmd load_cmd;
... ...
@@ -213,14 +213,17 @@ int cli_scanmacho(int fd, cli_ctx *ctx, struct cli_exe_info *fileinfo)
213 213
 	unsigned int arch = 0, ep = 0, err;
214 214
 	struct cli_exe_section *sections = NULL;
215 215
 	char name[16];
216
+	struct F_MAP *map = *ctx->fmap;
217
+	ssize_t at;
216 218
 
217 219
     if(fileinfo)
218 220
 	matcher = 1;
219 221
 
220
-    if(read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
222
+    if(fmap_readn(map, &hdr, 0, sizeof(hdr)) != sizeof(hdr)) {
221 223
 	cli_dbgmsg("cli_scanmacho: Can't read header\n");
222 224
 	return matcher ? -1 : CL_EFORMAT;
223 225
     }
226
+    at = sizeof(hdr);
224 227
 
225 228
     if(hdr.magic == 0xfeedface) {
226 229
 	conv = 0;
... ...
@@ -311,7 +314,7 @@ int cli_scanmacho(int fd, cli_ctx *ctx, struct cli_exe_info *fileinfo)
311 311
     }
312 312
 
313 313
     if(m64)
314
-	lseek(fd, 4, SEEK_CUR);
314
+	at += 4;
315 315
 
316 316
     hdr.ncmds = EC32(hdr.ncmds, conv);
317 317
     if(!hdr.ncmds || hdr.ncmds > 1024) {
... ...
@@ -320,11 +323,12 @@ int cli_scanmacho(int fd, cli_ctx *ctx, struct cli_exe_info *fileinfo)
320 320
     }
321 321
 
322 322
     for(i = 0; i < hdr.ncmds; i++) {
323
-	if(read(fd, &load_cmd, sizeof(load_cmd)) != sizeof(load_cmd)) {
323
+	if(fmap_readn(map, &load_cmd, at, sizeof(load_cmd)) != sizeof(load_cmd)) {
324 324
 	    cli_dbgmsg("cli_scanmacho: Can't read load command\n");
325 325
 	    free(sections);
326 326
 	    RETURN_BROKEN;
327 327
 	}
328
+	at += sizeof(load_cmd);
328 329
 	/*
329 330
 	if((m64 && EC32(load_cmd.cmdsize, conv) % 8) || (!m64 && EC32(load_cmd.cmdsize, conv) % 4)) {
330 331
 	    cli_dbgmsg("cli_scanmacho: Invalid command size (%u)\n", EC32(load_cmd.cmdsize, conv));
... ...
@@ -335,19 +339,21 @@ int cli_scanmacho(int fd, cli_ctx *ctx, struct cli_exe_info *fileinfo)
335 335
 	load_cmd.cmd = EC32(load_cmd.cmd, conv);
336 336
 	if((m64 && load_cmd.cmd == 0x19) || (!m64 && load_cmd.cmd == 0x01)) { /* LC_SEGMENT */
337 337
 	    if(m64) {
338
-		if(read(fd, &segment_cmd64, sizeof(segment_cmd64)) != sizeof(segment_cmd64)) {
338
+		if(fmap_readn(map, &segment_cmd64, at, sizeof(segment_cmd64)) != sizeof(segment_cmd64)) {
339 339
 		    cli_dbgmsg("cli_scanmacho: Can't read segment command\n");
340 340
 		    free(sections);
341 341
 		    RETURN_BROKEN;
342 342
 		}
343
+		at += sizeof(segment_cmd64);
343 344
 		nsects = EC32(segment_cmd64.nsects, conv);
344 345
 		strncpy(name, segment_cmd64.segname, 16);
345 346
 	    } else {
346
-		if(read(fd, &segment_cmd, sizeof(segment_cmd)) != sizeof(segment_cmd)) {
347
+		if(fmap_readn(map, &segment_cmd, at, sizeof(segment_cmd)) != sizeof(segment_cmd)) {
347 348
 		    cli_dbgmsg("cli_scanmacho: Can't read segment command\n");
348 349
 		    free(sections);
349 350
 		    RETURN_BROKEN;
350 351
 		}
352
+		at += sizeof(segment_cmd);
351 353
 		nsects = EC32(segment_cmd.nsects, conv);
352 354
 		strncpy(name, segment_cmd.segname, 16);
353 355
 	    }
... ...
@@ -374,11 +380,12 @@ int cli_scanmacho(int fd, cli_ctx *ctx, struct cli_exe_info *fileinfo)
374 374
 
375 375
 	    for(j = 0; j < nsects; j++) {
376 376
 		if(m64) {
377
-		    if(read(fd, &section64, sizeof(section64)) != sizeof(section64)) {
377
+		    if(fmap_readn(map, &section64, at, sizeof(section64)) != sizeof(section64)) {
378 378
 			cli_dbgmsg("cli_scanmacho: Can't read section\n");
379 379
 			free(sections);
380 380
 			RETURN_BROKEN;
381 381
 		    }
382
+		    at += sizeof(section64);
382 383
 		    sections[sect].rva = EC64(section64.addr, conv);
383 384
 		    sections[sect].vsz = EC64(section64.size, conv);
384 385
 		    sections[sect].raw = EC32(section64.offset, conv);
... ...
@@ -386,11 +393,12 @@ int cli_scanmacho(int fd, cli_ctx *ctx, struct cli_exe_info *fileinfo)
386 386
 		    sections[sect].rsz = sections[sect].vsz + (section64.align - (sections[sect].vsz % section64.align)) % section64.align; /* most likely we can assume it's the same as .vsz */
387 387
 		    strncpy(name, section64.sectname, 16);
388 388
 		} else {
389
-		    if(read(fd, &section, sizeof(section)) != sizeof(section)) {
389
+		    if(fmap_readn(map, &section, at, sizeof(section)) != sizeof(section)) {
390 390
 			cli_dbgmsg("cli_scanmacho: Can't read section\n");
391 391
 			free(sections);
392 392
 			RETURN_BROKEN;
393 393
 		    }
394
+		    at += sizeof(section);
394 395
 		    sections[sect].rva = EC32(section.addr, conv);
395 396
 		    sections[sect].vsz = EC32(section.size, conv);
396 397
 		    sections[sect].raw = EC32(section.offset, conv);
... ...
@@ -414,17 +422,18 @@ int cli_scanmacho(int fd, cli_ctx *ctx, struct cli_exe_info *fileinfo)
414 414
 		cli_dbgmsg("MACHO: ------------------\n");
415 415
 
416 416
 	} else if(arch && (load_cmd.cmd == 0x4 || load_cmd.cmd == 0x5)) { /* LC_(UNIX)THREAD */
417
-	    lseek(fd, 8, SEEK_CUR);
417
+	    at += 8;
418 418
 	    switch(arch) {
419 419
 		case 1: /* x86 */
420 420
 		{
421 421
 			struct macho_thread_state_x86 thread_state_x86;
422 422
 
423
-		    if(read(fd, &thread_state_x86, sizeof(thread_state_x86)) != sizeof(thread_state_x86)) {
423
+		    if(fmap_readn(map, &thread_state_x86, at, sizeof(thread_state_x86)) != sizeof(thread_state_x86)) {
424 424
 			cli_dbgmsg("cli_scanmacho: Can't read thread_state_x86\n");
425 425
 			free(sections);
426 426
 			RETURN_BROKEN;
427 427
 		    }
428
+		    at += sizeof(thread_state_x86);
428 429
 		    break;
429 430
 		}
430 431
 
... ...
@@ -432,11 +441,12 @@ int cli_scanmacho(int fd, cli_ctx *ctx, struct cli_exe_info *fileinfo)
432 432
 		{
433 433
 			struct macho_thread_state_ppc thread_state_ppc;
434 434
 
435
-		    if(read(fd, &thread_state_ppc, sizeof(thread_state_ppc)) != sizeof(thread_state_ppc)) {
435
+		    if(fmap_readn(map, &thread_state_ppc, at, sizeof(thread_state_ppc)) != sizeof(thread_state_ppc)) {
436 436
 			cli_dbgmsg("cli_scanmacho: Can't read thread_state_ppc\n");
437 437
 			free(sections);
438 438
 			RETURN_BROKEN;
439 439
 		    }
440
+		    at += sizeof(thread_state_ppc);
440 441
 		    ep = EC32(thread_state_ppc.srr0, conv);
441 442
 		    break;
442 443
 		}
... ...
@@ -445,11 +455,12 @@ int cli_scanmacho(int fd, cli_ctx *ctx, struct cli_exe_info *fileinfo)
445 445
 		{
446 446
 			struct macho_thread_state_ppc64 thread_state_ppc64;
447 447
 
448
-		    if(read(fd, &thread_state_ppc64, sizeof(thread_state_ppc64)) != sizeof(thread_state_ppc64)) {
448
+		    if(fmap_readn(map, &thread_state_ppc64, at, sizeof(thread_state_ppc64)) != sizeof(thread_state_ppc64)) {
449 449
 			cli_dbgmsg("cli_scanmacho: Can't read thread_state_ppc64\n");
450 450
 			free(sections);
451 451
 			RETURN_BROKEN;
452 452
 		    }
453
+		    at += sizeof(thread_state_ppc64);
453 454
 		    ep = EC64(thread_state_ppc64.srr0, conv);
454 455
 		    break;
455 456
 		}
... ...
@@ -460,7 +471,7 @@ int cli_scanmacho(int fd, cli_ctx *ctx, struct cli_exe_info *fileinfo)
460 460
 	    }
461 461
 	} else {
462 462
 	    if(EC32(load_cmd.cmdsize, conv) > sizeof(load_cmd))
463
-		lseek(fd, EC32(load_cmd.cmdsize, conv) - sizeof(load_cmd), SEEK_CUR);
463
+		at += EC32(load_cmd.cmdsize, conv) - sizeof(load_cmd);
464 464
 	}
465 465
     }
466 466
 
... ...
@@ -492,10 +503,12 @@ int cli_scanmacho(int fd, cli_ctx *ctx, struct cli_exe_info *fileinfo)
492 492
 
493 493
 int cli_machoheader(struct F_MAP *map, struct cli_exe_info *fileinfo)
494 494
 {
495
-    return cli_scanmacho(map->fd, NULL, fileinfo);
495
+    cli_ctx ctx;
496
+    ctx.fmap = &map;
497
+    return cli_scanmacho(&ctx, fileinfo);
496 498
 }
497 499
 
498
-int cli_scanmacho_unibin(int fd, cli_ctx *ctx)
500
+int cli_scanmacho_unibin(cli_ctx *ctx)
499 501
 {
500 502
 	struct macho_fat_header fat_header;
501 503
 	struct macho_fat_arch fat_arch;
... ...
@@ -503,16 +516,14 @@ int cli_scanmacho_unibin(int fd, cli_ctx *ctx)
503 503
 	int ret = CL_CLEAN;
504 504
 	struct stat sb;
505 505
 	off_t pos;
506
+	struct F_MAP *map = *ctx->fmap;
507
+	ssize_t at;
506 508
 
507
-    if(fstat(fd, &sb) == -1) {
508
-	cli_dbgmsg("cli_scanmacho_unibin: fstat failed for fd %d\n", fd);
509
-	return CL_ESTAT;
510
-    }
511
-
512
-    if(read(fd, &fat_header, sizeof(fat_header)) != sizeof(fat_header)) {
509
+    if(fmap_readn(map, &fat_header, 0, sizeof(fat_header)) != sizeof(fat_header)) {
513 510
 	cli_dbgmsg("cli_scanmacho_unibin: Can't read fat_header\n");
514 511
 	return CL_EFORMAT;
515 512
     }
513
+    at = sizeof(fat_header);
516 514
 
517 515
     if(fat_header.magic == 0xcafebabe) {
518 516
 	conv = 0;
... ...
@@ -533,18 +544,17 @@ int cli_scanmacho_unibin(int fd, cli_ctx *ctx)
533 533
     }
534 534
     cli_dbgmsg("UNIBIN: Number of architectures: %u\n", (unsigned int) fat_header.nfats);
535 535
     for(i = 0; i < fat_header.nfats; i++) {
536
-	if(read(fd, &fat_arch, sizeof(fat_arch)) != sizeof(fat_arch)) {
536
+	if(fmap_readn(map, &fat_arch, at, sizeof(fat_arch)) != sizeof(fat_arch)) {
537 537
 	    cli_dbgmsg("cli_scanmacho_unibin: Can't read fat_arch\n");
538 538
 	    RETURN_BROKEN;
539 539
 	}
540
-	pos = lseek(fd, 0, SEEK_CUR);
540
+	at += sizeof(fat_arch);
541 541
 	fat_arch.offset = EC32(fat_arch.offset, conv);
542 542
 	fat_arch.size = EC32(fat_arch.size, conv);
543 543
 	cli_dbgmsg("UNIBIN: Binary %u of %u\n", i + 1, fat_header.nfats);
544 544
 	cli_dbgmsg("UNIBIN: File offset: %u\n", fat_arch.offset);
545 545
 	cli_dbgmsg("UNIBIN: File size: %u\n", fat_arch.size);
546
-	ret = cli_dumpscan(fd, fat_arch.offset, fat_arch.size, ctx);
547
-	lseek(fd, pos, SEEK_SET);
546
+	ret = cli_dumpscan(map->fd, fat_arch.offset, fat_arch.size, ctx);
548 547
 	if(ret == CL_VIRUS)
549 548
 	    break;
550 549
     }
... ...
@@ -25,8 +25,8 @@
25 25
 #include "execs.h"
26 26
 #include "fmap.h"
27 27
 
28
-int cli_scanmacho(int fd, cli_ctx *ctx, struct cli_exe_info *fileinfo);
28
+int cli_scanmacho(cli_ctx *ctx, struct cli_exe_info *fileinfo);
29 29
 int cli_machoheader(struct F_MAP *map, struct cli_exe_info *fileinfo);
30
-int cli_scanmacho_unibin(int fd, cli_ctx *ctx);
30
+int cli_scanmacho_unibin(cli_ctx *ctx);
31 31
 
32 32
 #endif
... ...
@@ -2075,12 +2075,12 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
2075 2075
 
2076 2076
 	case CL_TYPE_MACHO:
2077 2077
 	    if(ctx->dconf->macho)
2078
-		ret = cli_scanmacho(desc, ctx, NULL);
2078
+		ret = cli_scanmacho(ctx, NULL);
2079 2079
 	    break;
2080 2080
 
2081 2081
 	case CL_TYPE_MACHO_UNIBIN:
2082 2082
 	    if(ctx->dconf->macho)
2083
-		ret = cli_scanmacho_unibin(desc, ctx);
2083
+		ret = cli_scanmacho_unibin(ctx);
2084 2084
 	    break;
2085 2085
 
2086 2086
 	case CL_TYPE_SIS: