Browse code

load idb

aCaB authored on 2009/12/08 02:54:09
Showing 5 changed files
... ...
@@ -114,7 +114,6 @@ typedef struct {
114 114
 } cli_ctx;
115 115
 
116 116
 struct icomtr {
117
-    unsigned int size;
118 117
     unsigned int color_avg[3];
119 118
     unsigned int color_x[3];
120 119
     unsigned int color_y[3];
... ...
@@ -205,7 +204,8 @@ struct cl_engine {
205 205
     char *pua_cats;
206 206
 
207 207
     /* Icon reference storage */
208
-    struct icomtr *icons;
208
+    struct icomtr *icons[3];
209
+    unsigned int icon_counts[3];
209 210
 
210 211
     /* Used for memory pools */
211 212
     mpool_t *mempool;
... ...
@@ -37,82 +37,6 @@
37 37
 #define LABDIFF(x) labdiff2(x)
38 38
 #endif
39 39
 
40
-static const struct icomtr reference[3] = {
41
-    {
42
-	/* 32x32x32 */
43
-	32,
44
-	{ 2923, 2746, 945 }, /* col avg */
45
-	{ 13, 0, 17 }, /* col x */
46
-	{ 3, 3, 15 }, /* col y */
47
-	{ 0, 0, 0 }, /* gray avg */
48
-	{ 22, 22, 0 }, /* gray x */
49
-	{ 0, 8, 12 }, /* gray y */
50
-	{ 255, 255, 251 }, /* bright avg */
51
-	{ 0, 0, 10 }, /* bright x */
52
-	{ 13, 21, 16 }, /* bright y */
53
-	{ 158, 184, 205 }, /* dark avg */
54
-	{ 17, 16, 0 }, /* dark x */
55
-	{ 23, 4, 5 }, /* dark y */
56
-	{ 105, 94, 73 }, /* edge avg */
57
-	{ 15, 5, 15 }, /* edge x */
58
-	{ 2, 2, 21 }, /* edge y */
59
-	{ 2, 2, 13 }, /* noedge avg */
60
-	{ 0, 0, 21 }, /* noedge x */
61
-	{ 23, 15, 12 }, /* noedge y */
62
-	99, 0, 0, 20,
63
-	"PDF.ICON.32x32"
64
-    },
65
-    {
66
-	/* 24x24x32 */
67
-	24,
68
-	{ 2940, 2722, 904 }, /* col avg */
69
-	{ 10, 1, 11 }, /* col x */
70
-	{ 2, 2, 11 }, /* col y */
71
-	{ 0, 0, 0 }, /* gray avg */
72
-	{ 0, 6, 16 }, /* gray x */
73
-	{ 9, 9, 9 }, /* gray y */
74
-	{ 252, 251, 251 }, /* bright avg */
75
-	{ 6, 0, 10 }, /* bright x */
76
-	{ 17, 10, 16 }, /* bright y */
77
-	{ 183, 184, 210 }, /* dark avg */
78
-	{ 13, 11, 1 }, /* dark x */
79
-	{ 16, 3, 4 }, /* dark y */
80
-	{ 137, 127, 76 }, /* edge avg */
81
-	{ 11, 1, 13 }, /* edge x */
82
-	{ 2, 3, 16 }, /* edge y */
83
-	{ 6, 14, 14 }, /* noedge avg */
84
-	{ 0, 6, 16 }, /* noedge x */
85
-	{ 15, 11, 9 }, /* noedge y */
86
-	99, 0, 0, 22,
87
-	"PDF.ICON.24x24"
88
-    },
89
-    {
90
-	/* 16x16x32 */
91
-	16,
92
-	{ 3403, 3347, 1567 }, /* col avg */
93
-	{ 0, 4, 8 }, /* col x */
94
-	{ 2, 2, 2 }, /* col y */
95
-	{ 0, 0, 0 }, /* gray avg */
96
-	{ 10, 10, 0 }, /* gray x */
97
-	{ 0, 4, 6 }, /* gray y */
98
-	{ 253, 253, 249 }, /* bright avg */
99
-	{ 4, 10, 6 }, /* bright x */
100
-	{ 11, 11, 7 }, /* bright y */
101
-	{ 163, 190, 235 }, /* dark avg */
102
-	{ 7, 3, 3 }, /* dark x */
103
-	{ 2, 2, 6 }, /* dark y */
104
-	{ 124, 111, 69 }, /* edge avg */
105
-	{ 7, 3, 2 }, /* edge x */
106
-	{ 1, 1, 5 }, /* edge y */
107
-	{ 17, 20, 26 }, /* noedge avg */
108
-	{ 9, 0, 4 }, /* noedge x */
109
-	{ 11, 9, 8 }, /* noedge y */
110
-	100, 0, 0, 20,
111
-	"PDF.ICON.16x16"
112
-    }
113
-
114
-};
115
-
116 40
 struct GICONS {
117 41
     unsigned int cnt;
118 42
     uint32_t lastg;
... ...
@@ -1119,6 +1043,49 @@ static int getmetrics(unsigned int side, unsigned int *imagedata, struct icomtr
1119 1119
     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]);
1120 1120
     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]);
