mirror of
https://github.com/Cisco-Talos/clamav.git
synced 2026-05-06 22:55:49 -04:00
Mach-O bytecode unpackers
This commit is contained in:
committed by
Micah Snyder
parent
2b776e4b89
commit
c84683f2f4
@@ -2986,6 +2986,9 @@ void cli_bytecode_describe(const struct cli_bc *bc)
|
||||
case BC_ELF_UNPACKER:
|
||||
puts("ELF unpacker hook");
|
||||
break;
|
||||
case BC_MACHO_UNPACKER:
|
||||
puts("Mach-O unpacker hook");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown (type %u)", bc->kind);
|
||||
break;
|
||||
@@ -3033,6 +3036,12 @@ void cli_bytecode_describe(const struct cli_bc *bc)
|
||||
else
|
||||
puts("all ELF files! (unpacked)");
|
||||
break;
|
||||
case BC_MACHO_UNPACKER:
|
||||
if (bc->lsig)
|
||||
puts("Mach-O files matching logical signature (unpacked)");
|
||||
else
|
||||
puts("all Mach-O files! (unpacked)");
|
||||
break;
|
||||
default:
|
||||
puts("N/A (unknown type)\n");
|
||||
break;
|
||||
|
||||
@@ -72,6 +72,8 @@ enum BytecodeKind {
|
||||
BC_PRECLASS,
|
||||
/** specifies an ELF unpacker, executed on ELF files on a logical trigger */
|
||||
BC_ELF_UNPACKER,
|
||||
/** specifies an Mach-O unpacker, executed on Mach-O files on a logical trigger */
|
||||
BC_MACHO_UNPACKER,
|
||||
_BC_LAST_HOOK
|
||||
};
|
||||
|
||||
|
||||
@@ -120,6 +120,7 @@ enum perfev {
|
||||
PERFT_KTIME,
|
||||
PERFT_UTIME,
|
||||
PERFT_ELF,
|
||||
PERFT_MACHO,
|
||||
PERFT_LAST
|
||||
};
|
||||
|
||||
|
||||
@@ -35,6 +35,14 @@
|
||||
#include "execs.h"
|
||||
#include "scanners.h"
|
||||
|
||||
#define CLI_TMPUNLK() \
|
||||
if (!ctx->engine->keeptmp) { \
|
||||
if (cli_unlink(tempfile)) { \
|
||||
free(tempfile); \
|
||||
return CL_EUNLINK; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define EC32(v, conv) (conv ? cbswap32(v) : v)
|
||||
#define EC64(v, conv) (conv ? cbswap64(v) : v)
|
||||
|
||||
@@ -556,3 +564,55 @@ int cli_scanmacho_unibin(cli_ctx *ctx)
|
||||
|
||||
return ret; /* result from the last binary */
|
||||
}
|
||||
|
||||
int cli_unpackmacho(cli_ctx *ctx)
|
||||
{
|
||||
char *tempfile;
|
||||
int ndesc;
|
||||
struct cli_bc_ctx *bc_ctx;
|
||||
int ret;
|
||||
fmap_t *map = *ctx->fmap;
|
||||
|
||||
/* Bytecode BC_MACHO_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);
|
||||
|
||||
ret = cli_bytecode_runhook(ctx, ctx->engine, bc_ctx, BC_MACHO_UNPACKER, map);
|
||||
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_scanmacho: Unpacked and rebuilt executable saved in %s\n", tempfile);
|
||||
else
|
||||
cli_dbgmsg("cli_scanmacho: Unpacked and rebuilt executable\n");
|
||||
lseek(ndesc, 0, SEEK_SET);
|
||||
cli_dbgmsg("***** Scanning rebuilt Mach-O 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_SUCCESS;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
cli_bytecode_context_destroy(bc_ctx);
|
||||
}
|
||||
|
||||
return CL_CLEAN;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,5 +29,6 @@
|
||||
int cli_scanmacho(cli_ctx *ctx, struct cli_exe_info *fileinfo);
|
||||
int cli_machoheader(fmap_t *map, struct cli_exe_info *fileinfo);
|
||||
int cli_scanmacho_unibin(cli_ctx *ctx);
|
||||
int cli_unpackmacho(cli_ctx *ctx);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3525,6 +3525,12 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
|
||||
ret = cli_unpackelf(ctx);
|
||||
perf_nested_stop(ctx, PERFT_ELF, PERFT_SCAN);
|
||||
break;
|
||||
case CL_TYPE_MACHO:
|
||||
case CL_TYPE_MACHO_UNIBIN:
|
||||
perf_nested_start(ctx, PERFT_MACHO, PERFT_SCAN);
|
||||
ret = cli_unpackmacho(ctx);
|
||||
perf_nested_stop(ctx, PERFT_MACHO, PERFT_SCAN);
|
||||
break;
|
||||
case CL_TYPE_BINARY_DATA:
|
||||
ret = cli_fmap_scandesc(ctx, CL_TYPE_OTHER, 0, NULL, AC_SCAN_VIR, NULL, NULL);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user