Browse code

add hash matching

aCaB authored on 2011/01/08 03:08:49
Showing 5 changed files
... ...
@@ -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