1121 1121
 
1122
+
1123
+    if(cli_debug_flag) {
1124
+#define ICOSIGSZ (2 + (3 + 2 + 2) * 3 * 2 + (2 + 2 + 2) * 3 * 4 + 2 + 2 + 2 + 2)
1125
+	char mstr[ICOSIGSZ + 1], *ptr = mstr;
1126
+
1127
+	sprintf(ptr, "%02x", side); ptr+=2;
1128
+	for(i=0; i<3; i++) {
1129
+	    sprintf(ptr, "%03x", res->color_avg[i]); ptr+=3;
1130
+	    sprintf(ptr, "%02x", res->color_x[i]); ptr+=2;
1131
+	    sprintf(ptr, "%02x", res->color_y[i]); ptr+=2;
1132
+	}
1133
+	for(i=0; i<3; i++) {
1134
+	    sprintf(ptr, "%03x", res->gray_avg[i]); ptr+=3;
1135
+	    sprintf(ptr, "%02x", res->gray_x[i]); ptr+=2;
1136
+	    sprintf(ptr, "%02x", res->gray_y[i]); ptr+=2;
1137
+	}
1138
+	for(i=0; i<3; i++) {
1139
+	    sprintf(ptr, "%02x", res->bright_avg[i]); ptr+=2;
1140
+	    sprintf(ptr, "%02x", res->bright_x[i]); ptr+=2;
1141
+	    sprintf(ptr, "%02x", res->bright_y[i]); ptr+=2;
1142
+	}
1143
+	for(i=0; i<3; i++) {
1144
+	    sprintf(ptr, "%02x", res->dark_avg[i]); ptr+=2;
1145
+	    sprintf(ptr, "%02x", res->dark_x[i]); ptr+=2;
1146
+	    sprintf(ptr, "%02x", res->dark_y[i]); ptr+=2;
1147
+	}
1148
+	for(i=0; i<3; i++) {
1149
+	    sprintf(ptr, "%02x", res->edge_avg[i]); ptr+=2;
1150
+	    sprintf(ptr, "%02x", res->edge_x[i]); ptr+=2;
1151
+	    sprintf(ptr, "%02x", res->edge_y[i]); ptr+=2;
1152
+	}
1153
+	for(i=0; i<3; i++) {
1154
+	    sprintf(ptr, "%02x", res->noedge_avg[i]); ptr+=2;
1155
+	    sprintf(ptr, "%02x", res->noedge_x[i]); ptr+=2;
1156
+	    sprintf(ptr, "%02x", res->noedge_y[i]); ptr+=2;
1157
+	}
1158
+	sprintf(ptr, "%02x", res->rsum); ptr+=2;
1159
+	sprintf(ptr, "%02x", res->gsum); ptr+=2;
1160
+	sprintf(ptr, "%02x", res->bsum);
1161
+	cli_dbgmsg("ICO SIGNATURE: ICON.NAME:%s\n", mstr);
1162
+
1163
+    }
1164
+
1122 1165
     return CL_CLEAN;
1123 1166
 }
1124 1167
 
