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

aCaB acab at clamav.net
Sun Apr 4 01:11:20 UTC 2010


The following commit has been merged in the debian/unstable branch:
commit 1a1ee68a2aa3c973e36f2a930e088381492ef819
Author: aCaB <acab at clamav.net>
Date:   Thu Dec 10 03:10:58 2009 +0100

    bw matching

diff --git a/libclamav/pe_icons.c b/libclamav/pe_icons.c
index 8fcb134..11652e0 100644
--- a/libclamav/pe_icons.c
+++ b/libclamav/pe_icons.c
@@ -630,7 +630,7 @@ static uint32_t labdiff2(unsigned int b) {
      return ((uint32_t)(sqrt(ld/1024.0)))>>17;
 }
 
-#define DUMPMATCHING
+/* #define DUMPMATCHING */
 #ifdef DUMPMATCHING
 #define DUMPBMP
 #endif
@@ -689,6 +689,45 @@ static unsigned int matchpoint(unsigned int side, unsigned int *x1, unsigned int
     return match / 3;
 }
 
+static unsigned int matchbwpoint(unsigned int side, unsigned int *x1a, unsigned int *y1a, unsigned int *avg1a, unsigned int *x1b, unsigned int *y1b, unsigned int *avg1b, const unsigned int *x2a, const unsigned int *y2a, const unsigned int *avg2a, const unsigned int *x2b, const unsigned int *y2b, const unsigned int *avg2b) {
+    unsigned int i, j, best, match = 0, ksize = side / 4;
+    unsigned int x1[6], y1[6], avg1[6], x2[6], y2[6], avg2[6];
+
+    for(i=0; i<3; i++) {
+	x1[i] = x1a[i];
+	y1[i] = y1a[i];
+	avg1[i] = avg1a[i];
+	x2[i] = x2a[i];
+	y2[i] = y2a[i];
+	avg2[i] = avg2a[i];
+
+	x1[i+3] = x1b[i];
+	y1[i+3] = y1b[i];
+	avg1[i+3] = avg1b[i];
+	x2[i+3] = x2b[i];
+	y2[i+3] = y2b[i];
+	avg2[i+3] = avg2b[i];
+    }
+
+    for(i=0; i<6; i++) {
+	best = 0;
+	for(j=0; j<6; j++) {
+	    /* approximately measure the distance from the best matching reference - avoid N*N total war */
+	    int diffx = (int)x1[i] - (int)x2[j];
+	    int diffy = ((int)y1[i] - (int)y2[j]);
+	    unsigned int diff = sqrt(diffx*diffx + diffy*diffy);
+	    if(diff > ksize * 3 / 4 || (unsigned int)abs((int)avg1[i]-(int)avg2[j]) > 255 / 5)
+		continue;
+
+	    diff = 100 - diff * 60 / (ksize * 3 / 4);
+	    if(diff > best)
+		best = diff;
+	}
+	match += best;
+    }
+    return match / 6;
+}
+
 static void hsv(unsigned int c, unsigned int *r, unsigned int *g, unsigned int *b, unsigned int *s, unsigned int *v, unsigned int *delta) {
     unsigned int min, max;
     *r=(c>>16)&0xff;
@@ -706,17 +745,13 @@ static void hsv(unsigned int c, unsigned int *r, unsigned int *g, unsigned int *
 
 static int getmetrics(unsigned int side, unsigned int *imagedata, struct icomtr *res) {
     unsigned int x, y, xk, yk, i, j, *tmp;
-    unsigned int ksize = side / 4;
+    unsigned int ksize = side / 4, bwonly = 0;
+    unsigned int edge_avg[6], edge_x[6], edge_y[6], noedge_avg[6], noedge_x[6], noedge_y[6];
 
     if(!(tmp = cli_malloc(side*side*4*2)))
 	return CL_EMEM;
 
     memset(res, 0, sizeof(*res));
-    for(i=0; i<3; i++) {
-	res->gray_avg[i] = 0xffffffff;
-	res->dark_avg[i] = 0xffffffff;
-    }
-
 
     /* compute colored, gray, bright and dark areas, color presence */
     for(y=0; y<=side - ksize; y++) {
@@ -794,6 +829,8 @@ static int getmetrics(unsigned int side, unsigned int *imagedata, struct icomtr
 
     /* extract top 3 non overlapping areas for: colored, gray, bright and dark areas, color presence */
     for(i=0; i<3; i++) {
+	res->gray_avg[i] = 0xffffffff;
+	res->dark_avg[i] = 0xffffffff;
 	for(y=0; y<side - ksize; y++) {
 	    for(x=0; x<side-1 - ksize; x++) {
 		unsigned int colsum = tmp[y*side+x], lightsum = tmp[side*side + y*side+x];
@@ -854,19 +891,19 @@ static int getmetrics(unsigned int side, unsigned int *imagedata, struct icomtr
 	res->dark_avg[i] /= ksize*ksize;
     }
 
-    if(res->ccount) {
+    if(res->ccount * 100 / side / side > 5) {
 	res->rsum /= res->ccount;
 	res->gsum /= res->ccount;
 	res->bsum /= res->ccount;
 	res->ccount = res->ccount * 100 / side / side;
+    } else {
+	res->ccount = 0;
+	res->rsum = 0;
+	res->gsum = 0;
+	res->bsum = 0;
+	bwonly = 1;
     }
 
-    cli_dbgmsg("color areas: %u@(%u,%u) %u@(%u,%u) %u@(%u,%u)\n", res->color_avg[0], res->color_x[0], res->color_y[0], res->color_avg[1], res->color_x[1], res->color_y[1], res->color_avg[2], res->color_x[2], res->color_y[2]);
-    cli_dbgmsg("gray areas: %u@(%u,%u) %u@(%u,%u) %u@(%u,%u)\n", res->gray_avg[0], res->gray_x[0], res->gray_y[0], res->gray_avg[1], res->gray_x[1], res->gray_y[1], res->gray_avg[2], res->gray_x[2], res->gray_y[2]);
-    cli_dbgmsg("bright areas: %u@(%u,%u) %u@(%u,%u) %u@(%u,%u)\n", res->bright_avg[0], res->bright_x[0], res->bright_y[0], res->bright_avg[1], res->bright_x[1], res->bright_y[1], res->bright_avg[2], res->bright_x[2], res->bright_y[2]);
-    cli_dbgmsg("dark areas: %u@(%u,%u) %u@(%u,%u) %u@(%u,%u)\n", res->dark_avg[0], res->dark_x[0], res->dark_y[0], res->dark_avg[1], res->dark_x[1], res->dark_y[1], res->dark_avg[2], res->dark_x[2], res->dark_y[2]);
-    cli_dbgmsg("color spread: %u,%u,%u %u%%\n", res->rsum, res->gsum, res->bsum, res->ccount);
-
     /* Edge detection - Sobel */
 
     /* Sobel 1 - gradients */
@@ -975,9 +1012,6 @@ static int getmetrics(unsigned int side, unsigned int *imagedata, struct icomtr
     makebmp("4-gauss", side, side, imagedata);
 
 
-    for(i=0; i<3; i++)
-	res->noedge_avg[i] = 0xffffffff;
-
     /* calculate edges */
     for(y=0; y<=side - ksize; y++) {
 	for(x=0; x<=side-1 - ksize; x++) {
@@ -1005,32 +1039,34 @@ static int getmetrics(unsigned int side, unsigned int *imagedata, struct icomtr
 	}
     }
 
-    /* calculate best and worst 3 edged areas */
-    for(i=0; i<3; i++) {
+    /* calculate best and worst 3 (or 6) edged areas */
+    for(i=0; i<3 * (bwonly + 1); i++) {
+	edge_avg[i] = 0;
+	noedge_avg[i] = 0xffffffff;
 	for(y=0; y<side - ksize; y++) {
 	    for(x=0; x<side-1 - ksize; x++) {
 		unsigned int sum = tmp[y*side + x];
 
-		if(sum > res->edge_avg[i]) {
+		if(sum > edge_avg[i]) {
 		    for(j=0; j<i; j++) {
-			if(x + ksize > res->edge_x[j] && x < res->edge_x[j] + ksize &&
-			   y + ksize > res->edge_y[j] && y < res->edge_y[j] + ksize) break;
+			if(x + ksize > edge_x[j] && x < edge_x[j] + ksize &&
+			   y + ksize > edge_y[j] && y < edge_y[j] + ksize) break;
 		    }
 		    if(j==i) {
-			res->edge_avg[i] = sum;
-			res->edge_x[i] = x;
-			res->edge_y[i] = y;
+			edge_avg[i] = sum;
+			edge_x[i] = x;
+			edge_y[i] = y;
 		    }
 		}
-		if(sum < res->noedge_avg[i]) {
+		if(sum < noedge_avg[i]) {
 		    for(j=0; j<i; j++) {
-			if(x + ksize > res->noedge_x[j] && x < res->noedge_x[j] + ksize &&
-			   y + ksize > res->noedge_y[j] && y < res->noedge_y[j] + ksize) break;
+			if(x + ksize > noedge_x[j] && x < noedge_x[j] + ksize &&
+			   y + ksize > noedge_y[j] && y < noedge_y[j] + ksize) break;
 		    }
 		    if(j==i) {
-			res->noedge_avg[i] = sum;
-			res->noedge_x[i] = x;
-			res->noedge_y[i] = y;
+			noedge_avg[i] = sum;
+			noedge_x[i] = x;
+			noedge_y[i] = y;
 		    }
 		}
 	    }
@@ -1041,12 +1077,32 @@ static int getmetrics(unsigned int side, unsigned int *imagedata, struct icomtr
 
     /* abs->avg */
     for(i=0; i<3; i++) {
-	res->edge_avg[i] /= ksize*ksize;
-	res->noedge_avg[i] /= ksize*ksize;
+	res->edge_avg[i] = edge_avg[i] / ksize / ksize;
+	res->edge_x[i] = edge_x[i];
+	res->edge_y[i] = edge_y[i];
+	res->noedge_avg[i] = noedge_avg[i] / ksize / ksize;
+	res->noedge_x[i] = noedge_x[i];
+	res->noedge_y[i] = noedge_y[i];
+    }
+    if(bwonly) {
+	for(i=0; i<3; i++) {
+	    res->color_avg[i] = edge_avg[i+3] / ksize / ksize;
+	    res->color_x[i] = edge_x[i+3];
+	    res->color_y[i] = edge_y[i+3];
+	    res->gray_avg[i] = noedge_avg[i+3] / ksize / ksize;
+	    res->gray_x[i] = edge_x[i+3];
+	    res->gray_y[i] = edge_y[i+3];
+	}
     }
 
     cli_dbgmsg("edge areas: %u@(%u,%u) %u@(%u,%u) %u@(%u,%u)\n", res->edge_avg[0], res->edge_x[0], res->edge_y[0], res->edge_avg[1], res->edge_x[1], res->edge_y[1], res->edge_avg[2], res->edge_x[2], res->edge_y[2]);
     cli_dbgmsg("noedge areas: %u@(%u,%u) %u@(%u,%u) %u@(%u,%u)\n", res->noedge_avg[0], res->noedge_x[0], res->noedge_y[0], res->noedge_avg[1], res->noedge_x[1], res->noedge_y[1], res->noedge_avg[2], res->noedge_x[2], res->noedge_y[2]);
+    cli_dbgmsg("%s areas: %u@(%u,%u) %u@(%u,%u) %u@(%u,%u)\n", bwonly?"edge(2nd)":"color", res->color_avg[0], res->color_x[0], res->color_y[0], res->color_avg[1], res->color_x[1], res->color_y[1], res->color_avg[2], res->color_x[2], res->color_y[2]);
+    cli_dbgmsg("%s areas: %u@(%u,%u) %u@(%u,%u) %u@(%u,%u)\n", bwonly?"noedge":"gray", res->gray_avg[0], res->gray_x[0], res->gray_y[0], res->gray_avg[1], res->gray_x[1], res->gray_y[1], res->gray_avg[2], res->gray_x[2], res->gray_y[2]);
+    cli_dbgmsg("bright areas: %u@(%u,%u) %u@(%u,%u) %u@(%u,%u)\n", res->bright_avg[0], res->bright_x[0], res->bright_y[0], res->bright_avg[1], res->bright_x[1], res->bright_y[1], res->bright_avg[2], res->bright_x[2], res->bright_y[2]);
+    cli_dbgmsg("dark areas: %u@(%u,%u) %u@(%u,%u) %u@(%u,%u)\n", res->dark_avg[0], res->dark_x[0], res->dark_y[0], res->dark_avg[1], res->dark_x[1], res->dark_y[1], res->dark_avg[2], res->dark_x[2], res->dark_y[2]);
+    if(!bwonly)
+	cli_dbgmsg("color spread: %u,%u,%u %u%%\n", res->rsum, res->gsum, res->bsum, res->ccount);
 
 
     if(cli_debug_flag) {
@@ -1350,40 +1406,55 @@ static int parseicon(uint32_t rva, cli_ctx *ctx, struct cli_exe_section *exe_sec
 
     enginesize = (width >> 3) - 2;
     for(x=0; x<ctx->engine->icon_counts[enginesize]; x++) {
-	unsigned int color = matchpoint(width, metrics.color_x, metrics.color_y, metrics.color_avg, ctx->engine->icons[enginesize][x].color_x, ctx->engine->icons[enginesize][x].color_y, ctx->engine->icons[enginesize][x].color_avg, 4072);
-	unsigned int gray = matchpoint(width, metrics.gray_x, metrics.gray_y, metrics.gray_avg, ctx->engine->icons[enginesize][x].gray_x, ctx->engine->icons[enginesize][x].gray_y, ctx->engine->icons[enginesize][x].gray_avg, 4072);
-	unsigned int bright = matchpoint(width, metrics.bright_x, metrics.bright_y, metrics.bright_avg, ctx->engine->icons[enginesize][x].bright_x, ctx->engine->icons[enginesize][x].bright_y, ctx->engine->icons[enginesize][x].bright_avg, 255);
-	unsigned int dark = matchpoint(width, metrics.dark_x, metrics.dark_y, metrics.dark_avg, ctx->engine->icons[enginesize][x].dark_x, ctx->engine->icons[enginesize][x].dark_y, ctx->engine->icons[enginesize][x].dark_avg, 255);
-	unsigned int edge = matchpoint(width, metrics.edge_x, metrics.edge_y, metrics.edge_avg, ctx->engine->icons[enginesize][x].edge_x, ctx->engine->icons[enginesize][x].edge_y, ctx->engine->icons[enginesize][x].edge_avg, 255);
-	unsigned int noedge = matchpoint(width, metrics.noedge_x, metrics.noedge_y, metrics.noedge_avg, ctx->engine->icons[enginesize][x].noedge_x, ctx->engine->icons[enginesize][x].noedge_y, ctx->engine->icons[enginesize][x].noedge_avg, 255);
-	unsigned int reds = abs((int)metrics.rsum - (int)ctx->engine->icons[enginesize][x].rsum) * 10;
-	unsigned int greens = abs((int)metrics.gsum - (int)ctx->engine->icons[enginesize][x].gsum) * 10;
-	unsigned int blues = abs((int)metrics.bsum - (int)ctx->engine->icons[enginesize][x].bsum) * 10;
-	unsigned int ccount = abs((int)metrics.ccount - (int)ctx->engine->icons[enginesize][x].ccount) * 10;
-	unsigned int colors, confidence;
+	unsigned int color = 0, gray = 0, bright, dark, edge, noedge, reds, greens, blues, ccount;
+	unsigned int colors, confidence, bwmatch = 0, positivematch = 64 + 4*(2-enginesize);
+
+	if(!metrics.ccount && !ctx->engine->icons[enginesize][x].ccount) {
+	    /* BW matching */
+	    edge = matchbwpoint(width, metrics.edge_x, metrics.edge_y, metrics.edge_avg, metrics.color_x, metrics.color_y, metrics.color_avg, ctx->engine->icons[enginesize][x].edge_x, ctx->engine->icons[enginesize][x].edge_y, ctx->engine->icons[enginesize][x].edge_avg, ctx->engine->icons[enginesize][x].color_x, ctx->engine->icons[enginesize][x].color_y, ctx->engine->icons[enginesize][x].color_avg);
+	    noedge = matchbwpoint(width, metrics.noedge_x, metrics.noedge_y, metrics.noedge_avg, metrics.gray_x, metrics.gray_y, metrics.gray_avg, ctx->engine->icons[enginesize][x].noedge_x, ctx->engine->icons[enginesize][x].noedge_y, ctx->engine->icons[enginesize][x].noedge_avg, ctx->engine->icons[enginesize][x].gray_x, ctx->engine->icons[enginesize][x].gray_y, ctx->engine->icons[enginesize][x].gray_avg);
+	    bwmatch = 1;
+	} else {
+	    edge = matchpoint(width, metrics.edge_x, metrics.edge_y, metrics.edge_avg, ctx->engine->icons[enginesize][x].edge_x, ctx->engine->icons[enginesize][x].edge_y, ctx->engine->icons[enginesize][x].edge_avg, 255);
+	    noedge = matchpoint(width, metrics.noedge_x, metrics.noedge_y, metrics.noedge_avg, ctx->engine->icons[enginesize][x].noedge_x, ctx->engine->icons[enginesize][x].noedge_y, ctx->engine->icons[enginesize][x].noedge_avg, 255);
+	    if(metrics.ccount && ctx->engine->icons[enginesize][x].ccount) {
+		/* color matching */
+		color = matchpoint(width, metrics.color_x, metrics.color_y, metrics.color_avg, ctx->engine->icons[enginesize][x].color_x, ctx->engine->icons[enginesize][x].color_y, ctx->engine->icons[enginesize][x].color_avg, 4072);
+		gray = matchpoint(width, metrics.gray_x, metrics.gray_y, metrics.gray_avg, ctx->engine->icons[enginesize][x].gray_x, ctx->engine->icons[enginesize][x].gray_y, ctx->engine->icons[enginesize][x].gray_avg, 4072);
+	    }
+	}
+
+	bright = matchpoint(width, metrics.bright_x, metrics.bright_y, metrics.bright_avg, ctx->engine->icons[enginesize][x].bright_x, ctx->engine->icons[enginesize][x].bright_y, ctx->engine->icons[enginesize][x].bright_avg, 255);
+	dark = matchpoint(width, metrics.dark_x, metrics.dark_y, metrics.dark_avg, ctx->engine->icons[enginesize][x].dark_x, ctx->engine->icons[enginesize][x].dark_y, ctx->engine->icons[enginesize][x].dark_avg, 255);
 
+	reds = abs((int)metrics.rsum - (int)ctx->engine->icons[enginesize][x].rsum) * 10;
 	reds = (reds < 100) * (100 - reds);
+	greens = abs((int)metrics.gsum - (int)ctx->engine->icons[enginesize][x].gsum) * 10;
 	greens = (greens < 100) * (100 - greens);
+	blues = abs((int)metrics.bsum - (int)ctx->engine->icons[enginesize][x].bsum) * 10;
 	blues = (blues < 100) * (100 - blues);
+	ccount = abs((int)metrics.ccount - (int)ctx->engine->icons[enginesize][x].ccount) * 10;
 	ccount = (ccount < 100) * (100 - ccount);
 	colors = (reds + greens + blues + ccount) / 4;
 
-	if(metrics.ccount < 5 && ctx->engine->icons[enginesize][x].ccount < 5)
-	    confidence = ((bright + edge) * 3 / 2 +  dark + noedge) / 5;
-	else
+	if(bwmatch) {
+	    confidence = (bright + dark + edge * 2 + noedge) / 6;
+	    positivematch = 70;
+	} else
 	    confidence = (color + (gray + bright + noedge)*2/3 + dark + edge + colors) / 6;
 
-
-	cli_dbgmsg("color confidence: %u%%\n", color);
-	cli_dbgmsg("gray confidence: %u%%\n", gray);
-	cli_dbgmsg("bright confidence: %u%%\n", bright);
-	cli_dbgmsg("dark confidence: %u%%\n", dark);
 	cli_dbgmsg("edge confidence: %u%%\n", edge);
 	cli_dbgmsg("noedge confidence: %u%%\n", noedge);
-	cli_dbgmsg("spread confidence: red %u%%, green %u%%, blue %u%% - colors %u%%\n", reds, greens, blues, ccount);
-
+	if(!bwmatch) {
+	    cli_dbgmsg("color confidence: %u%%\n", color);
+	    cli_dbgmsg("gray confidence: %u%%\n", gray);
+	}
+	cli_dbgmsg("bright confidence: %u%%\n", bright);
+	cli_dbgmsg("dark confidence: %u%%\n", dark);
+	if(!bwmatch)
+	    cli_dbgmsg("spread confidence: red %u%%, green %u%%, blue %u%% - colors %u%%\n", reds, greens, blues, ccount);
 
-	if(confidence > 65) {
+	if(confidence >= positivematch) {
 	    char name[128];
 	    cli_warnmsg("confidence: %u\n", confidence);
 
@@ -1396,8 +1467,6 @@ static int parseicon(uint32_t rva, cli_ctx *ctx, struct cli_exe_section *exe_sec
 #endif
 	    return CL_VIRUS;
 	}
-
-	/* CURRENTLY >=60% IS A MATCH */
     }
 
 #ifdef DUMPMATCHING    
diff --git a/libclamav/readdb.c b/libclamav/readdb.c
index cf4d932..52c9a92 100644
--- a/libclamav/readdb.c
+++ b/libclamav/readdb.c
@@ -537,6 +537,9 @@ static int cli_loadidb(FILE *fs, struct cl_engine *engine, unsigned int *signo,
 
     while(cli_dbgets(buffer, FILEBUFF, fs, dbio)) {
 	line++;
+	if(buffer[0] == '#')
+	    continue;
+
 	cli_chomp(buffer);
 	if(engine->ignored)
 	    strcpy(buffer_cpy, buffer);

-- 
Debian repository for ClamAV



More information about the Pkg-clamav-commits mailing list