... | ... |
@@ -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 |
+} |