... ...
@@ -1142,7 +1109,7 @@ static int parseicon(uint32_t rva, cli_ctx *ctx, struct cli_exe_section *exe_sec
1142 1142
     uint32_t *palette = NULL, *imagedata;
1143 1143
     unsigned int scanlinesz, andlinesz;
1144 1144
     unsigned int width, height, depth, x, y;
1145
-    unsigned int err, scalemode = 2;
1145
+    unsigned int err, scalemode = 2, enginesize;
1146 1146
     fmap_t *map = *ctx->fmap;
1147 1147
     uint32_t icoff = cli_rawaddr(rva, exe_sections, nsections, &err, map->len, hdr_size);
1148 1148
 
... ...
@@ -1370,49 +1337,49 @@ static int parseicon(uint32_t rva, cli_ctx *ctx, struct cli_exe_section *exe_sec
1370 1370
 
1371 1371
 
1372 1372
     getmetrics(width, imagedata, &metrics);
1373
-    for(x=0; x<sizeof(reference) / sizeof(reference[0]); x++) {
1374
-	if(reference[x].size == width) {
1375
-	    unsigned int color = matchpoint(width, metrics.color_x, metrics.color_y, metrics.color_avg, reference[x].color_x, reference[x].color_y, reference[x].color_avg, 4072);
1376
-	    unsigned int gray = matchpoint(width, metrics.gray_x, metrics.gray_y, metrics.gray_avg, reference[x].gray_x, reference[x].gray_y, reference[x].gray_avg, 4072);
1377
-	    unsigned int bright = matchpoint(width, metrics.bright_x, metrics.bright_y, metrics.bright_avg, reference[x].bright_x, reference[x].bright_y, reference[x].bright_avg, 255);
1378
-	    unsigned int dark = matchpoint(width, metrics.dark_x, metrics.dark_y, metrics.dark_avg, reference[x].dark_x, reference[x].dark_y, reference[x].dark_avg, 255);
1379
-	    unsigned int edge = matchpoint(width, metrics.edge_x, metrics.edge_y, metrics.edge_avg, reference[x].edge_x, reference[x].edge_y, reference[x].edge_avg, 255);
1380
-	    unsigned int noedge = matchpoint(width, metrics.noedge_x, metrics.noedge_y, metrics.noedge_avg, reference[x].noedge_x, reference[x].noedge_y, reference[x].noedge_avg, 255);
1381
-	    unsigned int reds = abs((int)metrics.rsum - (int)reference[x].rsum) * 10;
1382
-	    unsigned int greens = abs((int)metrics.gsum - (int)reference[x].gsum) * 10;
1383
-	    unsigned int blues = abs((int)metrics.bsum - (int)reference[x].bsum) * 10;
1384
-	    unsigned int ccount = abs((int)metrics.ccount - (int)reference[x].ccount) * 10;
1385
-	    unsigned int colors, used = 6, confidence;
1386
-
1387
-	    reds = (reds < 100) * (100 - reds);
1388
-	    greens = (greens < 100) * (100 - greens);
1389
-	    blues = (blues < 100) * (100 - blues);
1390
-	    ccount = (ccount < 100) * (100 - ccount);
1391
-	    colors = (reds + greens + blues + ccount) / 4;
1392
-
1393
-	    if(!metrics.ccount && !reference[x].ccount) {
1394
-		colors = 0;
1395
-		used--;
1396
-	    }
1397 1373
 
1398
-	    cli_dbgmsg("color confidence: %u%%\n", color);
1399
-	    cli_dbgmsg("gray confidence: %u%%\n", gray);
1400
-	    cli_dbgmsg("bright confidence: %u%%\n", bright);
1401
-	    cli_dbgmsg("dark confidence: %u%%\n", dark);
1402
-	    cli_dbgmsg("edge confidence: %u%%\n", edge);
1403
-	    cli_dbgmsg("noedge confidence: %u%%\n", noedge);
1404
-	    cli_dbgmsg("spread confidence: red %u%%, green %u%%, blue %u%% - colors %u%%\n", reds, greens, blues, ccount);
1405
-
1406
-	    confidence = (color + gray*2/3 + bright*2/3 + dark + edge + noedge*2/3 + colors) / used;
1407
-	    if(confidence > 65) {
1408
-		cli_warnmsg("confidence: %u\n", confidence);
1409
-		if(ctx->virname) 
1410
-		    *ctx->virname = reference[x].name;
1411
-		return CL_VIRUS;
1412
-	    }
1374
+    enginesize = (width >> 3) - 2;
1375
+    for(x=0; x<ctx->engine->icon_counts[enginesize]; x++) {
1376
+	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);
1377
+	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);
1378
+	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);
1379
+	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);
1380
+	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);
1381
+	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);
1382
+	unsigned int reds = abs((int)metrics.rsum - (int)ctx->engine->icons[enginesize][x].rsum) * 10;
1383
+	unsigned int greens = abs((int)metrics.gsum - (int)ctx->engine->icons[enginesize][x].gsum) * 10;
1384
+	unsigned int blues = abs((int)metrics.bsum - (int)ctx->engine->icons[enginesize][x].bsum) * 10;
1385
+	unsigned int ccount = abs((int)metrics.ccount - (int)ctx->engine->icons[enginesize][x].ccount) * 10;
1386
+	unsigned int colors, used = 6, confidence;
1387
+
1388
+	reds = (reds < 100) * (100 - reds);
1389
+	greens = (greens < 100) * (100 - greens);
1390
+	blues = (blues < 100) * (100 - blues);
1391
+	ccount = (ccount < 100) * (100 - ccount);
1392
+	colors = (reds + greens + blues + ccount) / 4;
1393
+
1394
+	if(!metrics.ccount && !ctx->engine->icons[enginesize][x].ccount) {
1395
+	    colors = 0;
1396
+	    used--;
1397
+	}
1413 1398
 
