mirror of
https://github.com/Cisco-Talos/clamav.git
synced 2025-10-19 10:23:17 +00:00
Linux bytecode unpackers
This commit is contained in:
parent
ddc1c9bb11
commit
2b776e4b89
6 changed files with 86 additions and 0 deletions
|
@ -2983,6 +2983,9 @@ void cli_bytecode_describe(const struct cli_bc *bc)
|
|||
case BC_PRECLASS:
|
||||
puts("preclass hook");
|
||||
break;
|
||||
case BC_ELF_UNPACKER:
|
||||
puts("ELF unpacker hook");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown (type %u)", bc->kind);
|
||||
break;
|
||||
|
@ -3024,6 +3027,12 @@ void cli_bytecode_describe(const struct cli_bc *bc)
|
|||
else
|
||||
puts("all PRECLASS files!");
|
||||
break;
|
||||
case BC_ELF_UNPACKER:
|
||||
if (bc->lsig)
|
||||
puts("ELF files matching logical signature (unpacked)");
|
||||
else
|
||||
puts("all ELF files! (unpacked)");
|
||||
break;
|
||||
default:
|
||||
puts("N/A (unknown type)\n");
|
||||
break;
|
||||
|
|
|
@ -70,6 +70,8 @@ enum BytecodeKind {
|
|||
/** specifies a PRECLASS hook, executes at the end of file property collection and
|
||||
* operates on the original file targeted for property collection */
|
||||
BC_PRECLASS,
|
||||
/** specifies an ELF unpacker, executed on ELF files on a logical trigger */
|
||||
BC_ELF_UNPACKER,
|
||||
_BC_LAST_HOOK
|
||||
};
|
||||
|
||||
|
|
|
@ -42,11 +42,21 @@
|
|||
#include "clamav.h"
|
||||
#include "execs.h"
|
||||
#include "matcher.h"
|
||||
#include "scanners.h"
|
||||
|
||||
#define EC16(v, conv) (conv ? cbswap16(v) : v)
|
||||
#define EC32(v, conv) (conv ? cbswap32(v) : v)
|
||||
#define EC64(v, conv) (conv ? cbswap64(v) : v)
|
||||
|
||||
|
||||
#define CLI_TMPUNLK() \
|
||||
if (!ctx->engine->keeptmp) { \
|
||||
if (cli_unlink(tempfile)) { \
|
||||
free(tempfile); \
|
||||
return CL_EUNLINK; \
|
||||
} \
|
||||
}
|
||||
|
||||
static void cli_elf_sectionlog(uint32_t sh_type, uint32_t sh_flags);
|
||||
|
||||
static uint32_t cli_rawaddr32(uint32_t vaddr, struct elf_program_hdr32 *ph, uint16_t phnum, uint8_t conv, uint8_t *err)
|
||||
|
@ -834,3 +844,60 @@ int cli_elfheader(fmap_t *map, struct cli_exe_info *elfinfo)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ELF file unpacking.
|
||||
*/
|
||||
int cli_unpackelf(cli_ctx *ctx)
|
||||
{
|
||||
char *tempfile;
|
||||
int ndesc;
|
||||
struct cli_bc_ctx *bc_ctx;
|
||||
int ret;
|
||||
fmap_t *map = *ctx->fmap;
|
||||
|
||||
/* Bytecode BC_ELF_UNPACKER hook */
|
||||
bc_ctx = cli_bytecode_context_alloc();
|
||||
if (!bc_ctx) {
|
||||
cli_errmsg("cli_scanelf: can't allocate memory for bc_ctx\n");
|
||||
return CL_EMEM;
|
||||
}
|
||||
|
||||
cli_bytecode_context_setctx(bc_ctx, ctx);
|
||||
|
||||
cli_dbgmsg("Running bytecode hook\n");
|
||||
ret = cli_bytecode_runhook(ctx, ctx->engine, bc_ctx, BC_ELF_UNPACKER, map);
|
||||
cli_dbgmsg("Finished running bytecode hook\n");
|
||||
switch (ret) {
|
||||
case CL_VIRUS:
|
||||
cli_bytecode_context_destroy(bc_ctx);
|
||||
return CL_VIRUS;
|
||||
case CL_SUCCESS:
|
||||
ndesc = cli_bytecode_context_getresult_file(bc_ctx, &tempfile);
|
||||
cli_bytecode_context_destroy(bc_ctx);
|
||||
if (ndesc != -1 && tempfile) {
|
||||
if (ctx->engine->keeptmp)
|
||||
cli_dbgmsg("cli_scanelf: Unpacked and rebuilt executable saved in %s\n", tempfile);
|
||||
else
|
||||
cli_dbgmsg("cli_scanelf: Unpacked and rebuilt executable\n");
|
||||
lseek(ndesc, 0, SEEK_SET);
|
||||
cli_dbgmsg("***** Scanning rebuilt ELF file *****\n");
|
||||
if (cli_magic_scandesc(ndesc, tempfile, ctx) == CL_VIRUS) {
|
||||
close(ndesc);
|
||||
CLI_TMPUNLK();
|
||||
free(tempfile);
|
||||
return CL_VIRUS;
|
||||
}
|
||||
close(ndesc);
|
||||
CLI_TMPUNLK();
|
||||
free(tempfile);
|
||||
return CL_CLEAN;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
cli_bytecode_context_destroy(bc_ctx);
|
||||
}
|
||||
|
||||
return CL_CLEAN;
|
||||
}
|
||||
|
||||
|
|
|
@ -147,4 +147,6 @@ int cli_scanelf(cli_ctx *ctx);
|
|||
|
||||
int cli_elfheader(fmap_t *map, struct cli_exe_info *elfinfo);
|
||||
|
||||
int cli_unpackelf(cli_ctx *ctx);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -119,6 +119,7 @@ enum perfev {
|
|||
PERFT_BYTECODE,
|
||||
PERFT_KTIME,
|
||||
PERFT_UTIME,
|
||||
PERFT_ELF,
|
||||
PERFT_LAST
|
||||
};
|
||||
|
||||
|
|
|
@ -3520,6 +3520,11 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
|
|||
}
|
||||
perf_nested_stop(ctx, PERFT_PE, PERFT_SCAN);
|
||||
break;
|
||||
case CL_TYPE_ELF:
|
||||
perf_nested_start(ctx, PERFT_ELF, PERFT_SCAN);
|
||||
ret = cli_unpackelf(ctx);
|
||||
perf_nested_stop(ctx, PERFT_ELF, PERFT_SCAN);
|
||||
break;
|
||||
case CL_TYPE_BINARY_DATA:
|
||||
ret = cli_fmap_scandesc(ctx, CL_TYPE_OTHER, 0, NULL, AC_SCAN_VIR, NULL, NULL);
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue