... | ... |
@@ -1,3 +1,9 @@ |
1 |
+Fri Jul 30 15:51:06 CEST 2010 (acab) |
|
2 |
+------------------------------------ |
|
3 |
+ * libclamav, unit_tests: use cached PE metadata when matching icons (better fix for |
|
4 |
+ bb#2064, partially reverts d932a6d) |
|
5 |
+ add some unit tests for ign2, ldb, idb |
|
6 |
+ |
|
1 | 7 |
Fri Jul 30 15:15:35 CEST 2010 (tk) |
2 | 8 |
---------------------------------- |
3 | 9 |
* freshclam: fix parsing of extended log entries |
... | ... |
@@ -50,6 +50,10 @@ struct cli_exe_info { |
50 | 50 |
uint32_t ep; |
51 | 51 |
/** Number of sections*/ |
52 | 52 |
uint16_t nsections; |
53 |
+ /** Resrources RVA - PE ONLY */ |
|
54 |
+ uint32_t res_addr; |
|
55 |
+ /** Address size - PE ONLY */ |
|
56 |
+ uint32_t hdr_size; |
|
53 | 57 |
/** Hashset for versioninfo matching */ |
54 | 58 |
struct cli_hashset *vinfo; |
55 | 59 |
}; |
... | ... |
@@ -429,16 +429,25 @@ int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx) |
429 | 429 |
return CL_VIRUS; |
430 | 430 |
} |
431 | 431 |
|
432 |
-static int matchicon(cli_ctx *ctx, const char *grp1, const char *grp2) |
|
432 |
+static int matchicon(cli_ctx *ctx, struct cli_exe_info *exeinfo, const char *grp1, const char *grp2) |
|
433 | 433 |
{ |
434 | 434 |
icon_groupset iconset; |
435 | 435 |
|
436 |
+ if(!ctx || |
|
437 |
+ !ctx->engine || |
|
438 |
+ !ctx->engine->iconcheck || |
|
439 |
+ !ctx->engine->iconcheck->group_counts[0] || |
|
440 |
+ !ctx->engine->iconcheck->group_counts[1] || |
|
441 |
+ !exeinfo->res_addr |
|
442 |
+ ) return CL_CLEAN; |
|
443 |
+ |
|
436 | 444 |
cli_icongroupset_init(&iconset); |
437 | 445 |
cli_icongroupset_add(grp1 ? grp1 : "*", &iconset, 0, ctx); |
438 | 446 |
cli_icongroupset_add(grp2 ? grp2 : "*", &iconset, 1, ctx); |
439 |
- return cli_match_icon(&iconset, ctx); |
|
447 |
+ return cli_scanicon(&iconset, exeinfo->res_addr, ctx, exeinfo->section, exeinfo->nsections, exeinfo->hdr_size); |
|
440 | 448 |
} |
441 | 449 |
|
450 |
+ |
|
442 | 451 |
int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode, struct cli_ac_result **acres) |
443 | 452 |
{ |
444 | 453 |
int ret = CL_EMEM, empty; |
... | ... |
@@ -483,7 +492,7 @@ int cli_lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *ac |
483 | 483 |
if(root->ac_lsigtable[i]->tdb.icongrp1 || root->ac_lsigtable[i]->tdb.icongrp2) { |
484 | 484 |
if(!target_info || target_info->status != 1) |
485 | 485 |
continue; |
486 |
- if(matchicon(ctx, root->ac_lsigtable[i]->tdb.icongrp1, root->ac_lsigtable[i]->tdb.icongrp2) == CL_VIRUS) { |
|
486 |
+ if(matchicon(ctx, &target_info->exeinfo, root->ac_lsigtable[i]->tdb.icongrp1, root->ac_lsigtable[i]->tdb.icongrp2) == CL_VIRUS) { |
|
487 | 487 |
if(ctx->virname) |
488 | 488 |
*ctx->virname = root->ac_lsigtable[i]->virname; |
489 | 489 |
return CL_VIRUS; |
... | ... |
@@ -58,7 +58,6 @@ |
58 | 58 |
#include "disasm.h" |
59 | 59 |
#include "special.h" |
60 | 60 |
#include "ishield.h" |
61 |
-#include "pe_icons.h" |
|
62 | 61 |
|
63 | 62 |
#define DCONF ctx->dconf->pe |
64 | 63 |
|
... | ... |
@@ -501,7 +500,7 @@ static void cli_parseres_special(uint32_t base, uint32_t rva, fmap_t *map, struc |
501 | 501 |
fmap_unneed_ptr(map, oentry, entries*8); |
502 | 502 |
} |
503 | 503 |
|
504 |
-int cli_scanpe(cli_ctx *ctx, icon_groupset *iconset) |
|
504 |
+int cli_scanpe(cli_ctx *ctx) |
|
505 | 505 |
{ |
506 | 506 |
uint16_t e_magic; /* DOS signature ("MZ") */ |
507 | 507 |
uint16_t nsections; |
... | ... |
@@ -1002,7 +1001,7 @@ int cli_scanpe(cli_ctx *ctx, icon_groupset *iconset) |
1002 | 1002 |
|
1003 | 1003 |
/* check MD5 section sigs */ |
1004 | 1004 |
md5_sect = ctx->engine->md5_mdb; |
1005 |
- if((DCONF & PE_CONF_MD5SECT) && md5_sect && !iconset) { |
|
1005 |
+ if((DCONF & PE_CONF_MD5SECT) && md5_sect) { |
|
1006 | 1006 |
found = 0; |
1007 | 1007 |
for(j = 0; j < md5_sect->soff_len && md5_sect->soff[j] <= exe_sections[i].rsz; j++) { |
1008 | 1008 |
if(md5_sect->soff[j] == exe_sections[i].rsz) { |
... | ... |
@@ -1078,15 +1077,6 @@ int cli_scanpe(cli_ctx *ctx, icon_groupset *iconset) |
1078 | 1078 |
|
1079 | 1079 |
cli_dbgmsg("EntryPoint offset: 0x%x (%d)\n", ep, ep); |
1080 | 1080 |
|
1081 |
- if(iconset){ |
|
1082 |
- if(!dll && dirs[2].Size && cli_scanicon(iconset, EC32(dirs[2].VirtualAddress), ctx, exe_sections, nsections, hdr_size) == CL_VIRUS) { |
|
1083 |
- free(exe_sections); |
|
1084 |
- return CL_VIRUS; |
|
1085 |
- } |
|
1086 |
- free(exe_sections); |
|
1087 |
- return CL_CLEAN; |
|
1088 |
- } |
|
1089 |
- |
|
1090 | 1081 |
if(pe_plus) { /* Do not continue for PE32+ files */ |
1091 | 1082 |
free(exe_sections); |
1092 | 1083 |
return CL_CLEAN; |
... | ... |
@@ -2383,7 +2373,7 @@ int cli_peheader(fmap_t *map, struct cli_exe_info *peinfo) |
2383 | 2383 |
valign = (pe_plus)?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment); |
2384 | 2384 |
falign = (pe_plus)?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment); |
2385 | 2385 |
|
2386 |
- hdr_size = PESALIGN(hdr_size, valign); |
|
2386 |
+ peinfo->hdr_size = hdr_size = PESALIGN(hdr_size, valign); |
|
2387 | 2387 |
|
2388 | 2388 |
peinfo->section = (struct cli_exe_section *) cli_calloc(peinfo->nsections, sizeof(struct cli_exe_section)); |
2389 | 2389 |
|
... | ... |
@@ -2447,6 +2437,11 @@ int cli_peheader(fmap_t *map, struct cli_exe_info *peinfo) |
2447 | 2447 |
return -1; |
2448 | 2448 |
} |
2449 | 2449 |
|
2450 |
+ if(EC16(file_hdr.Characteristics) & 0x2000 || !dirs[2].Size) |
|
2451 |
+ peinfo->res_addr = 0; |
|
2452 |
+ else |
|
2453 |
+ peinfo->res_addr = EC32(dirs[2].VirtualAddress); |
|
2454 |
+ |
|
2450 | 2455 |
while(dirs[2].Size && peinfo->vinfo) { |
2451 | 2456 |
struct vinfo_list vlist; |
2452 | 2457 |
uint8_t *vptr, *baseptr; |
... | ... |
@@ -152,7 +152,7 @@ struct cli_pe_hook_data { |
152 | 152 |
uint32_t hdr_size;/**< internally needed by rawaddr */ |
153 | 153 |
}; |
154 | 154 |
|
155 |
-int cli_scanpe(cli_ctx *ctx, icon_groupset *set); |
|
155 |
+int cli_scanpe(cli_ctx *ctx); |
|
156 | 156 |
|
157 | 157 |
int cli_peheader(fmap_t *map, struct cli_exe_info *peinfo); |
158 | 158 |
|
... | ... |
@@ -1503,20 +1503,6 @@ static int parseicon(icon_groupset *set, uint32_t rva, cli_ctx *ctx, struct cli_ |
1503 | 1503 |
return CL_SUCCESS; |
1504 | 1504 |
} |
1505 | 1505 |
|
1506 |
- |
|
1507 |
-int cli_match_icon(icon_groupset *set, cli_ctx *ctx) { |
|
1508 |
- if(!ctx || !ctx->engine || !ctx->engine->iconcheck || !ctx->engine->iconcheck->group_counts[0] || !ctx->engine->iconcheck->group_counts[1]) |
|
1509 |
- return CL_CLEAN; |
|
1510 |
- else { |
|
1511 |
- unsigned int ctx_opts = ctx->options; |
|
1512 |
- int ret; |
|
1513 |
- ctx->options &= ~CL_SCAN_BLOCKBROKEN; |
|
1514 |
- ret = cli_scanpe(ctx, set); |
|
1515 |
- ctx->options = ctx_opts; |
|
1516 |
- return ret; |
|
1517 |
- } |
|
1518 |
-} |
|
1519 |
- |
|
1520 | 1506 |
void cli_icongroupset_add(const char *groupname, icon_groupset *set, unsigned int type, cli_ctx *ctx) { |
1521 | 1507 |
struct icon_matcher *matcher; |
1522 | 1508 |
unsigned int i, j; |
... | ... |
@@ -23,7 +23,6 @@ |
23 | 23 |
#include "pe.h" |
24 | 24 |
|
25 | 25 |
int cli_scanicon(icon_groupset *set, 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(icon_groupset *set, cli_ctx *ctx); |
|
27 | 26 |
|
28 | 27 |
void cli_icongroupset_add(const char *groupname, icon_groupset *set, unsigned int type, cli_ctx *ctx); |
29 | 28 |
static inline void cli_icongroupset_init(icon_groupset *set) { |
... | ... |
@@ -171,6 +171,29 @@ EOF |
171 | 171 |
|
172 | 172 |
grep "phish-test-ssl: Heuristics.Phishing.Email.SSL-Spoof FOUND" clamscan3.log >/dev/null || die "phish-test1 failed"; |
173 | 173 |
grep "phish-test-cloak: Heuristics.Phishing.Email.Cloaked.Null FOUND" clamscan3.log >/dev/null || die "phish-test2 failed"; |
174 |
+ |
|
175 |
+ cat <<EOF >test-db/test.ign2 |
|
176 |
+ClamAV-Test-File |
|
177 |
+EOF |
|
178 |
+ cat <<EOF >test-db/test.idb |
|
179 |
+EA0X-32x32x8:ea0x-grp1:ea0x-grp2:2046f030a42a07153f4120a0031600007000005e1617ef0000d21100cb090674150f880313970b0e7716116d01136216022500002f0a173700081a004a0e |
|
180 |
+IScab-16x16x8:iscab-grp1:iscab-grp2:107b3000168306015c20a0105b07060be0a0b11c050bea0706cb0a0bbb060b6f00017c06018301068109086b03046705081b000a270a002a000039002b17 |
|
181 |
+EOF |
|
182 |
+ cat <<EOF >test-db/test.ldb |
|
183 |
+ClamAV-Test-Icon-EA0X;Engine:52-1000,Target:1,IconGroup1:ea0x-grp1,IconGroup2:*;(0);0:4d5a |
|
184 |
+ClamAV-Test-Icon-IScab;Engine:52-1000,Target:1,IconGroup2:iscab-grp2;(0);0:4d5a |
|
185 |
+EOF |
|
186 |
+ if test_run 1 $CLAMSCAN --quiet -dtest-db $TESTFILES --log=clamscan4.log; then |
|
187 |
+ scan_failed clamscan4.log "clamscan didn't detect icons correctly" |
|
188 |
+ fi |
|
189 |
+ grep "clam.ea05.exe: ClamAV-Test-Icon-EA0X.UNOFFICIAL FOUND" clamscan4.log || die "icon-test1 failed" |
|
190 |
+ grep "clam.ea06.exe: ClamAV-Test-Icon-EA0X.UNOFFICIAL FOUND" clamscan4.log || die "icon-test2 failed" |
|
191 |
+ grep "clam_IScab_ext.exe: ClamAV-Test-Icon-IScab.UNOFFICIAL FOUND" clamscan4.log || die "icon-test3 failed" |
|
192 |
+ grep "clam_IScab_int.exe: ClamAV-Test-Icon-IScab.UNOFFICIAL FOUND" clamscan4.log || die "icon-test4 failed" |
|
193 |
+ NINFECTED=`grep "Infected files" clamscan4.log | cut -f2 -d: | sed -e 's/ //g'` |
|
194 |
+ if test "x$NINFECTED" -ne x4; then |
|
195 |
+ scan_failed clamscan4.log "clamscan has detected spurious icons or whitlisting was not applier properly" |
|
196 |
+ fi |
|
174 | 197 |
test_end $1 |
175 | 198 |
} |
176 | 199 |
|