[Pkg-clamav-commits] [SCM] Debian repository for ClamAV branch, debian/unstable, updated. debian/0.95+dfsg-1-6156-g094ec9b

Tomasz Kojm tkojm at clamav.net
Sun Apr 4 00:58:30 UTC 2010


The following commit has been merged in the debian/unstable branch:
commit 8af7ccd0af1d3402e3559b9b8deba3b4eab6ec1b
Author: Tomasz Kojm <tkojm at clamav.net>
Date:   Mon Jul 13 21:29:46 2009 +0200

    libclamav: handle Mach-O files with type-9 signatures;
    all special offsets are supported for PPC32/64 and x86 executables; for ARM and other archs only section based extensions (Sx[+-]n, SL[+-]n) are supported atm

diff --git a/ChangeLog b/ChangeLog
index 4c6af1a..88f45a5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Mon Jul 13 21:24:05 CEST 2009 (tk)
+----------------------------------
+ * libclamav: handle Mach-O files with type-9 signatures; all special offsets are
+	      supported for PPC32/64 and x86 executables; for ARM and other archs
+	      only section based extensions (Sx[+-]n, SL[+-]n) are supported atm
+
 Mon Jul 13 19:34:36 EEST 2009 (edwin)
 -------------------------------------
  * clambc/, libclamav/, unit_tests/: Initial draft of bytecode interpreter (bb #1243).
diff --git a/libclamav/macho.c b/libclamav/macho.c
index c1a0cb4..f07e15f 100644
--- a/libclamav/macho.c
+++ b/libclamav/macho.c
@@ -18,10 +18,6 @@
  *  MA 02110-1301, USA.
  */
 
-/* TODO:
- *  - integrate with the matcher
- */
-
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
@@ -158,6 +154,8 @@ struct macho_thread_state_x86
 };
 
 #define RETURN_BROKEN					    \
