Also adds possibility to stop a hook from executing, and set
a virus as heuristic (by using BC.Heuristic* name)
... | ... |
@@ -1,3 +1,7 @@ |
1 |
+Fri Sep 10 22:10:33 EEST 2010 (edwin) |
|
2 |
+------------------------------------- |
|
3 |
+ * libclamav/pdf.c, pe.c, bytecode*: Fix bytecode virusname reporting (bb #2255) |
|
4 |
+ |
|
1 | 5 |
Fri Sep 10 10:52:45 CEST 2010 (acab) |
2 | 6 |
------------------------------------ |
3 | 7 |
* clamav-milter/netcode.c: fix error path fd leak when connection succeeds |
... | ... |
@@ -130,7 +130,6 @@ static int cli_bytecode_context_reset(struct cli_bc_ctx *ctx) |
130 | 130 |
|
131 | 131 |
if (ctx->outfd) { |
132 | 132 |
cli_ctx *cctx = ctx->ctx; |
133 |
- cli_bcapi_extract_new(ctx, -1); |
|
134 | 133 |
if (ctx->outfd) |
135 | 134 |
close(ctx->outfd); |
136 | 135 |
if (ctx->tempfile && (!cctx || !cctx->engine->keeptmp)) { |
... | ... |
@@ -1560,6 +1559,7 @@ int cli_bytecode_load(struct cli_bc *bc, FILE *f, struct cli_dbio *dbio, int tru |
1560 | 1560 |
|
1561 | 1561 |
int cli_bytecode_run(const struct cli_all_bc *bcs, const struct cli_bc *bc, struct cli_bc_ctx *ctx) |
1562 | 1562 |
{ |
1563 |
+ int ret; |
|
1563 | 1564 |
struct cli_bc_inst inst; |
1564 | 1565 |
struct cli_bc_func func; |
1565 | 1566 |
if (!ctx || !ctx->bc || !ctx->func) |
... | ... |
@@ -1593,10 +1593,16 @@ int cli_bytecode_run(const struct cli_all_bc *bcs, const struct cli_bc *bc, stru |
1593 | 1593 |
inst.u.ops.ops = ctx->operands; |
1594 | 1594 |
inst.u.ops.opsizes = ctx->opsizes; |
1595 | 1595 |
cli_dbgmsg("Bytecode: executing in interpeter mode\n"); |
1596 |
- return cli_vm_execute(ctx->bc, ctx, &func, &inst); |
|
1596 |
+ ret = cli_vm_execute(ctx->bc, ctx, &func, &inst); |
|
1597 |
+ } else { |
|
1598 |
+ cli_dbgmsg("Bytecode: executing in JIT mode\n"); |
|
1599 |
+ ret = cli_vm_execute_jit(bcs, ctx, &bc->funcs[ctx->funcid]); |
|
1597 | 1600 |
} |
1598 |
- cli_dbgmsg("Bytecode: executing in JIT mode\n"); |
|
1599 |
- return cli_vm_execute_jit(bcs, ctx, &bc->funcs[ctx->funcid]); |
|
1601 |
+ /* need to be called here to catch any extracted but not yet scanned files |
|
1602 |
+ */ |
|
1603 |
+ if (ctx->outfd) |
|
1604 |
+ cli_bcapi_extract_new(ctx, -1); |
|
1605 |
+ return ret; |
|
1600 | 1606 |
} |
1601 | 1607 |
|
1602 | 1608 |
uint64_t cli_bytecode_context_getresult_int(struct cli_bc_ctx *ctx) |
... | ... |
@@ -2463,11 +2469,16 @@ int cli_bytecode_runlsig(cli_ctx *cctx, struct cli_target_info *tinfo, |
2463 | 2463 |
return CL_SUCCESS; |
2464 | 2464 |
} |
2465 | 2465 |
if (ctx.virname) { |
2466 |
+ int rc; |
|
2466 | 2467 |
cli_dbgmsg("Bytecode found virus: %s\n", ctx.virname); |
2467 | 2468 |
if (virname) |
2468 | 2469 |
*virname = ctx.virname; |
2470 |
+ if (!strncmp(*virname, "BC.Heuristics", 13)) |
|
2471 |
+ rc = cli_found_possibly_unwanted(cctx); |
|
2472 |
+ else |
|
2473 |
+ rc = CL_VIRUS; |
|
2469 | 2474 |
cli_bytecode_context_clear(&ctx); |
2470 |
- return CL_VIRUS; |
|
2475 |
+ return rc; |
|
2471 | 2476 |
} |
2472 | 2477 |
ret = cli_bytecode_context_getresult_int(&ctx); |
2473 | 2478 |
cli_dbgmsg("Bytecode %u returned code: %u\n", bc->id, ret); |
... | ... |
@@ -2481,7 +2492,7 @@ int cli_bytecode_runhook(cli_ctx *cctx, const struct cl_engine *engine, struct c |
2481 | 2481 |
const unsigned *hooks = engine->hooks[id - _BC_START_HOOKS]; |
2482 | 2482 |
unsigned i, hooks_cnt = engine->hooks_cnt[id - _BC_START_HOOKS]; |
2483 | 2483 |
int ret; |
2484 |
- unsigned executed = 0; |
|
2484 |
+ unsigned executed = 0, breakflag = 0; |
|
2485 | 2485 |
|
2486 | 2486 |
cli_bytecode_context_setfile(ctx, map); |
2487 | 2487 |
cli_dbgmsg("Bytecode executing hook id %u (%u hooks)\n", id, hooks_cnt); |
... | ... |
@@ -2513,6 +2524,10 @@ int cli_bytecode_runhook(cli_ctx *cctx, const struct cl_engine *engine, struct c |
2513 | 2513 |
ret = cli_bytecode_context_getresult_int(ctx); |
2514 | 2514 |
/* TODO: use prefix here */ |
2515 | 2515 |
cli_dbgmsg("Bytecode %u returned %u\n", bc->id, ret); |
2516 |
+ if (ret == 0xcea5e) { |
|
2517 |
+ cli_dbgmsg("Bytecode set BREAK flag in hook!\n"); |
|
2518 |
+ breakflag = 1; |
|
2519 |
+ } |
|
2516 | 2520 |
if (!ret) { |
2517 | 2521 |
char *tempfile; |
2518 | 2522 |
int fd = cli_bytecode_context_getresult_file(ctx, &tempfile); |
... | ... |
@@ -2550,7 +2565,7 @@ int cli_bytecode_runhook(cli_ctx *cctx, const struct cl_engine *engine, struct c |
2550 | 2550 |
cli_dbgmsg("Bytecode: executed %u bytecodes for this hook\n", executed); |
2551 | 2551 |
else |
2552 | 2552 |
cli_dbgmsg("Bytecode: no logical signature matched, no bytecode executed\n"); |
2553 |
- return CL_CLEAN; |
|
2553 |
+ return breakflag ? CL_BREAK : CL_CLEAN; |
|
2554 | 2554 |
} |
2555 | 2555 |
|
2556 | 2556 |
int cli_bytecode_context_setpe(struct cli_bc_ctx *ctx, const struct cli_pe_hook_data *data, const struct cli_exe_section *sections) |
... | ... |
@@ -460,8 +460,11 @@ int32_t cli_bcapi_extract_new(struct cli_bc_ctx *ctx, int32_t id) |
460 | 460 |
cctx->container_type = ctx->containertype; |
461 | 461 |
res = cli_magic_scandesc(ctx->outfd, cctx); |
462 | 462 |
cctx->container_type = current; |
463 |
- if (res == CL_VIRUS) |
|
463 |
+ if (res == CL_VIRUS) { |
|
464 |
+ if (cctx->virname) |
|
465 |
+ ctx->virname = *cctx->virname; |
|
464 | 466 |
ctx->found = 1; |
467 |
+ } |
|
465 | 468 |
} |
466 | 469 |
if ((cctx && cctx->engine->keeptmp) || |
467 | 470 |
(ftruncate(ctx->outfd, 0) == -1)) { |
... | ... |
@@ -77,7 +77,8 @@ enum pdf_phase { |
77 | 77 |
PDF_PHASE_NONE /* not a PDF */, |
78 | 78 |
PDF_PHASE_PARSED, /* after parsing a PDF, object flags can be set etc. */ |
79 | 79 |
PDF_PHASE_POSTDUMP, /* after an obj was dumped and scanned */ |
80 |
- PDF_PHASE_END /* after the pdf scan finished */ |
|
80 |
+ PDF_PHASE_END, /* after the pdf scan finished */ |
|
81 |
+ PDF_PHASE_PRE /* before pdf is parsed at all */ |
|
81 | 82 |
}; |
82 | 83 |
|
83 | 84 |
/** PDF flags */ |
... | ... |
@@ -1082,6 +1082,11 @@ int cli_pdf(const char *dir, cli_ctx *ctx, off_t offset) |
1082 | 1082 |
cli_errmsg("cli_pdf: mmap() failed (3)\n"); |
1083 | 1083 |
return CL_EMAP; |
1084 | 1084 |
} |
1085 |
+ rc = run_pdf_hooks(&pdf, PDF_PHASE_PRE, -1, -1); |
|
1086 |
+ if (rc) { |
|
1087 |
+ cli_dbgmsg("cli_pdf: returning %d\n", rc); |
|
1088 |
+ return rc; |
|
1089 |
+ } |
|
1085 | 1090 |
/* parse PDF and find obj offsets */ |
1086 | 1091 |
while ((rc = pdf_findobj(&pdf)) > 0) { |
1087 | 1092 |
struct pdf_obj *obj = &pdf.objs[pdf.nobjs-1]; |
... | ... |
@@ -1130,10 +1130,10 @@ int cli_scanpe(cli_ctx *ctx) |
1130 | 1130 |
cli_bytecode_context_setpe(bc_ctx, &pedata, exe_sections); |
1131 | 1131 |
cli_bytecode_context_setctx(bc_ctx, ctx); |
1132 | 1132 |
ret = cli_bytecode_runhook(ctx, ctx->engine, bc_ctx, BC_PE_ALL, map, ctx->virname); |
1133 |
- if (ret == CL_VIRUS) { |
|
1133 |
+ if (ret == CL_VIRUS || ret == CL_BREAK) { |
|
1134 | 1134 |
free(exe_sections); |
1135 | 1135 |
cli_bytecode_context_destroy(bc_ctx); |
1136 |
- return CL_VIRUS; |
|
1136 |
+ return ret == CL_VIRUS ? CL_VIRUS : CL_CLEAN; |
|
1137 | 1137 |
} |
1138 | 1138 |
cli_bytecode_context_destroy(bc_ctx); |
1139 | 1139 |
|