... | ... |
@@ -72,7 +72,7 @@ int hm_addhash(struct cli_matcher *root, const char *hash, uint32_t size, const |
72 | 72 |
item = cli_htu32_find(ht, size); |
73 | 73 |
if(!item) { |
74 | 74 |
struct cli_htu32_element htitem; |
75 |
- szh = mpool_calloc(root->mempool, 1, sizeof(szh)); |
|
75 |
+ szh = mpool_calloc(root->mempool, 1, sizeof(*szh)); |
|
76 | 76 |
if(!szh) { |
77 | 77 |
cli_errmsg("hm_addhash: failed to allocate size hash\n"); |
78 | 78 |
return CL_EMEM; |
... | ... |
@@ -144,7 +144,7 @@ void hm_sort(struct cli_sz_hash *szh, size_t l, size_t r, unsigned int keylen) { |
144 | 144 |
|
145 | 145 |
memcpy(piv, &szh->hash_array[keylen * l], keylen); |
146 | 146 |
while(l1 < r1) { |
147 |
- if(cli_hm_cmp(&szh->hash_array[keylen * l1], piv, keylen) > 0) { |
|
147 |
+ if(hm_cmp(&szh->hash_array[keylen * l1], piv, keylen) > 0) { |
|
148 | 148 |
r1--; |
149 | 149 |
memcpy(tmph, &szh->hash_array[keylen * l1], keylen); |
150 | 150 |
tmpv = szh->virusnames[l1]; |
... | ... |
@@ -200,6 +200,13 @@ void hm_flush(struct cli_matcher *root) { |
200 | 200 |
} |
201 | 201 |
|
202 | 202 |
|
203 |
+int cli_hm_have_size(const struct cli_matcher *root, enum CLI_HASH_TYPE type, uint32_t size) { |
|
204 |
+ if(!size || size == 0xffffffff || !root || !root->hm.htinint[type] || !cli_htu32_find(&root->hm.sizehashes[type], size)) |
|
205 |
+ return 0; |
|
206 |
+ |
|
207 |
+ return 1; |
|
208 |
+} |
|
209 |
+ |
|
203 | 210 |
int cli_hm_scan(const unsigned char *digest, uint32_t size, const char **virname, const struct cli_matcher *root, enum CLI_HASH_TYPE type) { |
204 | 211 |
const struct cli_htu32_element *item; |
205 | 212 |
unsigned int keylen; |
... | ... |
@@ -53,5 +53,7 @@ struct cli_hash_patt { |
53 | 53 |
|
54 | 54 |
int hm_addhash(struct cli_matcher *root, const char *hash, uint32_t size, const char *virusname); |
55 | 55 |
void hm_flush(struct cli_matcher *root); |
56 |
+int cli_hm_scan(const unsigned char *digest, uint32_t size, const char **virname, const struct cli_matcher *root, enum CLI_HASH_TYPE type); |
|
57 |
+int cli_hm_have_size(const struct cli_matcher *root, enum CLI_HASH_TYPE type, uint32_t size); |
|
56 | 58 |
|
57 | 59 |
#endif |
... | ... |
@@ -387,6 +387,12 @@ int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx) |
387 | 387 |
cli_dbgmsg("cli_checkfp(): Found false positive detection (fp sig: %s)\n", virname); |
388 | 388 |
return CL_CLEAN; |
389 | 389 |
} |
390 |
+ |
|
391 |
+ if(ctx->engine->hm_fp && cli_hm_scan(digest, size, &virname, ctx->engine->hm_fp, CLI_HASH_MD5) == CL_VIRUS) { |
|
392 |
+ cli_dbgmsg("cli_checkfp(): Found false positive detection (fp sig: %s)\n", virname); |
|
393 |
+ return CL_CLEAN; |
|
394 |
+ } |
|
395 |
+ |
|
390 | 396 |
for(i = 0; i < 16; i++) |
391 | 397 |
sprintf(md5 + i * 2, "%02x", digest[i]); |
392 | 398 |
md5[32] = 0; |
... | ... |
@@ -698,12 +704,14 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli |
698 | 698 |
offset += bytes - maxpatlen; |
699 | 699 |
} |
700 | 700 |
|
701 |
- if(!ftonly && ctx->engine->md5_hdb) { |
|
701 |
+ if(!ftonly && (ctx->engine->md5_hdb || ctx->engine->hm_hdb)) { |
|
702 | 702 |
if(!refhash) { |
703 | 703 |
cli_md5_final(digest, &md5ctx); |
704 | 704 |
refhash = digest; |
705 | 705 |
} |
706 |
- if(cli_md5m_scan(refhash, map->len, ctx->virname, ctx->engine->md5_hdb) == CL_VIRUS && cli_md5m_scan(refhash, map->len, NULL, ctx->engine->md5_fp) != CL_VIRUS) |
|
706 |
+ if(ctx->engine->md5_hdb && cli_md5m_scan(refhash, map->len, ctx->virname, ctx->engine->md5_hdb) == CL_VIRUS && cli_md5m_scan(refhash, map->len, NULL, ctx->engine->md5_fp) != CL_VIRUS) |
|
707 |
+ ret = CL_VIRUS; |
|
708 |
+ if(ctx->engine->hm_hdb && cli_hm_scan(refhash, map->len, ctx->virname, ctx->engine->hm_hdb, CLI_HASH_MD5) == CL_VIRUS && cli_hm_scan(refhash, map->len, NULL, ctx->engine->hm_fp, CLI_HASH_MD5) != CL_VIRUS) |
|
707 | 709 |
ret = CL_VIRUS; |
708 | 710 |
} |
709 | 711 |
|
... | ... |
@@ -1002,11 +1002,9 @@ int cli_scanpe(cli_ctx *ctx) |
1002 | 1002 |
/* check MD5 section sigs */ |
1003 | 1003 |
md5_sect = ctx->engine->md5_mdb; |
1004 | 1004 |
if((DCONF & PE_CONF_MD5SECT) && md5_sect) { |
1005 |
- found = 0; |
|
1006 | 1005 |
for(j = 0; j < md5_sect->soff_len && md5_sect->soff[j] <= exe_sections[i].rsz; j++) { |
1007 | 1006 |
if(md5_sect->soff[j] == exe_sections[i].rsz) { |
1008 | 1007 |
unsigned char md5_dig[16]; |
1009 |
- const struct cli_md5m_patt *patt; |
|
1010 | 1008 |
if(cli_md5sect(map, &exe_sections[i], md5_dig) && cli_md5m_scan(md5_dig, exe_sections[i].rsz, ctx->virname, ctx->engine->md5_mdb) == CL_VIRUS) { |
1011 | 1009 |
if(cli_md5m_scan(md5_dig, fsize, NULL, ctx->engine->md5_fp) != CL_VIRUS) { |
1012 | 1010 |
free(section_hdr); |
... | ... |
@@ -1018,6 +1016,21 @@ int cli_scanpe(cli_ctx *ctx) |
1018 | 1018 |
} |
1019 | 1019 |
} |
1020 | 1020 |
} |
1021 |
+ |
|
1022 |
+ md5_sect = ctx->engine->hm_mdb; |
|
1023 |
+ if((DCONF & PE_CONF_MD5SECT) && md5_sect) { |
|
1024 |
+ unsigned char md5_dig[16]; |
|
1025 |
+ if(cli_hm_have_size(md5_sect, CLI_HASH_MD5, exe_sections[i].rsz) && |
|
1026 |
+ cli_md5sect(map, &exe_sections[i], md5_dig) && |
|
1027 |
+ cli_hm_scan(md5_dig, exe_sections[i].rsz, ctx->virname, md5_sect, CLI_HASH_MD5) == CL_VIRUS) { |
|
1028 |
+ if(cli_hm_scan(md5_dig, fsize, NULL, ctx->engine->hm_fp, CLI_HASH_MD5) != CL_VIRUS) { |
|
1029 |
+ free(section_hdr); |
|
1030 |
+ free(exe_sections); |
|
1031 |
+ return CL_VIRUS; |
|
1032 |
+ } |
|
1033 |
+ } |
|
1034 |
+ } |
|
1035 |
+ |
|
1021 | 1036 |
} |
1022 | 1037 |
|
1023 | 1038 |
if (exe_sections[i].urva>>31 || exe_sections[i].uvsz>>31 || (exe_sections[i].rsz && exe_sections[i].uraw>>31) || exe_sections[i].ursz>>31) { |
... | ... |
@@ -2092,15 +2092,29 @@ static int cli_loadhash(FILE *fs, struct cl_engine *engine, unsigned int *signo, |
2092 | 2092 |
break; |
2093 | 2093 |
} |
2094 | 2094 |
|
2095 |
- if(mode == MD5_HDB) |
|
2095 |
+ if(mode == MD5_HDB) |
|
2096 | 2096 |
db = engine->hm_hdb; |
2097 | 2097 |
else if(mode == MD5_MDB) |
2098 | 2098 |
db = engine->hm_mdb; |
2099 | 2099 |
else |
2100 | 2100 |
db = engine->hm_fp; |
2101 | 2101 |
|
2102 |
+ if(!db) { |
|
2103 |
+ if(!(db = mpool_calloc(engine->mempool, 1, sizeof(*db)))) { |
|
2104 |
+ ret = CL_EMEM; |
|
2105 |
+ break; |
|
2106 |
+ } |
|
2107 |
+ db->mempool = engine->mempool; |
|
2108 |
+ if(mode == MD5_HDB) |
|
2109 |
+ engine->hm_hdb = db; |
|
2110 |
+ else if(mode == MD5_MDB) |
|
2111 |
+ engine->hm_mdb = db; |
|
2112 |
+ else |
|
2113 |
+ engine->hm_fp = db; |
|
2114 |
+ } |
|
2115 |
+ |
|
2102 | 2116 |
if((ret = hm_addhash(db, tokens[md5_field], size, virname))) { |
2103 |
- cli_errmsg("cli_loadmd5: Malformed MD5 string at line %u\n", line); |
|
2117 |
+ cli_errmsg("cli_loadhash: Malformed MD5 string at line %u\n", line); |
|
2104 | 2118 |
mpool_free(engine->mempool, (void *)virname); |
2105 | 2119 |
break; |
2106 | 2120 |
} |
... | ... |
@@ -2111,12 +2125,12 @@ static int cli_loadhash(FILE *fs, struct cl_engine *engine, unsigned int *signo, |
2111 | 2111 |
free(buffer_cpy); |
2112 | 2112 |
|
2113 | 2113 |
if(!line) { |
2114 |
- cli_errmsg("cli_loadmd5: Empty database file\n"); |
|
2114 |
+ cli_errmsg("cli_loadhash: Empty database file\n"); |
|
2115 | 2115 |
return CL_EMALFDB; |
2116 | 2116 |
} |
2117 | 2117 |
|
2118 | 2118 |
if(ret) { |
2119 |
- cli_errmsg("cli_loadmd5: Problem parsing database at line %u\n", line); |
|
2119 |
+ cli_errmsg("cli_loadhash: Problem parsing database at line %u\n", line); |
|
2120 | 2120 |
return ret; |
2121 | 2121 |
} |
2122 | 2122 |
|