+    if(matcher)						    \
+	return -1;					    \
     if(DETECT_BROKEN) {					    \
 	if(ctx->virname)				    \
 	    *ctx->virname = "Broken.Executable";	    \
@@ -186,7 +184,7 @@ static uint32_t cli_rawaddr(uint32_t vaddr, struct cli_exe_section *sects, uint1
     return vaddr - sects[i].rva + sects[i].raw;
 }
 
-int cli_scanmacho(int fd, cli_ctx *ctx)
+int cli_scanmacho(int fd, cli_ctx *ctx, struct cli_exe_info *fileinfo)
 {
 	struct macho_hdr hdr;
 	struct macho_load_cmd load_cmd;
@@ -194,14 +192,17 @@ int cli_scanmacho(int fd, cli_ctx *ctx)
 	struct macho_segment_cmd64 segment_cmd64;
 	struct macho_section section;
 	struct macho_section64 section64;
-	unsigned int i, j, sect = 0, conv, m64, nsects;
+	unsigned int i, j, sect = 0, conv, m64, nsects, matcher = 0;
 	unsigned int arch = 0, ep = 0, err;
 	struct cli_exe_section *sections = NULL;
 	char name[16];
 
+    if(fileinfo)
+	matcher = 1;
+
     if(read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
 	cli_dbgmsg("cli_scanmacho: Can't read header\n");
-	return CL_EFORMAT;
+	return matcher ? -1 : CL_EFORMAT;
     }
 
     if(hdr.magic == 0xfeedface) {
@@ -218,37 +219,44 @@ int cli_scanmacho(int fd, cli_ctx *ctx)
 	m64 = 1;
     } else {
 	cli_dbgmsg("cli_scanmacho: Incorrect magic\n");
-	return CL_EFORMAT;
+	return matcher ? -1 : CL_EFORMAT;
     }
 
     switch(EC32(hdr.cpu_type, conv)) {
 	case 7:
-	    cli_dbgmsg("MACHO: CPU Type: Intel 32-bit\n");
+	    if(!matcher)
+		cli_dbgmsg("MACHO: CPU Type: Intel 32-bit\n");
 	    arch = 1;
 	    break;
 	case 7 | 0x1000000:
-	    cli_dbgmsg("MACHO: CPU Type: Intel 64-bit\n");
+	    if(!matcher)
+		cli_dbgmsg("MACHO: CPU Type: Intel 64-bit\n");
 	    break;
 	case 12:
-	    cli_dbgmsg("MACHO: CPU Type: ARM\n");
+	    if(!matcher)
+		cli_dbgmsg("MACHO: CPU Type: ARM\n");
 	    break;
 	case 14:
-	    cli_dbgmsg("MACHO: CPU Type: SPARC\n");
+	    if(!matcher)
+		cli_dbgmsg("MACHO: CPU Type: SPARC\n");
 	    break;
 	case 18:
-	    cli_dbgmsg("MACHO: CPU Type: POWERPC 32-bit\n");
+	    if(!matcher)
+		cli_dbgmsg("MACHO: CPU Type: POWERPC 32-bit\n");
 	    arch = 2;
 	    break;
 	case 18 | 0x1000000:
-	    cli_dbgmsg("MACHO: CPU Type: POWERPC 64-bit\n");
+	    if(!matcher)
+		cli_dbgmsg("MACHO: CPU Type: POWERPC 64-bit\n");
 	    arch = 3;
 	    break;
 	default:
-	    cli_dbgmsg("MACHO: CPU Type: ** UNKNOWN ** (%u)\n", EC32(hdr.cpu_type, conv));
+	    if(!matcher)
+		cli_dbgmsg("MACHO: CPU Type: ** UNKNOWN ** (%u)\n", EC32(hdr.cpu_type, conv));
 	    break;
     }
 
-    switch(EC32(hdr.filetype, conv)) {
+    if(!matcher) switch(EC32(hdr.filetype, conv)) {
 	case 0x1: /* MH_OBJECT */
 	    cli_dbgmsg("MACHO: Filetype: Relocatable object file\n");
 	    break;
@@ -280,8 +288,10 @@ int cli_scanmacho(int fd, cli_ctx *ctx)
 	    cli_dbgmsg("MACHO: Filetype: ** UNKNOWN ** (0x%x)\n", EC32(hdr.filetype, conv));
     }
 
-    cli_dbgmsg("MACHO: Number of load commands: %u\n", EC32(hdr.ncmds, conv));
-    cli_dbgmsg("MACHO: Size of load commands: %u\n", EC32(hdr.sizeofcmds, conv));
+    if(!matcher) {
+	cli_dbgmsg("MACHO: Number of load commands: %u\n", EC32(hdr.ncmds, conv));
+	cli_dbgmsg("MACHO: Size of load commands: %u\n", EC32(hdr.sizeofcmds, conv));
+    }
 
     if(m64)
 	lseek(fd, 4, SEEK_CUR);
@@ -324,22 +334,25 @@ int cli_scanmacho(int fd, cli_ctx *ctx)
 		nsects = EC32(segment_cmd.nsects, conv);
 		strncpy(name, segment_cmd.segname, 16);
 	    }
-	    name[15] = 0;
-	    cli_dbgmsg("MACHO: Segment name: %s\n", name);
-	    cli_dbgmsg("MACHO: Number of sections: %u\n", nsects);
+	    if(!matcher) {
+		name[15] = 0;
+		cli_dbgmsg("MACHO: Segment name: %s\n", name);
+		cli_dbgmsg("MACHO: Number of sections: %u\n", nsects);
+	    }
 	    if(nsects > 255) {
 		cli_dbgmsg("cli_scanmacho: Invalid number of sections\n");
 		free(sections);
 		RETURN_BROKEN;
 	    }
 	    if(!nsects) {
-		cli_dbgmsg("MACHO: ------------------\n");
+		if(!matcher)
+		    cli_dbgmsg("MACHO: ------------------\n");
 		continue;
 	    }
 	    sections = (struct cli_exe_section *) cli_realloc2(sections, (sect + nsects) * sizeof(struct cli_exe_section));
 	    if(!sections) {
 		cli_errmsg("cli_scanmacho: Can't allocate memory for 'sections'\n");
-		return CL_EMEM;
+		return matcher ? -1 : CL_EMEM;
 	    }
 
 	    for(j = 0; j < nsects; j++) {
@@ -364,21 +377,24 @@ int cli_scanmacho(int fd, cli_ctx *ctx)
 		    sections[sect].rva = EC32(section.addr, conv);
 		    sections[sect].vsz = EC32(section.size, conv);
 		    sections[sect].raw = EC32(section.offset, conv);
-		    section64.align = EC32(section64.align, conv);
-		    sections[sect].rsz = sections[sect].vsz + (section64.align - (sections[sect].vsz % section64.align)) % section64.align;
+		    section.align = EC32(section.align, conv);
+		    sections[sect].rsz = sections[sect].vsz + (section.align - (sections[sect].vsz % section.align)) % section.align;
 		    strncpy(name, section.sectname, 16);
 		}
-		name[15] = 0;
-		cli_dbgmsg("MACHO: --- Section %u ---\n", sect);
-		cli_dbgmsg("MACHO: Name: %s\n", name);
-		cli_dbgmsg("MACHO: Virtual address: 0x%x\n", (unsigned int) sections[sect].rva);
-		cli_dbgmsg("MACHO: Virtual size: %u\n", (unsigned int) sections[sect].vsz);
-		cli_dbgmsg("MACHO: Raw size: %u\n", (unsigned int) sections[sect].rsz);
-		if(sections[sect].raw)
-		    cli_dbgmsg("MACHO: File offset: %u\n", (unsigned int) sections[sect].raw);
+		if(!matcher) {
+		    name[15] = 0;
+		    cli_dbgmsg("MACHO: --- Section %u ---\n", sect);
+		    cli_dbgmsg("MACHO: Name: %s\n", name);
+		    cli_dbgmsg("MACHO: Virtual address: 0x%x\n", (unsigned int) sections[sect].rva);
+		    cli_dbgmsg("MACHO: Virtual size: %u\n", (unsigned int) sections[sect].vsz);
+		    cli_dbgmsg("MACHO: Raw size: %u\n", (unsigned int) sections[sect].rsz);
+		    if(sections[sect].raw)
+			cli_dbgmsg("MACHO: File offset: %u\n", (unsigned int) sections[sect].raw);
+		}
 		sect++;
 	    }
-	    cli_dbgmsg("MACHO: ------------------\n");
+	    if(!matcher)
+		cli_dbgmsg("MACHO: ------------------\n");
 
 	} else if(arch && (load_cmd.cmd == 0x4 || load_cmd.cmd == 0x5)) { /* LC_(UNIX)THREAD */
 	    lseek(fd, 8, SEEK_CUR);
@@ -423,7 +439,7 @@ int cli_scanmacho(int fd, cli_ctx *ctx)
 		default:
 		    cli_errmsg("cli_scanmacho: Invalid arch setting!\n");
 		    free(sections);
-		    return CL_EARG;
+		    return matcher ? -1 : CL_EARG;
 	    }
 	} else {
 	    if(EC32(load_cmd.cmdsize, conv) > sizeof(load_cmd))
@@ -432,18 +448,32 @@ int cli_scanmacho(int fd, cli_ctx *ctx)
     }
 
     if(ep) {
-	cli_dbgmsg("Entry Point: 0x%x (%u)\n", ep, ep);
+	if(!matcher)
+	    cli_dbgmsg("Entry Point: 0x%x\n", ep);
 	if(sections) {
 	    ep = cli_rawaddr(ep, sections, sect, &err);
 	    if(err) {
 		cli_dbgmsg("cli_scanmacho: Can't calculate EP offset\n");
 		free(sections);
-		return CL_EFORMAT;
+		return matcher ? -1 : CL_EFORMAT;
 	    }
-	    cli_dbgmsg("Entry Point file offset: %u\n", ep);
+	    if(!matcher)
+		cli_dbgmsg("Entry Point file offset: %u\n", ep);
 	}
     }
 
