Browse code

Fix matchicon bytecode API (bb #2139).

Now you can call it both from a normal lsig triggered BC, and from a PE hook BC.
The normal lsig triggered BC has exe_info (but not PE info) which allows it to
invoke the icon matcher API.
Also putting ICONGROUP1 into the ldb trigger of the bytecode works.

Török Edvin authored on 2010/08/03 03:50:14
Showing 5 changed files
... ...
@@ -1,3 +1,7 @@
1
+Mon Aug  2 21:51:32 EEST 2010 (edwin)
2
+-------------------------------------
3
+ * libclamav/{bytecode,matcher}.c: matchicon API (bb #2139)
4
+
1 5
 Mon Aug  2 17:16:24 CEST 2010 (acab)
2 6
 ------------------------------------
3 7
  * libclamav/pe_icons.c: BE fixes (bb#2151)
... ...
@@ -2400,11 +2400,15 @@ int cli_bytecode_context_setfile(struct cli_bc_ctx *ctx, fmap_t *map)
2400 2400
     return 0;
2401 2401
 }
2402 2402
 
2403
-int cli_bytecode_runlsig(cli_ctx *cctx, const struct cli_all_bc *bcs, unsigned bc_idx, const char **virname, const uint32_t* lsigcnt, const uint32_t *lsigsuboff, fmap_t *map)
2403
+int cli_bytecode_runlsig(cli_ctx *cctx, struct cli_target_info *tinfo,
2404
+			 const struct cli_all_bc *bcs, unsigned bc_idx,
2405
+			 const char **virname, const uint32_t* lsigcnt,
2406
+			 const uint32_t *lsigsuboff, fmap_t *map)
2404 2407
 {
2405 2408
     int ret;
2406 2409
     struct cli_bc_ctx ctx;
2407 2410
     const struct cli_bc *bc = &bcs->all_bcs[bc_idx-1];
2411
+    struct cli_pe_hook_data pehookdata;
2408 2412
 
2409 2413
     if (bc->hook_lsig_id) {
2410 2414
 	cli_dbgmsg("hook lsig id %d matched (bc %d)\n", bc->hook_lsig_id, bc->id);
... ...
@@ -2420,6 +2424,16 @@ int cli_bytecode_runlsig(cli_ctx *cctx, const struct cli_all_bc *bcs, unsigned b
2420 2420
     ctx.hooks.match_offsets = lsigsuboff;
2421 2421
     cli_bytecode_context_setctx(&ctx, cctx);
2422 2422
     cli_bytecode_context_setfile(&ctx, map);
2423
+    if (tinfo && tinfo->status == 1) {
2424
+	ctx.sections = tinfo->exeinfo.section;
2425
+	memset(&pehookdata, 0, sizeof(pehookdata));
2426
+	pehookdata.offset = tinfo->exeinfo.offset;
2427
+	pehookdata.ep = tinfo->exeinfo.ep;
2428
+	pehookdata.nsections = tinfo->exeinfo.nsections;
2429
+	pehookdata.hdr_size = tinfo->exeinfo.hdr_size;
2430
+	ctx.hooks.pedata = &pehookdata;
2431
+	ctx.resaddr = tinfo->exeinfo.res_addr;
2432
+    }
2423 2433
 
2424 2434
     cli_dbgmsg("Running bytecode for logical signature match\n");
2425 2435
     ret = cli_bytecode_run(bcs, bc, &ctx);
... ...
@@ -117,7 +117,8 @@ void cli_bytecode_describe(const struct cli_bc *bc);
117 117
 /* Hooks */
118 118
 struct cli_exe_info;
119 119
 struct cli_ctx_tag;
120
-int cli_bytecode_runlsig(struct cli_ctx_tag *ctx, const struct cli_all_bc *bcs, unsigned bc_idx, const char **virname, const uint32_t* lsigcnt, const uint32_t *lsigsuboff, fmap_t *map);
120
+struct cli_target_info;
121
+int cli_bytecode_runlsig(struct cli_ctx_tag *ctx, struct cli_target_info *info, const struct cli_all_bc *bcs, unsigned bc_idx, const char **virname, const uint32_t* lsigcnt, const uint32_t *lsigsuboff, fmap_t *map);
121 122
 int cli_bytecode_runhook(struct cli_ctx_tag *cctx, const struct cl_engine *engine, struct cli_bc_ctx *ctx, unsigned id, fmap_t *map, const char **virname);
122 123
 
123 124
 #ifdef __cplusplus
... ...
@@ -165,6 +165,7 @@ struct cli_bc_ctx {
165 165
     unsigned pdf_phase;
166 166
     int32_t pdf_dumpedid;
167 167
     const struct cli_exe_section *sections;
168
+    uint32_t resaddr;
168 169
     char *tempfile;
169 170
     void *ctx;
170 171
     unsigned written;
... ...
@@ -454,10 +454,10 @@ int32_t cli_bcapi_matchicon(struct cli_bc_ctx *ctx , const uint8_t* grp1, int32_
454 454
 {
455 455
     int ret;
456 456
     char group1[128], group2[128];
457
-    const char *oldvirname;
457
+    const char **oldvirname;
458 458
     struct cli_exe_info info;
459 459
 
460
-    if (ctx->bc->kind != BC_PE_UNPACKER) {
460
+    if (!ctx->hooks.pedata->ep) {
461 461
 	cli_dbgmsg("bytecode: matchicon only works with PE files\n");
462 462
 	return -1;
463 463
     }
... ...
@@ -465,20 +465,26 @@ int32_t cli_bcapi_matchicon(struct cli_bc_ctx *ctx , const uint8_t* grp1, int32_
465 465
 	grp2len > sizeof(group2)-1)
466 466
 	return -1;
467 467
     oldvirname = ((cli_ctx*)ctx->ctx)->virname;
468
+    ((cli_ctx*)ctx->ctx)->virname = NULL;
468 469
     memcpy(group1, grp1, grp1len);
469 470
     memcpy(group2, grp2, grp2len);
470 471
     group1[grp1len] = 0;
471
-    group2[grp1len] = 0;
472
+    group2[grp2len] = 0;
472 473
     memset(&info, 0, sizeof(info));
473
-    if(le16_to_host(ctx->hooks.pedata->file_hdr.Characteristics) & 0x2000 ||
474
-       !ctx->hooks.pedata->dirs[2].Size)
475
-	info.res_addr = 0;
476
-    else
477
-	info.res_addr = le32_to_host(ctx->hooks.pedata->dirs[2].VirtualAddress);
474
+    if (ctx->bc->kind == BC_PE_UNPACKER) {
475
+	if(le16_to_host(ctx->hooks.pedata->file_hdr.Characteristics) & 0x2000 ||
476
+	   !ctx->hooks.pedata->dirs[2].Size)
477
+	    info.res_addr = 0;
478
+	else
479
+	    info.res_addr = le32_to_host(ctx->hooks.pedata->dirs[2].VirtualAddress);
480
+    } else
481
+	info.res_addr = ctx->resaddr; /* from target_info */
478 482
     info.section = (struct cli_exe_section*)ctx->sections;
479 483
     info.nsections = ctx->hooks.pedata->nsections;
480 484
     info.hdr_size = ctx->hooks.pedata->hdr_size;
481
-    ret = matchicon(ctx->ctx, &info, group1, group2);
485
+    cli_dbgmsg("bytecode matchicon %s %s\n", group1, group2);
486
+    ret = matchicon(ctx->ctx, &info, group1[0] ? group1 : NULL,
487
+		    group2[0] ? group2 : NULL);
482 488
     ((cli_ctx*)ctx->ctx)->virname = oldvirname;
483 489
     return ret;
484 490
 }
... ...
@@ -533,7 +539,7 @@ int cli_lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *ac
533 533
 			if(ctx->virname)
534 534
 			    *ctx->virname = root->ac_lsigtable[i]->virname;
535 535
 			return CL_VIRUS;
536
-		    } else if(cli_bytecode_runlsig(ctx, &ctx->engine->bcs, root->ac_lsigtable[i]->bc_idx, ctx->virname, acdata->lsigcnt[i], acdata->lsigsuboff[i], map) == CL_VIRUS) {
536
+		    } else if(cli_bytecode_runlsig(ctx, target_info, &ctx->engine->bcs, root->ac_lsigtable[i]->bc_idx, ctx->virname, acdata->lsigcnt[i], acdata->lsigsuboff[i], map) == CL_VIRUS) {
537 537
 			return CL_VIRUS;
538 538
 		    }
539 539
 		}
... ...
@@ -544,7 +550,7 @@ int cli_lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *ac
544 544
 		    *ctx->virname = root->ac_lsigtable[i]->virname;
545 545
 		return CL_VIRUS;
546 546
 	    }
547
-	    if(cli_bytecode_runlsig(ctx, &ctx->engine->bcs, root->ac_lsigtable[i]->bc_idx, ctx->virname, acdata->lsigcnt[i], acdata->lsigsuboff[i], map) == CL_VIRUS) {
547
+	    if(cli_bytecode_runlsig(ctx, target_info, &ctx->engine->bcs, root->ac_lsigtable[i]->bc_idx, ctx->virname, acdata->lsigcnt[i], acdata->lsigsuboff[i], map) == CL_VIRUS) {
548 548
 		return CL_VIRUS;
549 549
 	    }
550 550
 	}