[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:06:52 UTC 2010
The following commit has been merged in the debian/unstable branch:
commit ab63657088ee8db1bb9c7824320afa69d56a067b
Author: Török Edvin <edwin at clamav.net>
Date: Fri Oct 2 17:33:11 2009 +0300
Add generic and PE hooks.
diff --git a/libclamav/bytecode.c b/libclamav/bytecode.c
index d686998..71484b7 100644
--- a/libclamav/bytecode.c
+++ b/libclamav/bytecode.c
@@ -26,6 +26,7 @@
#include "clamav.h"
#include "others.h"
+#include "pe.h"
#include "bytecode.h"
#include "bytecode_priv.h"
#include "readdb.h"
@@ -45,6 +46,7 @@ struct cli_bc_ctx *cli_bytecode_context_alloc(void)
ctx->fd = -1;
ctx->off = 0;
ctx->hooks.match_counts = nomatch;
+ /* TODO: init all hooks with safe values */
ctx->virname = NULL;
return ctx;
}
@@ -55,11 +57,18 @@ void cli_bytecode_context_destroy(struct cli_bc_ctx *ctx)
free(ctx);
}
-int cli_bytecode_context_clear(struct cli_bc_ctx *ctx)
+/* resets bytecode state, so you can run another bytecode with same ctx */
+int cli_bytecode_context_reset(struct cli_bc_ctx *ctx)
{
free(ctx->opsizes);
free(ctx->values);
free(ctx->operands);
+ return CL_SUCCESS;
+}
+
+int cli_bytecode_context_clear(struct cli_bc_ctx *ctx)
+{
+ cli_bytecode_context_reset(ctx);
memset(ctx, 0, sizeof(ctx));
return CL_SUCCESS;
}
@@ -1435,7 +1444,46 @@ int cli_bytecode_runlsig(const struct cli_all_bc *bcs, const struct cli_bc *bc,
return CL_VIRUS;
}
ret = cli_bytecode_context_getresult_int(&ctx);
- cli_dbgmsg("Bytecode returned code: %u\n", ret);
+ cli_dbgmsg("Bytecode %u returned code: %u\n", bc->id, ret);
cli_bytecode_context_clear(&ctx);
return CL_SUCCESS;
}
+
+int cli_bytecode_runhook(const struct cl_engine *engine, struct cli_bc_ctx *ctx,
+ unsigned id, int fd, const char **virname)
+{
+ const unsigned *hooks = engine->hooks[id - _BC_START_HOOKS];
+ unsigned i, hooks_cnt = engine->hooks_cnt[id - _BC_START_HOOKS];
+ int ret;
+
+ cli_bytecode_context_setfile(ctx, fd);
+ 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]];
+ cli_bytecode_context_setfuncid(ctx, bc, 0);
+ ret = cli_bytecode_run(&engine->bcs, bc, ctx);
+ if (ret != CL_SUCCESS) {
+ cli_warnmsg("Bytecode failed to run: %s\n", cl_strerror(ret));
+ return CL_SUCCESS;
+ }
+ if (ctx->virname) {
+ cli_dbgmsg("Bytecode found virus: %s\n", ctx->virname);
+ if (virname)
+ *virname = ctx->virname;
+ cli_bytecode_context_clear(ctx);
+ return CL_VIRUS;
+ }
+ ret = cli_bytecode_context_getresult_int(ctx);
+ /* TODO: use prefix here */
+ cli_dbgmsg("Bytecode %u returned %u\n", bc->id, ret);
+ cli_bytecode_context_reset(ctx);
+ }
+ return CL_CLEAN;
+}
+
+int cli_bytecode_context_setpe(struct cli_bc_ctx *ctx, const struct cli_pe_hook_data *data)
+{
+ ctx->hooks.exeinfo = &data->exe_info;
+ ctx->hooks.pedata = data;
+ return 0;
+}
diff --git a/libclamav/bytecode.h b/libclamav/bytecode.h
index 1cf9d98..a10a133 100644
--- a/libclamav/bytecode.h
+++ b/libclamav/bytecode.h
@@ -32,6 +32,7 @@ struct cli_bc_inst;
struct cli_bc_type;
struct cli_bc_engine;
struct bitset_tag;
+struct cl_engine;
enum bc_state {
bc_skip,
@@ -65,11 +66,13 @@ struct cli_all_bc {
struct cli_bcengine *engine;
};
+struct cli_pe_hook_data;
struct cli_bc_ctx *cli_bytecode_context_alloc(void);
int cli_bytecode_context_setfuncid(struct cli_bc_ctx *ctx, const struct cli_bc *bc, unsigned funcid);
int cli_bytecode_context_setparam_int(struct cli_bc_ctx *ctx, unsigned i, uint64_t c);
int cli_bytecode_context_setparam_ptr(struct cli_bc_ctx *ctx, unsigned i, void *data, unsigned datalen);
int cli_bytecode_context_setfile(struct cli_bc_ctx *ctx, int fd);
+int cli_bytecode_context_setpe(struct cli_bc_ctx *ctx, const struct cli_pe_hook_data *data);
int cli_bytecode_context_clear(struct cli_bc_ctx *ctx);
uint64_t cli_bytecode_context_getresult_int(struct cli_bc_ctx *ctx);
void cli_bytecode_context_destroy(struct cli_bc_ctx *ctx);
@@ -83,7 +86,9 @@ void cli_bytecode_destroy(struct cli_bc *bc);
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, int fd);
+int cli_bytecode_runhook(const struct cl_engine *engine, struct cli_bc_ctx *ctx, unsigned id, int fd, const char **virname);
#ifdef __cplusplus
extern "C" {
diff --git a/libclamav/bytecode_api.h b/libclamav/bytecode_api.h
index ae736a3..88c44ad 100644
--- a/libclamav/bytecode_api.h
+++ b/libclamav/bytecode_api.h
@@ -19,6 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
+#ifndef BYTECODE_API_H
+#define BYTECODE_API_H
#ifdef __CLAMBC__
#include "bytecode_execs.h"
@@ -32,16 +34,19 @@ struct foo {
struct foo *nxt;
};
+enum BytecodeKind {
+ BC_GENERIC=0,/* generic bytecode, not tied to a specific hook */
+ _BC_START_HOOKS=256,
+ BC_LOGICAL=256,/* triggered by a logical signature */
+ BC_PE_UNPACKER,/* a PE unpacker */
+ _BC_LAST_HOOK
+};
+
#ifdef __CLAMBC__
extern const uint32_t __clambc_match_counts[64];
extern const struct cli_exe_info __clambc_exeinfo;
-enum BytecodeKind {
- BC_GENERIC=0,/* generic bytecode, not tied to a specific hook */
- BC_LOGICAL,/* triggered by a logical signature */
- BC_PE_UNPACKER,/* a PE unpacker */
-};
const uint8_t __clambc_kind;
uint32_t test0(struct foo*, uint32_t);
@@ -68,3 +73,4 @@ uint32_t debug_print_uint(uint32_t a, uint32_t b);
//const char *LogicalSignature;
#endif
+#endif
diff --git a/libclamav/bytecode_hooks.h b/libclamav/bytecode_hooks.h
index 47305f5..a068dc2 100644
--- a/libclamav/bytecode_hooks.h
+++ b/libclamav/bytecode_hooks.h
@@ -24,7 +24,8 @@
struct cli_bc_hooks {
const uint32_t* match_counts;
- const struct cli_exe_info exeinfo;
+ const struct cli_exe_info *exeinfo;
+ const struct cli_pe_hook_data *pedata;
const uint8_t kind;
};
#endif
diff --git a/libclamav/others.h b/libclamav/others.h
index e74038b..b1dd94f 100644
--- a/libclamav/others.h
+++ b/libclamav/others.h
@@ -41,6 +41,7 @@
#include "libclamunrar_iface/unrar_iface.h"
#include "regex/regex.h"
#include "bytecode.h"
+#include "bytecode_api.h"
/*
* CL_FLEVEL is the signature f-level specific to the current code and
@@ -181,6 +182,8 @@ struct cl_engine {
/* Used for bytecode */
struct cli_all_bc bcs;
+ unsigned *hooks[_BC_LAST_HOOK - _BC_START_HOOKS];
+ unsigned hooks_cnt[_BC_LAST_HOOK - _BC_START_HOOKS];
};
struct cl_settings {
diff --git a/libclamav/pe.c b/libclamav/pe.c
index c8b1029..ae3285f 100644
--- a/libclamav/pe.c
+++ b/libclamav/pe.c
@@ -439,18 +439,20 @@ int cli_scanpe(int desc, cli_ctx *ctx)
char *src = NULL, *dest = NULL;
int ndesc, ret = CL_CLEAN, upack = 0, native=0;
size_t fsize;
- uint32_t valign, falign, hdr_size, j;
+ uint32_t valign, falign, hdr_size, j, offset;
struct cli_exe_section *exe_sections;
struct cli_matcher *md5_sect;
char timestr[32];
struct pe_image_data_dir *dirs;
+ struct cli_bc_ctx *bc_ctx;
+ struct cli_pe_hook_data pedata;
if(!ctx) {
cli_errmsg("cli_scanpe: ctx == NULL\n");
return CL_ENULLARG;
}
-
+ offset = lseek(desc, 0, SEEK_CUR);
if(cli_readn(desc, &e_magic, sizeof(e_magic)) != sizeof(e_magic)) {
cli_dbgmsg("Can't read DOS signature\n");
return CL_CLEAN;
@@ -2252,6 +2254,27 @@ int cli_scanpe(int desc, cli_ctx *ctx)
/* to be continued ... */
+ /* Bytecode */
+ bc_ctx = cli_bytecode_context_alloc();
+ if (!bc_ctx) {
+ cli_errmsg("cli_scanpe: can't allocate memory for bc_ctx\n");
+ return CL_EMEM;
+ }
+ pedata.exe_info.section = exe_sections;
+ pedata.exe_info.nsections = nsections;
+ pedata.exe_info.ep = ep;
+ pedata.exe_info.offset = offset;
+ pedata.file_hdr = &file_hdr;
+ pedata.opt32 = &pe_opt.opt32;
+ pedata.opt64 = &pe_opt.opt64;
+ pedata.dirs = dirs;
+ pedata.overlays = overlays;
+ pedata.overlays_sz = fsize - overlays;
+ cli_bytecode_context_setpe(bc_ctx, &pedata);
+ if (cli_bytecode_runhook(ctx->engine, bc_ctx, BC_PE_UNPACKER, desc, ctx->virname) == CL_VIRUS)
+ return CL_VIRUS;
+ cli_bytecode_context_destroy(bc_ctx);
+
free(exe_sections);
return CL_CLEAN;
}
diff --git a/libclamav/pe.h b/libclamav/pe.h
index a8ad47a..35cab9e 100644
--- a/libclamav/pe.h
+++ b/libclamav/pe.h
@@ -128,6 +128,16 @@ struct pe_image_section_hdr {
uint32_t Characteristics;
};
+struct cli_pe_hook_data {
+ struct cli_exe_info exe_info;
+ struct pe_image_file_hdr *file_hdr;
+ struct pe_image_optional_hdr32 *opt32;
+ struct pe_image_optional_hdr64 *opt64;
+ struct pe_image_data_dir *dirs;
+ uint32_t overlays;
+ int32_t overlays_sz;
+};
+
int cli_scanpe(int desc, cli_ctx *ctx);
int cli_peheader(int desc, struct cli_exe_info *peinfo);
diff --git a/libclamav/readdb.c b/libclamav/readdb.c
index 4251d75..cf4e15e 100644
--- a/libclamav/readdb.c
+++ b/libclamav/readdb.c
@@ -70,6 +70,7 @@
#include "mpool.h"
#include "bytecode.h"
+#include "bytecode_api.h"
#include "bytecode_priv.h"
#ifdef CL_THREAD_SAFE
# include <pthread.h>
@@ -1044,6 +1045,7 @@ static int cli_loadcbc(FILE *fs, struct cl_engine *engine, unsigned int *signo,
struct cli_bc *bc;
unsigned sigs = 0;
+ /* TODO: virusname have a common prefix, and whitelist by that */
if((rc = cli_initroots(engine, options)))
return rc;
@@ -1059,18 +1061,42 @@ static int cli_loadcbc(FILE *fs, struct cl_engine *engine, unsigned int *signo,
bc = &bcs->all_bcs[bcs->count-1];
rc = cli_bytecode_load(bc, fs, dbio);
if (rc != CL_SUCCESS) {
- fprintf(stderr,"Unable to load %s bytecode: %s\n", dbname, cl_strerror(rc));
+ cli_errmsg("Unable to load %s bytecode: %s\n", dbname, cl_strerror(rc));
return rc;
}
sigs += 2;/* the bytecode itself and the logical sig */
- if (bc->lsig) {
+ if (bc->kind == BC_LOGICAL) {
+ if (!bc->lsig) {
+ cli_errmsg("Bytecode %s has logical kind, but missing logical signature!\n", dbname);
+ return CL_EMALFDB;
+ }
cli_dbgmsg("Bytecode %s has logical signature: %s\n", dbname, bc->lsig);
rc = load_oneldb(bc->lsig, 0, 0, engine, options, dbname, 0, &sigs, bc, NULL);
if (rc != CL_SUCCESS) {
- fprintf(stderr,"Problem parsing logical signature %s for bytecode %s: %s\n",
- bc->lsig, dbname, cl_strerror(rc));
+ cli_errmsg("Problem parsing logical signature %s for bytecode %s: %s\n",
+ bc->lsig, dbname, cl_strerror(rc));
return rc;
}
+ } else {
+ if (bc->lsig) {
+ cli_errmsg("Bytecode %s has logical signature but is not logical kind!\n", dbname);
+ return CL_EMALFDB;
+ }
+ if (bc->kind >= _BC_START_HOOKS && bc->kind < _BC_LAST_HOOK) {
+ unsigned hook = bc->kind - _BC_START_HOOKS;
+ unsigned cnt = ++engine->hooks_cnt[hook];
+ engine->hooks[hook] = cli_realloc2(engine->hooks[hook],
+ sizeof(*engine->hooks[0])*cnt);
+ if (!engine->hooks[hook]) {
+ cli_errmsg("Out of memory allocating memory for hook %u", hook);
+ return CL_EMEM;
+ }
+ engine->hooks[hook][cnt-1] = bcs->count-1;
+ } else switch (bc->kind) {
+ default:
+ cli_errmsg("Bytecode: unhandled bytecode kind %u\n", bc->kind);
+ return CL_EMALFDB;
+ }
}
if (signo)
*signo += sigs;
@@ -2199,6 +2225,9 @@ int cl_engine_free(struct cl_engine *engine)
cli_bytecode_destroy(&engine->bcs.all_bcs[i]);
cli_bytecode_done(&engine->bcs);
free(engine->bcs.all_bcs);
+ for (i=0;i<_BC_LAST_HOOK - _BC_START_HOOKS;i++) {
+ free (engine->hooks[i]);
+ }
}
if(engine->dconf->phishing & PHISHING_CONF_ENGINE)
phishing_done(engine);
@@ -2286,7 +2315,7 @@ int cl_engine_compile(struct cl_engine *engine)
/* Compile bytecode */
if((ret = cli_bytecode_prepare(&engine->bcs))) {
- fprintf(stderr,"Unable to compile/load bytecode: %s\n", cl_strerror(ret));
+ cli_errmsg("Unable to compile/load bytecode: %s\n", cl_strerror(ret));
return ret;
}
--
Debian repository for ClamAV
More information about the Pkg-clamav-commits
mailing list