-    free(sections);
-    return CL_SUCCESS;
+    if(matcher) {
+	fileinfo->ep = ep;
+	fileinfo->nsections = sect;
+	fileinfo->section = sections;
+	return 0;
+    } else {
+	free(sections);
+	return CL_SUCCESS;
+    }
+}
+
+int cli_machoheader(int fd, struct cli_exe_info *fileinfo)
+{
+    return cli_scanmacho(fd, NULL, fileinfo);
 }
diff --git a/libclamav/macho.h b/libclamav/macho.h
index c8553d0..bce0de8 100644
--- a/libclamav/macho.h
+++ b/libclamav/macho.h
@@ -24,7 +24,7 @@
 #include "others.h"
 #include "execs.h"
 
-int cli_scanmacho(int fd, cli_ctx *ctx);
-int cli_machoheader(int fd, struct cli_exe_info *elfinfo);
+int cli_scanmacho(int fd, cli_ctx *ctx, struct cli_exe_info *fileinfo);
+int cli_machoheader(int fd, struct cli_exe_info *fileinfo);
 
 #endif
diff --git a/libclamav/matcher.c b/libclamav/matcher.c
index d12e6cc..dd2008d 100644
--- a/libclamav/matcher.c
+++ b/libclamav/matcher.c
@@ -44,7 +44,7 @@
 #include "str.h"
 #include "cltypes.h"
 #include "default.h"