1414
-	    /* CURRENTLY >=60% IS A MATCH */
1399
+	cli_dbgmsg("color confidence: %u%%\n", color);
1400
+	cli_dbgmsg("gray confidence: %u%%\n", gray);
1401
+	cli_dbgmsg("bright confidence: %u%%\n", bright);
1402
+	cli_dbgmsg("dark confidence: %u%%\n", dark);
1403
+	cli_dbgmsg("edge confidence: %u%%\n", edge);
1404
+	cli_dbgmsg("noedge confidence: %u%%\n", noedge);
1405
+	cli_dbgmsg("spread confidence: red %u%%, green %u%%, blue %u%% - colors %u%%\n", reds, greens, blues, ccount);
1406
+
1407
+	confidence = (color + gray*2/3 + bright*2/3 + dark + edge + noedge*2/3 + colors) / used;
1408
+	if(confidence > 65) {
1409
+	    cli_warnmsg("confidence: %u\n", confidence);
1410
+	    if(ctx->virname) 
1411
+		*ctx->virname = ctx->engine->icons[enginesize][x].name;
1412
+	    return CL_VIRUS;
1415 1413
 	}
1414
+
1415
+	/* CURRENTLY >=60% IS A MATCH */
1416 1416
     }
1417 1417
     
1418 1418
     free(imagedata);
... ...
@@ -521,52 +521,186 @@ static int cli_loaddb(FILE *fs, struct cl_engine *engine, unsigned int *signo, u
521 521
     return CL_SUCCESS;
522 522
 }
523 523
 
