|
|
|
@ -2037,42 +2037,43 @@ static void emax_reached(cli_ctx *ctx) { |
|
|
|
|
#define LINESTR(x) #x |
|
|
|
|
#define LINESTR2(x) LINESTR(x) |
|
|
|
|
#define __AT__ " at line "LINESTR2(__LINE__) |
|
|
|
|
#define ret_from_magicscan(retcode) do { \ |
|
|
|
|
cli_dbgmsg("cli_magic_scandesc: returning %d %s\n", retcode, __AT__); \
|
|
|
|
|
if(ctx->engine->cb_post_scan) { \
|
|
|
|
|
perf_start(ctx, PERFT_POSTCB); \
|
|
|
|
|
switch(ctx->engine->cb_post_scan(desc, retcode, retcode == CL_VIRUS && ctx->virname ? *ctx->virname : NULL, ctx->cb_ctx)) { \
|
|
|
|
|
case CL_BREAK: \
|
|
|
|
|
cli_dbgmsg("cli_magic_scandesc: file whitelisted by callback\n"); \
|
|
|
|
|
perf_stop(ctx, PERFT_POSTCB); \
|
|
|
|
|
return CL_CLEAN; \
|
|
|
|
|
case CL_VIRUS: \
|
|
|
|
|
cli_dbgmsg("cli_magic_scandesc: file blacklisted by callback\n"); \
|
|
|
|
|
if(ctx->virname) \
|
|
|
|
|
*ctx->virname = "Detected.By.Callback"; \
|
|
|
|
|
perf_stop(ctx, PERFT_POSTCB); \
|
|
|
|
|
return CL_VIRUS; \
|
|
|
|
|
case CL_CLEAN: \
|
|
|
|
|
break; \
|
|
|
|
|
default: \
|
|
|
|
|
cli_warnmsg("cli_magic_scandesc: ignoring bad return code from callback\n"); \
|
|
|
|
|
#define ret_from_magicscan(retcode) \ |
|
|
|
|
do { \
|
|
|
|
|
cli_dbgmsg("cli_magic_scandesc: returning %d %s\n", retcode, __AT__); \
|
|
|
|
|
if(ctx->engine->cb_post_scan) { \
|
|
|
|
|
perf_start(ctx, PERFT_POSTCB); \
|
|
|
|
|
switch(ctx->engine->cb_post_scan(desc, retcode, retcode == CL_VIRUS && ctx->virname ? *ctx->virname : NULL, ctx->cb_ctx)) { \
|
|
|
|
|
case CL_BREAK: \
|
|
|
|
|
cli_dbgmsg("cli_magic_scandesc: file whitelisted by post_scan callback\n"); \
|
|
|
|
|
perf_stop(ctx, PERFT_POSTCB); \
|
|
|
|
|
return CL_CLEAN; \
|
|
|
|
|
case CL_VIRUS: \
|
|
|
|
|
cli_dbgmsg("cli_magic_scandesc: file blacklisted by post_scan callback\n"); \
|
|
|
|
|
if(ctx->virname) \
|
|
|
|
|
*ctx->virname = "Detected.By.Callback"; \
|
|
|
|
|
perf_stop(ctx, PERFT_POSTCB); \
|
|
|
|
|
return CL_VIRUS; \
|
|
|
|
|
case CL_CLEAN: \
|
|
|
|
|
break; \
|
|
|
|
|
default: \
|
|
|
|
|
cli_warnmsg("cli_magic_scandesc: ignoring bad return code from post_scan callback\n"); \
|
|
|
|
|
} \
|
|
|
|
|
perf_stop(ctx, PERFT_POSTCB); \
|
|
|
|
|
} \
|
|
|
|
|
perf_stop(ctx, PERFT_POSTCB); \
|
|
|
|
|
}\
|
|
|
|
|
return retcode; \
|
|
|
|
|
return retcode; \
|
|
|
|
|
} while(0) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define CALL_PRESCAN_CB(type_name) \ |
|
|
|
|
if(ctx->engine->cb_pre_scan) { \
|
|
|
|
|
#define CALL_PRESCAN_CB(scanfn) \ |
|
|
|
|
if(ctx->engine->scanfn) { \
|
|
|
|
|
perf_start(ctx, PERFT_PRECB); \
|
|
|
|
|
switch(ctx->engine->cb_pre_scan(desc, (type_name), ctx->cb_ctx)) { \
|
|
|
|
|
switch(ctx->engine->scanfn(desc, filetype, ctx->cb_ctx)) { \
|
|
|
|
|
case CL_BREAK: \
|
|
|
|
|
cli_dbgmsg("cli_magic_scandesc: file whitelisted by callback\n"); \
|
|
|
|
|
cli_dbgmsg("cli_magic_scandesc: file whitelisted by "#scanfn" callback\n"); \
|
|
|
|
|
perf_stop(ctx, PERFT_PRECB); \
|
|
|
|
|
ret_from_magicscan(CL_CLEAN); \
|
|
|
|
|
case CL_VIRUS: \
|
|
|
|
|
cli_dbgmsg("cli_magic_scandesc: file blacklisted by callback\n"); \
|
|
|
|
|
cli_dbgmsg("cli_magic_scandesc: file blacklisted by "#scanfn" callback\n"); \
|
|
|
|
|
if(ctx->virname) \
|
|
|
|
|
*ctx->virname = "Detected.By.Callback"; \
|
|
|
|
|
perf_stop(ctx, PERFT_PRECB); \
|
|
|
|
@ -2097,6 +2098,7 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
|
|
|
|
unsigned char hash[16]; |
|
|
|
|
bitset_t *old_hook_lsig_matches; |
|
|
|
|
int desc = (*ctx->fmap)->fd; |
|
|
|
|
const char *filetype; |
|
|
|
|
|
|
|
|
|
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); |
|
|
|
@ -2119,6 +2121,18 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
|
|
|
|
ret_from_magicscan(CL_CLEAN); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
perf_start(ctx, PERFT_FT); |
|
|
|
|
if(type == CL_TYPE_ANY) |
|
|
|
|
type = cli_filetype2(*ctx->fmap, ctx->engine); |
|
|
|
|
perf_stop(ctx, PERFT_FT); |
|
|
|
|
if(type == CL_TYPE_ERROR) { |
|
|
|
|
cli_dbgmsg("cli_magic_scandesc: cli_filetype2 returned CL_TYPE_ERROR\n"); |
|
|
|
|
ctx->hook_lsig_matches = old_hook_lsig_matches; |
|
|
|
|
ret_from_magicscan(CL_EREAD); |
|
|
|
|
} |
|
|
|
|
filetype = cli_ftname(type); |
|
|
|
|
CALL_PRESCAN_CB(cb_pre_cache); |
|
|
|
|
|
|
|
|
|
perf_start(ctx, PERFT_CACHE); |
|
|
|
|
if(cache_check(hash, ctx) == CL_CLEAN) { |
|
|
|
|
perf_stop(ctx, PERFT_CACHE); |
|
|
|
@ -2135,7 +2149,7 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
|
|
|
|
else |
|
|
|
|
cli_dbgmsg("Raw mode: No support for special files\n"); |
|
|
|
|
|
|
|
|
|
CALL_PRESCAN_CB("CL_TYPE_BINARY_DATA"); |
|
|
|
|
CALL_PRESCAN_CB(cb_pre_scan); |
|
|
|
|
if((ret = cli_fmap_scandesc(ctx, 0, 0, NULL, AC_SCAN_VIR, NULL, hash)) == CL_VIRUS) |
|
|
|
|
cli_dbgmsg("%s found in descriptor %d\n", *ctx->virname, desc); |
|
|
|
|
else if(ret == CL_CLEAN) { |
|
|
|
@ -2149,17 +2163,7 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
|
|
|
|
ret_from_magicscan(ret); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
perf_start(ctx, PERFT_FT); |
|
|
|
|
if(type == CL_TYPE_ANY) |
|
|
|
|
type = cli_filetype2(*ctx->fmap, ctx->engine); |
|
|
|
|
perf_stop(ctx, PERFT_FT); |
|
|
|
|
if(type == CL_TYPE_ERROR) { |
|
|
|
|
cli_dbgmsg("cli_magic_scandesc: cli_filetype2 returned CL_TYPE_ERROR\n"); |
|
|
|
|
ctx->hook_lsig_matches = old_hook_lsig_matches; |
|
|
|
|
ret_from_magicscan(CL_EREAD); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
CALL_PRESCAN_CB(cli_ftname(type)); |
|
|
|
|
CALL_PRESCAN_CB(cb_pre_scan); |
|
|
|
|
|
|
|
|
|
#ifdef HAVE__INTERNAL__SHA_COLLECT |
|
|
|
|
if(!ctx->sha_collect && type==CL_TYPE_MSEXE) ctx->sha_collect = 1; |
|
|
|
|