-
+#include "macho.h"
 
 int cli_scanbuff(const unsigned char *buffer, uint32_t length, uint32_t offset, cli_ctx *ctx, cli_file_t ftype, struct cli_ac_data **acdata)
 {
@@ -131,6 +131,8 @@ off_t cli_caloff(const char *offstr, struct cli_target_info *info, int fd, cli_f
 		einfo = cli_peheader;
 	    else if(ftype == CL_TYPE_ELF)
 		einfo = cli_elfheader;
+	    else if(ftype == CL_TYPE_MACHO)
+		einfo = cli_machoheader;
 
 	    if(einfo) {
 		if((pos = lseek(fd, 0, SEEK_CUR)) == -1) {
diff --git a/libclamav/matcher.h b/libclamav/matcher.h
index 70d8a39..0069cb1 100644
--- a/libclamav/matcher.h
+++ b/libclamav/matcher.h
@@ -104,7 +104,7 @@ struct cli_mtarget {
     uint8_t ac_only;
 };
 
-#define CLI_MTARGETS 9
+#define CLI_MTARGETS 10
 static const struct cli_mtarget cli_mtargets[CLI_MTARGETS] =  {
     { 0,		    "GENERIC",	    0,	0   },
     { CL_TYPE_MSEXE,	    "PE",	    1,	0   },
@@ -114,7 +114,8 @@ static const struct cli_mtarget cli_mtargets[CLI_MTARGETS] =  {
     { CL_TYPE_GRAPHICS,	    "GRAPHICS",	    5,	1   },
     { CL_TYPE_ELF,	    "ELF",	    6,	1   },
     { CL_TYPE_TEXT_ASCII,   "ASCII",	    7,	1   },
-    { CL_TYPE_PE_DISASM,    "DISASM",	    8,	1   }
+    { CL_TYPE_PE_DISASM,    "DISASM",	    8,	1   },
+    { CL_TYPE_MACHO,	    "MACH-O",	    9,	1   }
 };
 
 struct cli_target_info {
diff --git a/libclamav/readdb.c b/libclamav/readdb.c
index 4602511..5ac1457 100644
--- a/libclamav/readdb.c
+++ b/libclamav/readdb.c
@@ -532,7 +532,7 @@ static int cli_checkoffset(const char *offset, unsigned int type)
     if(!strncmp(offset, "EOF-", 4))
 	return 0;
 
-    if((type == 1 || type == 6) && (!strncmp(offset, "EP+", 3) || !strncmp(offset, "EP-", 3) || (sscanf(offset, "SL+%u", &foo) == 1) || (sscanf(offset, "S%u+%u", &foo, &foo) == 2)))
+    if((type == 1 || type == 6 || type == 9) && (!strncmp(offset, "EP+", 3) || !strncmp(offset, "EP-", 3) || (sscanf(offset, "SL+%u", &foo) == 1) || (sscanf(offset, "S%u+%u", &foo, &foo) == 2)))
 	return 0;
 
     return 1;
diff --git a/libclamav/scanners.c b/libclamav/scanners.c
index 0222e52..4741ef7 100644
--- a/libclamav/scanners.c
+++ b/libclamav/scanners.c
@@ -2087,7 +2087,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
 
 	case CL_TYPE_MACHO:
 	    if(ctx->dconf->macho)
-		ret = cli_scanmacho(desc, ctx);
+		ret = cli_scanmacho(desc, ctx, NULL);
 	    break;
 
 	case CL_TYPE_SIS:

-- 
Debian repository for ClamAV



More information about the Pkg-clamav-commits mailing list