524
-#define ICO_TOKENS 9
525
-/* static int cli_loadico(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int mode, unsigned int options, struct cli_dbio *dbio, const char *dbname) */
526
-/* { */
527
-/* 	const char *tokens[ICO_TOKENS + 1]; */
528
-/* 	char buffer[FILEBUFF], *buffer_cpy; */
529
-/* 	const char *pt; */
530
-/* 	int ret = CL_SUCCESS; */
531
-/* 	unsigned int size_field = 1, md5_field = 0, line = 0, sigs = 0, tokens_count; */
532
-
533
-
534
-/*     if(engine->ignored) */
535
-/* 	if(!(buffer_cpy = cli_malloc(FILEBUFF))) */
536
-/* 	    return CL_EMEM; */
537
-
538
-/*     while(cli_dbgets(buffer, FILEBUFF, fs, dbio)) { */
539
-/* 	line++; */
540
-/* 	cli_chomp(buffer); */
541
-/* 	if(engine->ignored) */
542
-/* 	    strcpy(buffer_cpy, buffer); */
543
-
544
-/* 	tokens_count = cli_strtokenize(buffer, ':', ICO_TOKENS + 1, tokens); */
545
-/* 	if(tokens_count != ICO_TOKENS) { */
546
-/* 	    ret = CL_EMALFDB; */
547
-/* 	    break; */
548
-/* 	} */
549
-
550
-/* 	sigs++; */
551
-/*     } */
552
-/*     if(engine->ignored) */
553
-/* 	free(buffer_cpy); */
554
-
555
-/*     if(!line) { */
556
-/* 	cli_errmsg("cli_loadmd5: Empty database file\n"); */
557
-/* 	return CL_EMALFDB; */
558
-/*     } */
559
-
560
-/*     if(ret) { */
561
-/* 	cli_errmsg("cli_loadmd5: Problem parsing database at line %u\n", line); */
562
-/* 	return ret; */
563
-/*     } */
564
-
565
-/*     if(signo) */
566
-/* 	*signo += sigs; */
567
-
568
-/*     return CL_SUCCESS; */
569
-/* } */
524
+#define ICO_TOKENS 2
525
+static int cli_loadidb(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int options, struct cli_dbio *dbio, const char *dbname)
526
+{
527
+        const char *tokens[ICO_TOKENS + 1];
528
+	char buffer[FILEBUFF], *buffer_cpy;
529
+	uint8_t *pt, *hash;
530
+	int ret = CL_SUCCESS;
531
+	unsigned int line = 0, sigs = 0, tokens_count, i, size;
532
+	struct icomtr *metric;
533
+
534
+    if(engine->ignored)
535
+	if(!(buffer_cpy = cli_malloc(FILEBUFF)))
536
+	    return CL_EMEM;
537
+
538
+    while(cli_dbgets(buffer, FILEBUFF, fs, dbio)) {
539
+	line++;
540
+	cli_chomp(buffer);
541
+	if(engine->ignored)
542
+	    strcpy(buffer_cpy, buffer);
543
+
544
+	tokens_count = cli_strtokenize(buffer, ':', ICO_TOKENS + 1, tokens);
545
+	if(tokens_count != ICO_TOKENS) {
546
+	    ret = CL_EMALFDB;
547
+	    break;
548
+	}
549
+
550
+	if(strlen(tokens[1]) != 122) {
551
+	    ret = CL_EMALFDB;
552
+	    break;
553
+	}
554
+
555
+	if(engine->ignored && cli_chkign(engine->ignored, tokens[0], buffer_cpy))
556
+	    continue;
557
+
558
+	hash = tokens[1];
559
+	if(cli_hexnibbles(hash, 122)) {
560
+	    cli_errmsg("cli_loadidb: Malformed hash at line %u (bad chars)\n", line);
561
+	    ret = CL_EMALFDB;
562
+	    break;
563
+	}
564
+	size = (hash[0] << 4) + hash[1];
565
+	if(size != 32 && size != 24 && size != 16) {
566
+	    cli_errmsg("cli_loadidb: Malformed hash at line %u (bad size)\n", line);
567
+	    ret = CL_EMALFDB;
568
+	    break;
569
+	}
570
+	size = (size >> 3) - 2;
571
+	hash+=2;
572
+
573
+	metric = (struct icomtr *) mpool_realloc(engine->mempool, engine->icons[size], sizeof(struct icomtr) * (engine->icon_counts[size] + 1));
574
+	if(!metric) {
575
+	    ret = CL_EMEM;
576
+	    break;
577
+	}
578
+
579
+	engine->icons[size] = metric;
580
+	metric += engine->icon_counts[size];
581
+	engine->icon_counts[size]++;
582
+
583
+	for(i=0; i<3; i++) {
584
+	    if((metric->color_avg[i] = (hash[0] << 8) | (hash[1] << 4) | hash[2]) > 4072)
585
+		break;
586
+	    if((metric->color_x[i] = (hash[3] << 4) | hash[4]) > size - size / 8)
587
+		break;
588
+	    if((metric->color_y[i] = (hash[5] << 4) | hash[6]) > size - size / 8)
589
+		break;
590
+	    hash += 7;
591
+	}
592
+	if(i!=3) {
593
+	    cli_errmsg("cli_loadidb: Malformed hash at line %u (bad color data)\n", line);
594
+	    ret = CL_EMALFDB;
595
+	    break;
596
+	}
597
+
598
+	for(i=0; i<3; i++) {
599
+	    if((metric->gray_avg[i] = (hash[0] << 8) | (hash[1] << 4) | hash[2]) > 4072)
600
+		break;
601
+	    if((metric->gray_x[i] = (hash[3] << 4) | hash[4]) > size - size / 8)
602
+		break;
603
+	    if((metric->gray_y[i] = (hash[5] << 4) | hash[6]) > size - size / 8)
604
+		break;
605
+	    hash += 7;
606
+	}
607
+	if(i!=3) {
608
+	    cli_errmsg("cli_loadidb: Malformed hash at line %u (bad gray data)\n", line);
609
+	    ret = CL_EMALFDB;
610
+	    break;
611
+	}
612
+
613
+	for(i=0; i<3; i++) {
614
+	    metric->bright_avg[i] = (hash[0] << 4) | hash[1];
615
+	    if((metric->bright_x[i] = (hash[2] << 4) | hash[3]) > size - size / 8)
616
+		break;
617
+	    if((metric->bright_y[i] = (hash[6] << 4) | hash[5]) > size - size / 8)
618
+		break;
619
+	    hash += 6;
620
+	}
621
+	if(i!=3) {
622
+	    cli_errmsg("cli_loadidb: Malformed hash at line %u (bad bright data)\n", line);
623
+	    ret = CL_EMALFDB;
624
+	    break;
625
+	}
626
+
627
+	for(i=0; i<3; i++) {
628
+	    metric->dark_avg[i] = (hash[0] << 4) | hash[1];
629
+	    if((metric->dark_x[i] = (hash[2] << 4) | hash[3]) > size - size / 8)
630
+		break;
631
+	    if((metric->dark_y[i] = (hash[6] << 4) | hash[5]) > size - size / 8)
632
+		break;
633
+	    hash += 6;
634
+	}
635
+	if(i!=3) {
636
+	    cli_errmsg("cli_loadidb: Malformed hash at line %u (bad dark data)\n", line);
637
+	    ret = CL_EMALFDB;
638
+	    break;
639
+	}
640
+
641
+	for(i=0; i<3; i++) {
642
+	    metric->edge_avg[i] = (hash[0] << 4) | hash[1];
643
+	    if((metric->edge_x[i] = (hash[2] << 4) | hash[3]) > size - size / 8)
644
+		break;
645
+	    if((metric->edge_y[i] = (hash[6] << 4) | hash[5]) > size - size / 8)
646
+		break;
647
+	    hash += 6;
648
+	}
649
+	if(i!=3) {
650
+	    cli_errmsg("cli_loadidb: Malformed hash at line %u (bad edge data)\n", line);
651
+	    ret = CL_EMALFDB;
652
+	    break;
653
+	}
654
+
655
+	for(i=0; i<3; i++) {
656
+	    metric->noedge_avg[i] = (hash[0] << 4) | hash[1];
657
+	    if((metric->noedge_x[i] = (hash[2] << 4) | hash[3]) > size - size / 8)
658
+		break;
659
+	    if((metric->noedge_y[i] = (hash[6] << 4) | hash[5]) > size - size / 8)
660
+		break;
661
+	    hash += 6;
662
+	}
663
+	if(i!=3) {
664
+	    cli_errmsg("cli_loadidb: Malformed hash at line %u (bad noedge data)\n", line);
665
+	    ret = CL_EMALFDB;
666
+	    break;
667
+	}
668
+
669
+	metric->rsum = (hash[0] << 4) | hash[1];
670
+	metric->gsum = (hash[2] << 4) | hash[3];
671
+	metric->bsum = (hash[4] << 4) | hash[5];
672
+	metric->ccount = (hash[6] << 4) | hash[7];
673
+	if(metric->rsum + metric->gsum + metric->bsum > 100 || metric->ccount > 100) {
674
+	    cli_errmsg("cli_loadidb: Malformed hash at line %u (bad spread data)\n", line);
675
+	    ret = CL_EMALFDB;
676
+	    break;
677
+	}
678
+
679
+	if(!(metric->name = cli_mpool_strdup(engine->mempool, tokens[0]))) {
680
+	    ret = CL_EMEM;
681
+	    break;
682
+	}
683
+
684
+	sigs++;
685
+    }
686
+    if(engine->ignored)
687
+	free(buffer_cpy);
688
+
689
+    if(!line) {
690
+	cli_errmsg("cli_loadmd5: Empty database file\n");
691
+	return CL_EMALFDB;
692
+    }
693
+
694
+    if(ret) {
695
+	cli_errmsg("cli_loadmd5: Problem parsing database at line %u\n", line);
696
+	return ret;
697
+    }
698
+
699
+    if(signo)
700
+	*signo += sigs;
701
+
702
+    return CL_SUCCESS;
703
+}
570 704
 
571 705
 static int cli_loadwdb(FILE *fs, struct cl_engine *engine, unsigned int options, struct cli_dbio *dbio)
572 706
 {
... ...
@@ -582,3 +582,13 @@ int cli_textbuffer_append_normalize(struct text_buffer *buf, const char *str, si
582 582
 	return 0;
583 583
 }
584 584
 
585
+int cli_hexnibbles(char *str, int len)
586
+{
587
+    int i;
588
+    for(i=0; i<len; i++) {
589
+	int c = cli_hex2int(str[i]);
590
+	if(c<0) return 1;
591
+	str[i] = c;
592
+    }
593
+    return 0;
594
+}
... ...
@@ -49,5 +49,6 @@ int cli_isnumber(const char *str);
49 49
 char *cli_unescape(const char *str);
50 50
 struct text_buffer;
51 51
 int  cli_textbuffer_append_normalize(struct text_buffer *buf, const char *str, size_t len);
52
+int cli_hexnibbles(char *str, int len);
52 53
 
53 54
 #endif