[Pkg-clamav-commits] [SCM] Debian repository for ClamAV branch, debian/unstable, updated. debian/0.95+dfsg-1-6156-g094ec9b
Török Edvin
edwin at clamav.net
Sun Apr 4 01:15:39 UTC 2010
The following commit has been merged in the debian/unstable branch:
commit f4e342159210b2746277be70d1a320a95d6d1693
Author: Török Edvin <edwin at clamav.net>
Date: Tue Jan 19 16:38:12 2010 +0200
Support PE hook bytecodes triggered by logical signature.
diff --git a/libclamav/bytecode.c b/libclamav/bytecode.c
index 6bf1f75..c61c739 100644
--- a/libclamav/bytecode.c
+++ b/libclamav/bytecode.c
@@ -1609,10 +1609,18 @@ int cli_bytecode_context_setfile(struct cli_bc_ctx *ctx, fmap_t *map)
return 0;
}
-int cli_bytecode_runlsig(const struct cli_all_bc *bcs, const struct cli_bc *bc, const char **virname, const uint32_t* lsigcnt, fmap_t *map)
+int cli_bytecode_runlsig(cli_ctx *cctx, const struct cli_all_bc *bcs, const struct cli_bc *bc, const char **virname, const uint32_t* lsigcnt, fmap_t *map)
{
int ret;
struct cli_bc_ctx ctx;
+
+ if (bc->hook_lsig_id) {
+ /* this is a bytecode for a hook, defer running it until hook is
+ * executed, so that it has all the info for the hook */
+ if (cctx->hook_lsig_matches)
+ cli_bitset_set(cctx->hook_lsig_matches, bc->hook_lsig_id-1);
+ return CL_SUCCESS;
+ }
memset(&ctx, 0, sizeof(ctx));
cli_bytecode_context_setfuncid(&ctx, bc, 0);
ctx.hooks.match_counts = lsigcnt;
@@ -1637,7 +1645,7 @@ int cli_bytecode_runlsig(const struct cli_all_bc *bcs, const struct cli_bc *bc,
return CL_SUCCESS;
}
-int cli_bytecode_runhook(const struct cl_engine *engine, struct cli_bc_ctx *ctx,
+int cli_bytecode_runhook(cli_ctx *cctx, const struct cl_engine *engine, struct cli_bc_ctx *ctx,
unsigned id, fmap_t *map, const char **virname)
{
const unsigned *hooks = engine->hooks[id - _BC_START_HOOKS];
@@ -1648,6 +1656,12 @@ int cli_bytecode_runhook(const struct cl_engine *engine, struct cli_bc_ctx *ctx,
cli_dbgmsg("Bytecode executing hook id %u (%u hooks)\n", id, hooks_cnt);
for (i=0;i < hooks_cnt;i++) {
const struct cli_bc *bc = &engine->bcs.all_bcs[hooks[i]];
+ if (bc->lsig) {
+ if (!cctx->hook_lsig_matches ||
+ !cli_bitset_test(cctx->hook_lsig_matches, bc->hook_lsig_id-1))
+ continue;
+ cli_dbgmsg("Bytecode: executing bytecode %u (lsig matched)" , bc->id);
+ }
cli_bytecode_context_setfuncid(ctx, bc, 0);
ret = cli_bytecode_run(&engine->bcs, bc, ctx);
if (ret != CL_SUCCESS) {
diff --git a/libclamav/bytecode.h b/libclamav/bytecode.h
index 5d4911d..d3be533 100644
--- a/libclamav/bytecode.h
+++ b/libclamav/bytecode.h
@@ -66,6 +66,7 @@ struct cli_bc {
unsigned vnames_cnt;
struct cli_bc_dbgnode *dbgnodes;
unsigned dbgnode_cnt;
+ unsigned hook_lsig_id;
};
struct cli_all_bc {
@@ -106,8 +107,9 @@ int cli_bytecode_done(struct cli_all_bc *allbc);
/* Hooks */
struct cli_exe_info;
-int cli_bytecode_runlsig(const struct cli_all_bc *bcs, const struct cli_bc* bc, const char **virname, const uint32_t* lsigcnt, fmap_t *fmap);
-int cli_bytecode_runhook(const struct cl_engine *engine, struct cli_bc_ctx *ctx, unsigned id, fmap_t *map, const char **virname);
+struct cli_ctx_tag;
+int cli_bytecode_runlsig(struct cli_ctx_tag *ctx, const struct cli_all_bc *bcs, const struct cli_bc* bc, const char **virname, const uint32_t* lsigcnt, fmap_t *fmap);
+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);
#ifdef __cplusplus
extern "C" {
diff --git a/libclamav/bytecode_api.h b/libclamav/bytecode_api.h
index a9edc04..d81f083 100644
--- a/libclamav/bytecode_api.h
+++ b/libclamav/bytecode_api.h
@@ -71,7 +71,7 @@ extern const struct cli_exe_info __clambc_exeinfo;
/** PE data, if this is a PE hook */
extern const struct cli_pe_hook_data __clambc_pedata;
/** File size (max 4G) */
-extern const uint32_t __clambc_filesize;
+extern const uint32_t __clambc_filesize[1];
/** Kind of the bytecode */
const uint16_t __clambc_kind;
diff --git a/libclamav/bytecode_api_decl.c b/libclamav/bytecode_api_decl.c
index 2ab0660..1315d1b 100644
--- a/libclamav/bytecode_api_decl.c
+++ b/libclamav/bytecode_api_decl.c
@@ -54,9 +54,9 @@ const struct cli_apiglobal cli_globals[] = {
/* Bytecode globals BEGIN */
{"__clambc_kind", GLOBAL_KIND, 16,
((char*)&((struct cli_bc_ctx*)0)->hooks.kind - (char*)NULL)},
- {"__clambc_match_counts", GLOBAL_MATCH_COUNTS, 82,
+ {"__clambc_match_counts", GLOBAL_MATCH_COUNTS, 83,
((char*)&((struct cli_bc_ctx*)0)->hooks.match_counts - (char*)NULL)},
- {"__clambc_filesize", GLOBAL_FILESIZE, 32,
+ {"__clambc_filesize", GLOBAL_FILESIZE, 82,
((char*)&((struct cli_bc_ctx*)0)->hooks.filesize - (char*)NULL)},
{"__clambc_exeinfo", GLOBAL_EXEINFO, 79,
((char*)&((struct cli_bc_ctx*)0)->hooks.exeinfo - (char*)NULL)},
@@ -79,17 +79,18 @@ static uint16_t cli_tmp10[]={80, 32, 32, 16};
static uint16_t cli_tmp11[]={81};
static uint16_t cli_tmp12[]={32, 32, 32, 32, 32, 32, 32, 32, 32};
static uint16_t cli_tmp13[]={32};
-static uint16_t cli_tmp14[]={32, 32, 32};
-static uint16_t cli_tmp15[]={32, 65, 32};
-static uint16_t cli_tmp16[]={32, 86, 32};
-static uint16_t cli_tmp17[]={87};
-static uint16_t cli_tmp18[]={16, 8, 8, 8, 89, 88};
-static uint16_t cli_tmp19[]={8};
-static uint16_t cli_tmp20[]={90};
-static uint16_t cli_tmp21[]={8};
-static uint16_t cli_tmp22[]={32, 92, 32};
-static uint16_t cli_tmp23[]={93};
-static uint16_t cli_tmp24[]={92};
+static uint16_t cli_tmp14[]={32};
+static uint16_t cli_tmp15[]={32, 32, 32};
+static uint16_t cli_tmp16[]={32, 65, 32};
+static uint16_t cli_tmp17[]={32, 87, 32};
+static uint16_t cli_tmp18[]={88};
+static uint16_t cli_tmp19[]={16, 8, 8, 8, 90, 89};
+static uint16_t cli_tmp20[]={8};
+static uint16_t cli_tmp21[]={91};
+static uint16_t cli_tmp22[]={8};
+static uint16_t cli_tmp23[]={32, 93, 32};
+static uint16_t cli_tmp24[]={94};
+static uint16_t cli_tmp25[]={93};
const struct cli_bc_type cli_apicall_types[]={
{DStructType, cli_tmp0, 10, 0, 0},
@@ -105,39 +106,40 @@ const struct cli_bc_type cli_apicall_types[]={
{DStructType, cli_tmp10, 4, 0, 0},
{DPointerType, cli_tmp11, 1, 0, 0},
{DStructType, cli_tmp12, 9, 0, 0},
- {DArrayType, cli_tmp13, 64, 0, 0},
- {DFunctionType, cli_tmp14, 3, 0, 0},
+ {DArrayType, cli_tmp13, 1, 0, 0},
+ {DArrayType, cli_tmp14, 64, 0, 0},
{DFunctionType, cli_tmp15, 3, 0, 0},
{DFunctionType, cli_tmp16, 3, 0, 0},
- {DPointerType, cli_tmp17, 1, 0, 0},
- {DStructType, cli_tmp18, 6, 0, 0},
- {DArrayType, cli_tmp19, 29, 0, 0},
- {DArrayType, cli_tmp20, 10, 0, 0},
- {DArrayType, cli_tmp21, 3, 0, 0},
- {DFunctionType, cli_tmp22, 3, 0, 0},
- {DPointerType, cli_tmp23, 1, 0, 0},
- {DStructType, cli_tmp24, 1, 0, 0}
+ {DFunctionType, cli_tmp17, 3, 0, 0},
+ {DPointerType, cli_tmp18, 1, 0, 0},
+ {DStructType, cli_tmp19, 6, 0, 0},
+ {DArrayType, cli_tmp20, 29, 0, 0},
+ {DArrayType, cli_tmp21, 10, 0, 0},
+ {DArrayType, cli_tmp22, 3, 0, 0},
+ {DFunctionType, cli_tmp23, 3, 0, 0},
+ {DPointerType, cli_tmp24, 1, 0, 0},
+ {DStructType, cli_tmp25, 1, 0, 0}
};
const unsigned cli_apicall_maxtypes=sizeof(cli_apicall_types)/sizeof(cli_apicall_types[0]);
const struct cli_apicall cli_apicalls[]={
/* Bytecode APIcalls BEGIN */
- {"test0", 22, 0, 1},
- {"test1", 14, 0, 0},
- {"read", 15, 1, 1},
- {"write", 15, 2, 1},
- {"seek", 14, 1, 0},
- {"setvirusname", 15, 3, 1},
- {"debug_print_str", 15, 4, 1},
- {"debug_print_uint", 14, 2, 0},
- {"disasm_x86", 16, 5, 1},
- {"trace_directory", 15, 6, 1},
- {"trace_scope", 15, 7, 1},
- {"trace_source", 15, 8, 1},
- {"trace_op", 15, 9, 1},
- {"trace_value", 15, 10, 1},
- {"trace_ptr", 15, 11, 1},
- {"pe_rawaddr", 14, 3, 0}
+ {"test0", 23, 0, 1},
+ {"test1", 15, 0, 0},
+ {"read", 16, 1, 1},
+ {"write", 16, 2, 1},
+ {"seek", 15, 1, 0},
+ {"setvirusname", 16, 3, 1},
+ {"debug_print_str", 16, 4, 1},
+ {"debug_print_uint", 15, 2, 0},
+ {"disasm_x86", 17, 5, 1},
+ {"trace_directory", 16, 6, 1},
+ {"trace_scope", 16, 7, 1},
+ {"trace_source", 16, 8, 1},
+ {"trace_op", 16, 9, 1},
+ {"trace_value", 16, 10, 1},
+ {"trace_ptr", 16, 11, 1},
+ {"pe_rawaddr", 15, 3, 0}
/* Bytecode APIcalls END */
};
const cli_apicall_int2 cli_apicalls0[] = {
diff --git a/libclamav/matcher.c b/libclamav/matcher.c
index f9e761f..ffd17d3 100644
--- a/libclamav/matcher.c
+++ b/libclamav/matcher.c
@@ -512,7 +512,7 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
ret = CL_VIRUS; \
break; \
} \
- if(cli_bytecode_runlsig(&ctx->engine->bcs, xroot->ac_lsigtable[i]->bc, ctx->virname, xdata.lsigcnt[i], map) == CL_VIRUS) { \
+ if(cli_bytecode_runlsig(ctx, &ctx->engine->bcs, xroot->ac_lsigtable[i]->bc, ctx->virname, xdata.lsigcnt[i], map) == CL_VIRUS) { \
ret = CL_VIRUS; \
break; \
} \
diff --git a/libclamav/others.h b/libclamav/others.h
index 99274b2..47a8dc2 100644
--- a/libclamav/others.h
+++ b/libclamav/others.h
@@ -99,8 +99,14 @@ extern uint8_t cli_debug_flag;
#define NAME_MAX 256
#endif
+typedef struct bitset_tag
+{
+ unsigned char *bitset;
+ unsigned long length;
+} bitset_t;
+
/* internal clamav context */
-typedef struct {
+typedef struct cli_ctx_tag {
const char **virname;
unsigned long int *scanned;
const struct cli_matcher *root;
@@ -114,6 +120,7 @@ typedef struct {
size_t container_size;
struct cli_dconf *dconf;
fmap_t **fmap;
+ bitset_t* hook_lsig_matches;
} cli_ctx;
@@ -227,6 +234,7 @@ struct cl_engine {
struct cli_all_bc bcs;
unsigned *hooks[_BC_LAST_HOOK - _BC_START_HOOKS];
unsigned hooks_cnt[_BC_LAST_HOOK - _BC_START_HOOKS];
+ unsigned hook_lsig_ids;
};
struct cl_settings {
@@ -372,12 +380,6 @@ static inline void cli_writeint32(char *offset, uint32_t value)
#endif
#define CLI_SAR(n,s) n = CLI_SRS(n,s)
-typedef struct bitset_tag
-{
- unsigned char *bitset;
- unsigned long length;
-} bitset_t;
-
#ifdef __GNUC__
void cli_warnmsg(const char *str, ...) __attribute__((format(printf, 1, 2)));
#else
diff --git a/libclamav/pe.c b/libclamav/pe.c
index 256a11f..2645d76 100644
--- a/libclamav/pe.c
+++ b/libclamav/pe.c
@@ -2239,7 +2239,7 @@ int cli_scanpe(cli_ctx *ctx, icon_groupset *iconset)
pedata.hdr_size = hdr_size;
cli_bytecode_context_setpe(bc_ctx, &pedata);
cli_bytecode_context_setctx(bc_ctx, ctx);
- ret = cli_bytecode_runhook(ctx->engine, bc_ctx, BC_PE_UNPACKER, map, ctx->virname);
+ ret = cli_bytecode_runhook(ctx, ctx->engine, bc_ctx, BC_PE_UNPACKER, map, ctx->virname);
switch (ret) {
case CL_VIRUS:
return CL_VIRUS;
diff --git a/libclamav/readdb.c b/libclamav/readdb.c
index fed0145..e2250ed 100644
--- a/libclamav/readdb.c
+++ b/libclamav/readdb.c
@@ -1330,7 +1330,7 @@ static int cli_loadcbc(FILE *fs, struct cl_engine *engine, unsigned int *signo,
return rc;
}
sigs += 2;/* the bytecode itself and the logical sig */
- if (bc->kind == BC_LOGICAL) {
+ if (bc->kind == BC_LOGICAL || bc->lsig) {
if (!bc->lsig) {
cli_errmsg("Bytecode %s has logical kind, but missing logical signature!\n", dbname);
return CL_EMALFDB;
@@ -1342,10 +1342,13 @@ static int cli_loadcbc(FILE *fs, struct cl_engine *engine, unsigned int *signo,
bc->lsig, dbname, cl_strerror(rc));
return rc;
}
- } else {
+ }
+ if (bc->kind != BC_LOGICAL) {
if (bc->lsig) {
- cli_errmsg("Bytecode %s has logical signature but is not logical kind!\n", dbname);
- return CL_EMALFDB;
+ /* runlsig will only flip a status bit, not report a match,
+ * when the hooks are executed we only execute the hook if its
+ * status bit is on */
+ bc->hook_lsig_id = ++engine->hook_lsig_ids;
}
if (bc->kind >= _BC_START_HOOKS && bc->kind < _BC_LAST_HOOK) {
unsigned hook = bc->kind - _BC_START_HOOKS;
diff --git a/libclamav/scanners.c b/libclamav/scanners.c
index ac225b1..1cdc134 100644
--- a/libclamav/scanners.c
+++ b/libclamav/scanners.c
@@ -1815,6 +1815,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
cli_file_t current_container_type = ctx->container_type; /* TODO: container tracking code TBD - bb#1293 */
size_t current_container_size = ctx->container_size, hashed_size;
unsigned char hash[16];
+ bitset_t *old_hook_lsig_matches;
if(ctx->engine->maxreclevel && ctx->recursion > ctx->engine->maxreclevel) {
cli_dbgmsg("cli_magic_scandesc: Archive recursion limit exceeded (%u, max: %u)\n", ctx->recursion, ctx->engine->maxreclevel);
@@ -1857,6 +1858,8 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
return CL_CLEAN;
}
hashed_size = (*ctx->fmap)->len;
+ old_hook_lsig_matches = ctx->hook_lsig_matches;
+ ctx->hook_lsig_matches = NULL;
if(!ctx->options || (ctx->recursion == ctx->engine->maxreclevel)) { /* raw mode (stdin, etc.) or last level of recursion */
if(ctx->recursion == ctx->engine->maxreclevel)
@@ -1883,11 +1886,17 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
}
lseek(desc, 0, SEEK_SET); /* FIXMEFMAP: remove ? */
+ ctx->hook_lsig_matches = cli_bitset_init();
+ if (!ctx->hook_lsig_matches)
+ return CL_EMEM;
+
if(type != CL_TYPE_IGNORED && ctx->engine->sdb) {
if((ret = cli_scanraw(ctx, type, 0, &dettype)) == CL_VIRUS) {
ret = cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
funmap(*ctx->fmap);
- ctx->fmap--;
+ ctx->fmap--;
+ cli_bitset_free(ctx->hook_lsig_matches);
+ ctx->hook_lsig_matches = old_hook_lsig_matches;
return ret;
}
lseek(desc, 0, SEEK_SET); /* FIXMEFMAP: remove ? */
@@ -2134,7 +2143,9 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
if(ret == CL_VIRUS) {
ret = cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
funmap(*ctx->fmap);
- ctx->fmap--;
+ ctx->fmap--;
+ cli_bitset_free(ctx->hook_lsig_matches);
+ ctx->hook_lsig_matches = old_hook_lsig_matches;
return ret;
}
@@ -2150,7 +2161,9 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
if(cli_scanraw(ctx, type, typercg, &dettype) == CL_VIRUS) {
ret = cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
funmap(*ctx->fmap);
- ctx->fmap--;
+ ctx->fmap--;
+ cli_bitset_free(ctx->hook_lsig_matches);
+ ctx->hook_lsig_matches = old_hook_lsig_matches;
return ret;
}
}
@@ -2158,6 +2171,8 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
ctx->recursion++;
lseek(desc, 0, SEEK_SET);
switch(type) {
+ /* bytecode hooks triggered by a lsig must be a hook
+ * called from one of the functions here */
case CL_TYPE_TEXT_ASCII:
case CL_TYPE_TEXT_UTF16BE:
case CL_TYPE_TEXT_UTF16LE:
@@ -2176,13 +2191,14 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
if(SCAN_PE && ctx->dconf->pe)
ret = cli_scanpe(ctx, NULL);
break;
-
default:
break;
}
ctx->recursion--;
funmap(*ctx->fmap);
ctx->fmap--;
+ cli_bitset_free(ctx->hook_lsig_matches);
+ ctx->hook_lsig_matches = old_hook_lsig_matches;
if(ret == CL_VIRUS)
ret = cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
@@ -2219,11 +2235,12 @@ int cl_scandesc(int desc, const char **virname, unsigned long int *scanned, cons
if(!ctx.fmap)
return CL_EMEM;
ctx.fmap--;
+ ctx.hook_lsig_matches = NULL; cli_bitset_init();
rc = cli_magic_scandesc(desc, &ctx);
ctx.fmap++;
- free(ctx.fmap);
+ cli_bitset_free(ctx.hook_lsig_matches);
if(rc == CL_CLEAN && ctx.found_possibly_unwanted)
rc = CL_VIRUS;
return rc;
--
Debian repository for ClamAV
More information about the Pkg-clamav-commits
mailing list