... | ... |
@@ -114,6 +114,7 @@ typedef struct { |
114 | 114 |
} cli_ctx; |
115 | 115 |
|
116 | 116 |
struct icomtr { |
117 |
+ uint32_t group[2]; |
|
117 | 118 |
unsigned int color_avg[3]; |
118 | 119 |
unsigned int color_x[3]; |
119 | 120 |
unsigned int color_y[3]; |
... | ... |
@@ -139,6 +140,13 @@ struct icomtr { |
139 | 139 |
char *name; |
140 | 140 |
}; |
141 | 141 |
|
142 |
+struct icon_matcher { |
|
143 |
+ char **group_names[2]; |
|
144 |
+ unsigned int group_counts[2]; |
|
145 |
+ struct icomtr *icons[3]; |
|
146 |
+ unsigned int icon_counts[3]; |
|
147 |
+}; |
|
148 |
+ |
|
142 | 149 |
struct cl_engine { |
143 | 150 |
uint32_t refcount; /* reference counter */ |
144 | 151 |
uint32_t sdb; |
... | ... |
@@ -204,8 +212,7 @@ struct cl_engine { |
204 | 204 |
char *pua_cats; |
205 | 205 |
|
206 | 206 |
/* Icon reference storage */ |
207 |
- struct icomtr *icons[3]; |
|
208 |
- unsigned int icon_counts[3]; |
|
207 |
+ struct icon_matcher *iconcheck; |
|
209 | 208 |
|
210 | 209 |
/* Used for memory pools */ |
211 | 210 |
mpool_t *mempool; |
... | ... |
@@ -471,7 +471,7 @@ static void cli_parseres_special(uint32_t base, uint32_t rva, fmap_t *map, struc |
471 | 471 |
fmap_unneed_ptr(map, oentry, entries*8); |
472 | 472 |
} |
473 | 473 |
|
474 |
-int cli_scanpe(cli_ctx *ctx) |
|
474 |
+int cli_scanpe(cli_ctx *ctx, unsigned int *icongrps1, unsigned int *icongrps2) |
|
475 | 475 |
{ |
476 | 476 |
uint16_t e_magic; /* DOS signature ("MZ") */ |
477 | 477 |
uint16_t nsections; |
... | ... |
@@ -1042,11 +1042,13 @@ int cli_scanpe(cli_ctx *ctx) |
1042 | 1042 |
|
1043 | 1043 |
cli_dbgmsg("EntryPoint offset: 0x%x (%d)\n", ep, ep); |
1044 | 1044 |
|
1045 |
- if(!dll && dirs[2].Size) { /* RES */ |
|
1046 |
- if(scanicon(EC32(dirs[2].VirtualAddress), ctx, exe_sections, nsections, hdr_size) == CL_VIRUS) { |
|
1047 |
- free(exe_sections); |
|
1048 |
- return CL_VIRUS; |
|
1049 |
- } |
|
1045 |
+ if(icongrps1 || icongrps2){ |
|
1046 |
+ if(!dll && dirs[2].Size && scanicon(icongrps1, icongrps2, EC32(dirs[2].VirtualAddress), ctx, exe_sections, nsections, hdr_size) == CL_VIRUS) { |
|
1047 |
+ free(exe_sections); |
|
1048 |
+ return CL_VIRUS; |
|
1049 |
+ } |
|
1050 |
+ free(exe_sections); |
|
1051 |
+ return CL_CLEAN; |
|
1050 | 1052 |
} |
1051 | 1053 |
|
1052 | 1054 |
if(pe_plus) { /* Do not continue for PE32+ files */ |
... | ... |
@@ -129,7 +129,7 @@ struct pe_image_section_hdr { |
129 | 129 |
uint32_t Characteristics; |
130 | 130 |
}; |
131 | 131 |
|
132 |
-int cli_scanpe(cli_ctx *ctx); |
|
132 |
+int cli_scanpe(cli_ctx *ctx, unsigned int *icongrp1, unsigned int *icongrp2); |
|
133 | 133 |
|
134 | 134 |
int cli_peheader(fmap_t *map, struct cli_exe_info *peinfo); |
135 | 135 |
|
... | ... |
@@ -74,9 +74,9 @@ static int icon_cb(void *ptr, uint32_t type, uint32_t name, uint32_t lang, uint3 |
74 | 74 |
} |
75 | 75 |
|
76 | 76 |
|
77 |
-static int parseicon(uint32_t rva, cli_ctx *ctx, struct cli_exe_section *exe_sections, uint16_t nsections, uint32_t hdr_size); |
|
77 |
+static int parseicon(unsigned int *grp1, unsigned int *grp2, uint32_t rva, cli_ctx *ctx, struct cli_exe_section *exe_sections, uint16_t nsections, uint32_t hdr_size); |
|
78 | 78 |
|
79 |
-int scanicon(uint32_t resdir_rva, cli_ctx *ctx, struct cli_exe_section *exe_sections, uint16_t nsections, uint32_t hdr_size) { |
|
79 |
+int scanicon(unsigned int *grp1, unsigned int *grp2, uint32_t resdir_rva, cli_ctx *ctx, struct cli_exe_section *exe_sections, uint16_t nsections, uint32_t hdr_size) { |
|
80 | 80 |
struct GICONS gicons; |
81 | 81 |
struct ICONS icons; |
82 | 82 |
unsigned int curicon, err; |
... | ... |
@@ -122,7 +122,7 @@ int scanicon(uint32_t resdir_rva, cli_ctx *ctx, struct cli_exe_section *exe_sect |
122 | 122 |
} |
123 | 123 |
|
124 | 124 |
for(curicon=0; curicon<icons.cnt; curicon++) { |
125 |
- if(parseicon(icons.rvas[curicon], ctx, exe_sections, nsections, hdr_size) == CL_VIRUS) |
|
125 |
+ if(parseicon(grp1, grp2, icons.rvas[curicon], ctx, exe_sections, nsections, hdr_size) == CL_VIRUS) |
|
126 | 126 |
return CL_VIRUS; |
127 | 127 |
} |
128 | 128 |
return 0; |
... | ... |
@@ -747,6 +747,7 @@ static int getmetrics(unsigned int side, unsigned int *imagedata, struct icomtr |
747 | 747 |
unsigned int x, y, xk, yk, i, j, *tmp; |
748 | 748 |
unsigned int ksize = side / 4, bwonly = 0; |
749 | 749 |
unsigned int edge_avg[6], edge_x[6], edge_y[6], noedge_avg[6], noedge_x[6], noedge_y[6]; |
750 |
+ double *sobel; |
|
750 | 751 |
|
751 | 752 |
if(!(tmp = cli_malloc(side*side*4*2))) |
752 | 753 |
return CL_EMEM; |
... | ... |
@@ -909,13 +910,13 @@ static int getmetrics(unsigned int side, unsigned int *imagedata, struct icomtr |
909 | 909 |
/* Sobel 1 - gradients */ |
910 | 910 |
i = 0; |
911 | 911 |
#ifdef USE_FLOATS |
912 |
- double *sobel = cli_malloc(side * side * sizeof(double)); |
|
912 |
+ sobel = cli_malloc(side * side * sizeof(double)); |
|
913 | 913 |
if(!sobel) { |
914 | 914 |
free(tmp); |
915 | 915 |
return CL_EMEM; |
916 | 916 |
} |
917 | 917 |
#else |
918 |
- unsigned int *sobel = imagedata; |
|
918 |
+#define sobel imagedata |
|
919 | 919 |
#endif |
920 | 920 |
for(y=0; y<side; y++) { |
921 | 921 |
for(x=0; x<side; x++) { |
... | ... |
@@ -1098,7 +1099,7 @@ static int getmetrics(unsigned int side, unsigned int *imagedata, struct icomtr |
1098 | 1098 |
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]); |
1099 | 1099 |
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]); |
1100 | 1100 |
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]); |
1101 |
- 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]); |
|
1101 |
+ cli_dbgmsg("%s areas: %u@(%u,%u) %u@(%u,%u) %u@(%u,%u)\n", bwonly?"noedge(2nd)":"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]); |
|
1102 | 1102 |
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]); |
1103 | 1103 |
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]); |
1104 | 1104 |
if(!bwonly) |
... | ... |
@@ -1152,7 +1153,7 @@ static int getmetrics(unsigned int side, unsigned int *imagedata, struct icomtr |
1152 | 1152 |
} |
1153 | 1153 |
|
1154 | 1154 |
|
1155 |
-static int parseicon(uint32_t rva, cli_ctx *ctx, struct cli_exe_section *exe_sections, uint16_t nsections, uint32_t hdr_size) { |
|
1155 |
+static int parseicon(unsigned int *grp1, unsigned int *grp2, uint32_t rva, cli_ctx *ctx, struct cli_exe_section *exe_sections, uint16_t nsections, uint32_t hdr_size) { |
|
1156 | 1156 |
struct { |
1157 | 1157 |
unsigned int sz; |
1158 | 1158 |
unsigned int w; |
... | ... |
@@ -1174,6 +1175,10 @@ static int parseicon(uint32_t rva, cli_ctx *ctx, struct cli_exe_section *exe_sec |
1174 | 1174 |
unsigned int err, scalemode = 2, enginesize; |
1175 | 1175 |
fmap_t *map = *ctx->fmap; |
1176 | 1176 |
uint32_t icoff = cli_rawaddr(rva, exe_sections, nsections, &err, map->len, hdr_size); |
1177 |
+ struct icon_matcher *matcher; |
|
1178 |
+ |
|
1179 |
+ if(!ctx || !ctx->engine || !(matcher=ctx->engine->iconcheck)) |
|
1180 |
+ return CL_SUCCESS; |
|
1177 | 1181 |
|
1178 | 1182 |
/* read the bitmap header */ |
1179 | 1183 |
if(err || !(imagedata = fmap_need_off_once(map, icoff, 4))) { |
... | ... |
@@ -1405,35 +1410,49 @@ static int parseicon(uint32_t rva, cli_ctx *ctx, struct cli_exe_section *exe_sec |
1405 | 1405 |
free(imagedata); |
1406 | 1406 |
|
1407 | 1407 |
enginesize = (width >> 3) - 2; |
1408 |
- for(x=0; x<ctx->engine->icon_counts[enginesize]; x++) { |
|
1408 |
+ for(x=0; x<matcher->icon_counts[enginesize]; x++) { |
|
1409 | 1409 |
unsigned int color = 0, gray = 0, bright, dark, edge, noedge, reds, greens, blues, ccount; |
1410 | 1410 |
unsigned int colors, confidence, bwmatch = 0, positivematch = 64 + 4*(2-enginesize); |
1411 |
+ unsigned int i, j; |
|
1411 | 1412 |
|
1412 |
- if(!metrics.ccount && !ctx->engine->icons[enginesize][x].ccount) { |
|
1413 |
+ if(grp1) { |
|
1414 |
+ unsigned int *g1 = grp1; |
|
1415 |
+ while(*g1 && *g1 != matcher->icons[enginesize][x].group[0]+1) |
|
1416 |
+ g1++; |
|
1417 |
+ if(!*g1) continue; |
|
1418 |
+ } |
|
1419 |
+ if(grp2) { |
|
1420 |
+ unsigned int *g2 = grp2; |
|
1421 |
+ while(*g2 && *g2 != matcher->icons[enginesize][x].group[1]+1) |
|
1422 |
+ g2++; |
|
1423 |
+ if(!*g2) continue; |
|
1424 |
+ } |
|
1425 |
+ |
|
1426 |
+ if(!metrics.ccount && !matcher->icons[enginesize][x].ccount) { |
|
1413 | 1427 |
/* BW matching */ |
1414 |
- 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); |
|
1415 |
- 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); |
|
1428 |
+ edge = matchbwpoint(width, metrics.edge_x, metrics.edge_y, metrics.edge_avg, metrics.color_x, metrics.color_y, metrics.color_avg, matcher->icons[enginesize][x].edge_x, matcher->icons[enginesize][x].edge_y, matcher->icons[enginesize][x].edge_avg, matcher->icons[enginesize][x].color_x, matcher->icons[enginesize][x].color_y, matcher->icons[enginesize][x].color_avg); |
|
1429 |
+ noedge = matchbwpoint(width, metrics.noedge_x, metrics.noedge_y, metrics.noedge_avg, metrics.gray_x, metrics.gray_y, metrics.gray_avg, matcher->icons[enginesize][x].noedge_x, matcher->icons[enginesize][x].noedge_y, matcher->icons[enginesize][x].noedge_avg, matcher->icons[enginesize][x].gray_x, matcher->icons[enginesize][x].gray_y, matcher->icons[enginesize][x].gray_avg); |
|
1416 | 1430 |
bwmatch = 1; |
1417 | 1431 |
} else { |
1418 |
- 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); |
|
1419 |
- 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); |
|
1420 |
- if(metrics.ccount && ctx->engine->icons[enginesize][x].ccount) { |
|
1432 |
+ edge = matchpoint(width, metrics.edge_x, metrics.edge_y, metrics.edge_avg, matcher->icons[enginesize][x].edge_x, matcher->icons[enginesize][x].edge_y, matcher->icons[enginesize][x].edge_avg, 255); |
|
1433 |
+ noedge = matchpoint(width, metrics.noedge_x, metrics.noedge_y, metrics.noedge_avg, matcher->icons[enginesize][x].noedge_x, matcher->icons[enginesize][x].noedge_y, matcher->icons[enginesize][x].noedge_avg, 255); |
|
1434 |
+ if(metrics.ccount && matcher->icons[enginesize][x].ccount) { |
|
1421 | 1435 |
/* color matching */ |
1422 |
- 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); |
|
1423 |
- 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); |
|
1436 |
+ color = matchpoint(width, metrics.color_x, metrics.color_y, metrics.color_avg, matcher->icons[enginesize][x].color_x, matcher->icons[enginesize][x].color_y, matcher->icons[enginesize][x].color_avg, 4072); |
|
1437 |
+ gray = matchpoint(width, metrics.gray_x, metrics.gray_y, metrics.gray_avg, matcher->icons[enginesize][x].gray_x, matcher->icons[enginesize][x].gray_y, matcher->icons[enginesize][x].gray_avg, 4072); |
|
1424 | 1438 |
} |
1425 | 1439 |
} |
1426 | 1440 |
|
1427 |
- 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); |
|
1428 |
- 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); |
|
1441 |
+ bright = matchpoint(width, metrics.bright_x, metrics.bright_y, metrics.bright_avg, matcher->icons[enginesize][x].bright_x, matcher->icons[enginesize][x].bright_y, matcher->icons[enginesize][x].bright_avg, 255); |
|
1442 |
+ dark = matchpoint(width, metrics.dark_x, metrics.dark_y, metrics.dark_avg, matcher->icons[enginesize][x].dark_x, matcher->icons[enginesize][x].dark_y, matcher->icons[enginesize][x].dark_avg, 255); |
|
1429 | 1443 |
|
1430 |
- reds = abs((int)metrics.rsum - (int)ctx->engine->icons[enginesize][x].rsum) * 10; |
|
1444 |
+ reds = abs((int)metrics.rsum - (int)matcher->icons[enginesize][x].rsum) * 10; |
|
1431 | 1445 |
reds = (reds < 100) * (100 - reds); |
1432 |
- greens = abs((int)metrics.gsum - (int)ctx->engine->icons[enginesize][x].gsum) * 10; |
|
1446 |
+ greens = abs((int)metrics.gsum - (int)matcher->icons[enginesize][x].gsum) * 10; |
|
1433 | 1447 |
greens = (greens < 100) * (100 - greens); |
1434 |
- blues = abs((int)metrics.bsum - (int)ctx->engine->icons[enginesize][x].bsum) * 10; |
|
1448 |
+ blues = abs((int)metrics.bsum - (int)matcher->icons[enginesize][x].bsum) * 10; |
|
1435 | 1449 |
blues = (blues < 100) * (100 - blues); |
1436 |
- ccount = abs((int)metrics.ccount - (int)ctx->engine->icons[enginesize][x].ccount) * 10; |
|
1450 |
+ ccount = abs((int)metrics.ccount - (int)matcher->icons[enginesize][x].ccount) * 10; |
|
1437 | 1451 |
ccount = (ccount < 100) * (100 - ccount); |
1438 | 1452 |
colors = (reds + greens + blues + ccount) / 4; |
1439 | 1453 |
|
... | ... |
@@ -1459,7 +1478,7 @@ static int parseicon(uint32_t rva, cli_ctx *ctx, struct cli_exe_section *exe_sec |
1459 | 1459 |
cli_warnmsg("confidence: %u\n", confidence); |
1460 | 1460 |
|
1461 | 1461 |
if(ctx->virname) |
1462 |
- *ctx->virname = ctx->engine->icons[enginesize][x].name; |
|
1462 |
+ *ctx->virname = matcher->icons[enginesize][x].name; |
|
1463 | 1463 |
#ifdef DUMPMATCHING |
1464 | 1464 |
snprintf(name, sizeof(name), "match-%s-%u%%", *ctx->virname, confidence); |
1465 | 1465 |
makebmp(name, width, height, imagedata2); |
... | ... |
@@ -1474,3 +1493,25 @@ static int parseicon(uint32_t rva, cli_ctx *ctx, struct cli_exe_section *exe_sec |
1474 | 1474 |
#endif |
1475 | 1475 |
return CL_SUCCESS; |
1476 | 1476 |
} |
1477 |
+ |
|
1478 |
+ |
|
1479 |
+int cli_match_icon(cli_ctx *ctx, unsigned int *icongrp1, unsigned int *icongrp2) { |
|
1480 |
+ if(!ctx || !ctx->engine || !ctx->engine->iconcheck || !ctx->engine->iconcheck->group_counts[0] || !ctx->engine->iconcheck->group_counts[1]) |
|
1481 |
+ return CL_CLEAN; |
|
1482 |
+ return cli_scanpe(ctx, icongrp1, icongrp2); |
|
1483 |
+} |
|
1484 |
+ |
|
1485 |
+int cli_icon_getgroup(const char *group, unsigned int type, cli_ctx *ctx) { |
|
1486 |
+ struct icon_matcher *matcher; |
|
1487 |
+ unsigned int i; |
|
1488 |
+ |
|
1489 |
+ if(type>1 || !ctx || !ctx->engine || !ctx->engine->iconcheck || !ctx->engine->iconcheck->group_counts[type]) |
|
1490 |
+ return 0; |
|
1491 |
+ |
|
1492 |
+ matcher = ctx->engine->iconcheck; |
|
1493 |
+ for(i=0; i<matcher->group_counts[type]; i++) { |
|
1494 |
+ if(!strcmp(group, matcher->group_names[type][i])) |
|
1495 |
+ return i+1; |
|
1496 |
+ } |
|
1497 |
+ return 0; |
|
1498 |
+} |
... | ... |
@@ -22,6 +22,7 @@ |
22 | 22 |
#define __PE_ICONS_H |
23 | 23 |
#include "pe.h" |
24 | 24 |
|
25 |
-int scanicon(uint32_t resdir_rva, cli_ctx *ctx, struct cli_exe_section *exe_sections, uint16_t nsections, uint32_t hdr_size); |
|
26 |
- |
|
25 |
+int scanicon(unsigned int *icongrp1, unsigned int *icongrp2, uint32_t resdir_rva, cli_ctx *ctx, struct cli_exe_section *exe_sections, uint16_t nsections, uint32_t hdr_size); |
|
26 |
+int cli_match_icon(cli_ctx *ctx, unsigned int *icongrp1, unsigned int *icongrp2); |
|
27 |
+int cli_icon_getgroup(const char *group, unsigned int type, cli_ctx *ctx); |
|
27 | 28 |
#endif |
... | ... |
@@ -521,7 +521,7 @@ 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 2 |
|
524 |
+#define ICO_TOKENS 4 |
|
525 | 525 |
static int cli_loadidb(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int options, struct cli_dbio *dbio) |
526 | 526 |
{ |
527 | 527 |
const char *tokens[ICO_TOKENS + 1]; |
... | ... |
@@ -530,7 +530,12 @@ static int cli_loadidb(FILE *fs, struct cl_engine *engine, unsigned int *signo, |
530 | 530 |
int ret = CL_SUCCESS; |
531 | 531 |
unsigned int line = 0, sigs = 0, tokens_count, i, size, enginesize; |
532 | 532 |
struct icomtr *metric; |
533 |
+ struct icon_matcher *matcher; |
|
533 | 534 |
|
535 |
+ |
|
536 |
+ if(!(matcher = (struct icon_matcher *)mpool_calloc(engine->mempool, sizeof(*matcher),1))) |
|
537 |
+ return CL_EMEM; |
|
538 |
+ |
|
534 | 539 |
if(engine->ignored) |
535 | 540 |
if(!(buffer_cpy = cli_malloc(FILEBUFF))) |
536 | 541 |
return CL_EMEM; |
... | ... |
@@ -550,7 +555,7 @@ static int cli_loadidb(FILE *fs, struct cl_engine *engine, unsigned int *signo, |
550 | 550 |
break; |
551 | 551 |
} |
552 | 552 |
|
553 |
- if(strlen(tokens[1]) != 124) { |
|
553 |
+ if(strlen(tokens[3]) != 124) { |
|
554 | 554 |
ret = CL_EMALFDB; |
555 | 555 |
break; |
556 | 556 |
} |
... | ... |
@@ -558,7 +563,7 @@ static int cli_loadidb(FILE *fs, struct cl_engine *engine, unsigned int *signo, |
558 | 558 |
if(engine->ignored && cli_chkign(engine->ignored, tokens[0], buffer_cpy)) |
559 | 559 |
continue; |
560 | 560 |
|
561 |
- hash = (uint8_t *)tokens[1]; |
|
561 |
+ hash = (uint8_t *)tokens[3]; |
|
562 | 562 |
if(cli_hexnibbles((char *)hash, 124)) { |
563 | 563 |
cli_errmsg("cli_loadidb: Malformed hash at line %u (bad chars)\n", line); |
564 | 564 |
ret = CL_EMALFDB; |
... | ... |
@@ -573,15 +578,15 @@ static int cli_loadidb(FILE *fs, struct cl_engine *engine, unsigned int *signo, |
573 | 573 |
enginesize = (size >> 3) - 2; |
574 | 574 |
hash+=2; |
575 | 575 |
|
576 |
- metric = (struct icomtr *) mpool_realloc(engine->mempool, engine->icons[enginesize], sizeof(struct icomtr) * (engine->icon_counts[enginesize] + 1)); |
|
576 |
+ metric = (struct icomtr *)mpool_realloc(engine->mempool, matcher->icons[enginesize], sizeof(struct icomtr) * (matcher->icon_counts[enginesize] + 1)); |
|
577 | 577 |
if(!metric) { |
578 | 578 |
ret = CL_EMEM; |
579 | 579 |
break; |
580 | 580 |
} |
581 | 581 |
|
582 |
- engine->icons[enginesize] = metric; |
|
583 |
- metric += engine->icon_counts[enginesize]; |
|
584 |
- engine->icon_counts[enginesize]++; |
|
582 |
+ matcher->icons[enginesize] = metric; |
|
583 |
+ metric += matcher->icon_counts[enginesize]; |
|
584 |
+ matcher->icon_counts[enginesize]++; |
|
585 | 585 |
|
586 | 586 |
for(i=0; i<3; i++) { |
587 | 587 |
if((metric->color_avg[i] = (hash[0] << 8) | (hash[1] << 4) | hash[2]) > 4072) |
... | ... |
@@ -684,6 +689,34 @@ static int cli_loadidb(FILE *fs, struct cl_engine *engine, unsigned int *signo, |
684 | 684 |
break; |
685 | 685 |
} |
686 | 686 |
|
687 |
+ for(i=0; i<matcher->group_counts[0]; i++) { |
|
688 |
+ if(!strcmp(tokens[1], matcher->group_names[0][i])) |
|
689 |
+ break; |
|
690 |
+ } |
|
691 |
+ if(i==matcher->group_counts[0]) { |
|
692 |
+ if(!(matcher->group_names[0] = mpool_realloc(engine->mempool, matcher->group_names[0], sizeof(char *) * (i + 1))) || |
|
693 |
+ !(matcher->group_names[0][i] = cli_mpool_strdup(engine->mempool, tokens[1]))) { |
|
694 |
+ ret = CL_EMEM; |
|
695 |
+ break; |
|
696 |
+ } |
|
697 |
+ matcher->group_counts[0]++; |
|
698 |
+ } |
|
699 |
+ metric->group[0] = i; |
|
700 |
+ |
|
701 |
+ for(i=0; i<matcher->group_counts[1]; i++) { |
|
702 |
+ if(!strcmp(tokens[2], matcher->group_names[1][i])) |
|
703 |
+ break; |
|
704 |
+ } |
|
705 |
+ if(i==matcher->group_counts[1]) { |
|
706 |
+ if(!(matcher->group_names[1] = mpool_realloc(engine->mempool, matcher->group_names[1], sizeof(char *) * (i + 1))) || |
|
707 |
+ !(matcher->group_names[1][i] = cli_mpool_strdup(engine->mempool, tokens[2]))) { |
|
708 |
+ ret = CL_EMALFDB; |
|
709 |
+ break; |
|
710 |
+ } |
|
711 |
+ matcher->group_counts[1]++; |
|
712 |
+ } |
|
713 |
+ metric->group[1] = i; |
|
714 |
+ |
|
687 | 715 |
sigs++; |
688 | 716 |
} |
689 | 717 |
if(engine->ignored) |
... | ... |
@@ -702,6 +735,7 @@ static int cli_loadidb(FILE *fs, struct cl_engine *engine, unsigned int *signo, |
702 | 702 |
if(signo) |
703 | 703 |
*signo += sigs; |
704 | 704 |
|
705 |
+ engine->iconcheck = matcher; |
|
705 | 706 |
return CL_SUCCESS; |
706 | 707 |
} |
707 | 708 |
|
... | ... |
@@ -2358,12 +2392,26 @@ int cl_engine_free(struct cl_engine *engine) |
2358 | 2358 |
if(engine->pua_cats) |
2359 | 2359 |
mpool_free(engine->mempool, engine->pua_cats); |
2360 | 2360 |
|
2361 |
- for(i=0; i<3; i++) { |
|
2362 |
- if(engine->icons[i]) { |
|
2363 |
- mpool_free(engine->mempool, engine->icons[i]->name); |
|
2364 |
- mpool_free(engine->mempool, engine->icons[i]); |
|
2361 |
+ if(engine->iconcheck) { |
|
2362 |
+ struct icon_matcher *iconcheck = engine->iconcheck; |
|
2363 |
+ for(i=0; i<3; i++) { |
|
2364 |
+ if(iconcheck->icons[i]) { |
|
2365 |
+ mpool_free(engine->mempool, iconcheck->icons[i]->name); |
|
2366 |
+ mpool_free(engine->mempool, iconcheck->icons[i]); |
|
2367 |
+ } |
|
2365 | 2368 |
} |
2366 |
- } |
|
2369 |
+ if(iconcheck->group_names[0]) { |
|
2370 |
+ for(i=0; i<iconcheck->group_counts[0]; i++) |
|
2371 |
+ mpool_free(engine->mempool, iconcheck->group_names[0][i]); |
|
2372 |
+ mpool_free(engine->mempool, iconcheck->group_names[0]); |
|
2373 |
+ } |
|
2374 |
+ if(iconcheck->group_names[1]) { |
|
2375 |
+ for(i=0; i<iconcheck->group_counts[1]; i++) |
|
2376 |
+ mpool_free(engine->mempool, iconcheck->group_names[1][i]); |
|
2377 |
+ mpool_free(engine->mempool, iconcheck->group_names[1]); |
|
2378 |
+ } |
|
2379 |
+ mpool_free(engine->mempool, iconcheck); |
|
2380 |
+ } |
|
2367 | 2381 |
|
2368 | 2382 |
if(engine->tmpdir) |
2369 | 2383 |
mpool_free(engine->mempool, engine->tmpdir); |