... | ... |
@@ -1612,13 +1612,15 @@ int cli_bytecode_run(const struct cli_all_bc *bcs, const struct cli_bc *bc, stru |
1612 | 1612 |
|
1613 | 1613 |
int test_mode = 0; |
1614 | 1614 |
cli_ctx *cctx =(cli_ctx*)ctx->ctx; |
1615 |
- if (cctx && cctx->engine->bytecode_mode == CL_BYTECODE_MODE_TEST) |
|
1616 |
- test_mode = 1; |
|
1617 | 1615 |
|
1618 | 1616 |
if (!ctx || !ctx->bc || !ctx->func) |
1619 | 1617 |
return CL_ENULLARG; |
1620 | 1618 |
if (ctx->numParams && (!ctx->values || !ctx->operands)) |
1621 | 1619 |
return CL_ENULLARG; |
1620 |
+ |
|
1621 |
+ if (cctx && cctx->engine->bytecode_mode == CL_BYTECODE_MODE_TEST) |
|
1622 |
+ test_mode = 1; |
|
1623 |
+ |
|
1622 | 1624 |
if (bc->state == bc_loaded) { |
1623 | 1625 |
cli_errmsg("bytecode has to be prepared either for interpreter or JIT!\n"); |
1624 | 1626 |
return CL_EARG; |
... | ... |
@@ -1628,7 +1630,7 @@ int cli_bytecode_run(const struct cli_all_bc *bcs, const struct cli_bc *bc, stru |
1628 | 1628 |
return CL_SUCCESS; |
1629 | 1629 |
} |
1630 | 1630 |
if (cctx) |
1631 |
- cli_event_time_start(cctx->perf, PERFT_BYTECODE); |
|
1631 |
+ cli_event_time_start(cctx->perf, PERFT_BYTECODE); |
|
1632 | 1632 |
ctx->env = &bcs->env; |
1633 | 1633 |
context_safe(ctx); |
1634 | 1634 |
if (test_mode) { |
... | ... |
@@ -1742,7 +1744,7 @@ int cli_bytecode_run(const struct cli_all_bc *bcs, const struct cli_bc *bc, stru |
1742 | 1742 |
cli_events_free(jit_ev); |
1743 | 1743 |
cli_events_free(interp_ev); |
1744 | 1744 |
if (cctx) |
1745 |
- cli_event_time_stop(cctx->perf, PERFT_BYTECODE); |
|
1745 |
+ cli_event_time_stop(cctx->perf, PERFT_BYTECODE); |
|
1746 | 1746 |
return ret; |
1747 | 1747 |
} |
1748 | 1748 |
|
... | ... |
@@ -1900,6 +1902,7 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc) |
1900 | 1900 |
unsigned i, j, k; |
1901 | 1901 |
uint64_t *gmap; |
1902 | 1902 |
unsigned bcglobalid = cli_apicall_maxglobal - _FIRST_GLOBAL+2; |
1903 |
+ int ret=CL_SUCCESS; |
|
1903 | 1904 |
bc->numGlobalBytes = 0; |
1904 | 1905 |
gmap = cli_malloc(bc->num_globals*sizeof(*gmap)); |
1905 | 1906 |
if (!gmap) |
... | ... |
@@ -1914,8 +1917,10 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc) |
1914 | 1914 |
} |
1915 | 1915 |
if (bc->numGlobalBytes) { |
1916 | 1916 |
bc->globalBytes = cli_calloc(1, bc->numGlobalBytes); |
1917 |
- if (!bc->globalBytes) |
|
1917 |
+ if (!bc->globalBytes) { |
|
1918 |
+ free(gmap); |
|
1918 | 1919 |
return CL_EMEM; |
1920 |
+ } |
|
1919 | 1921 |
} else |
1920 | 1922 |
bc->globalBytes = NULL; |
1921 | 1923 |
|
... | ... |
@@ -1975,14 +1980,14 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc) |
1975 | 1975 |
} |
1976 | 1976 |
} |
1977 | 1977 |
|
1978 |
- for (i=0;i<bc->num_func;i++) { |
|
1978 |
+ for (i=0;i<bc->num_func && ret == CL_SUCCESS;i++) { |
|
1979 | 1979 |
struct cli_bc_func *bcfunc = &bc->funcs[i]; |
1980 | 1980 |
unsigned totValues = bcfunc->numValues + bcfunc->numConstants + bc->num_globals; |
1981 | 1981 |
unsigned *map = cli_malloc(sizeof(*map)*totValues); |
1982 | 1982 |
if (!map) |
1983 |
- return CL_EMEM; |
|
1983 |
+ ret = CL_EMEM; |
|
1984 | 1984 |
bcfunc->numBytes = 0; |
1985 |
- for (j=0;j<bcfunc->numValues;j++) { |
|
1985 |
+ for (j=0;j<bcfunc->numValues && ret == CL_SUCCESS;j++) { |
|
1986 | 1986 |
uint16_t ty = bcfunc->types[j]; |
1987 | 1987 |
unsigned align; |
1988 | 1988 |
align = typealign(bc, ty); |
... | ... |
@@ -1999,7 +2004,7 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc) |
1999 | 1999 |
map[bcfunc->numValues+j] = bcfunc->numBytes; |
2000 | 2000 |
bcfunc->numBytes += 8; |
2001 | 2001 |
} |
2002 |
- for (j=0;j<bcfunc->numInsts;j++) { |
|
2002 |
+ for (j=0;j<bcfunc->numInsts && ret == CL_SUCCESS;j++) { |
|
2003 | 2003 |
struct cli_bc_inst *inst = &bcfunc->allinsts[j]; |
2004 | 2004 |
inst->dest = map[inst->dest]; |
2005 | 2005 |
switch (inst->opcode) { |
... | ... |
@@ -2057,27 +2062,33 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc) |
2057 | 2057 |
target = &bc->funcs[inst->u.ops.funcid]; |
2058 | 2058 |
if (inst->u.ops.funcid > bc->num_func) { |
2059 | 2059 |
cli_errmsg("bytecode: called function out of range: %u > %u\n", inst->u.ops.funcid, bc->num_func); |
2060 |
- return CL_EBYTECODE; |
|
2060 |
+ ret = CL_EBYTECODE; |
|
2061 | 2061 |
} |
2062 |
+ if (ret != CL_SUCCESS) |
|
2063 |
+ break; |
|
2062 | 2064 |
if (inst->u.ops.numOps != target->numArgs) { |
2063 | 2065 |
cli_errmsg("bytecode: call operands don't match function prototype\n"); |
2064 |
- return CL_EBYTECODE; |
|
2066 |
+ ret = CL_EBYTECODE; |
|
2065 | 2067 |
} |
2066 | 2068 |
} else { |
2067 | 2069 |
/* APIs have at most 2 parameters always */ |
2068 | 2070 |
if (inst->u.ops.numOps > 5) { |
2069 | 2071 |
cli_errmsg("bytecode: call operands don't match function prototype\n"); |
2070 |
- return CL_EBYTECODE; |
|
2072 |
+ ret = CL_EBYTECODE; |
|
2071 | 2073 |
} |
2074 |
+ if (ret != CL_SUCCESS) |
|
2075 |
+ break; |
|
2072 | 2076 |
} |
2073 | 2077 |
if (inst->u.ops.numOps) { |
2074 | 2078 |
inst->u.ops.opsizes = cli_malloc(sizeof(*inst->u.ops.opsizes)*inst->u.ops.numOps); |
2075 | 2079 |
if (!inst->u.ops.opsizes) { |
2076 | 2080 |
cli_errmsg("Out of memory when allocating operand sizes\n"); |
2077 |
- return CL_EMEM; |
|
2081 |
+ ret = CL_EMEM; |
|
2078 | 2082 |
} |
2079 | 2083 |
} else |
2080 | 2084 |
inst->u.ops.opsizes = NULL; |
2085 |
+ if (ret != CL_SUCCESS) |
|
2086 |
+ break; |
|
2081 | 2087 |
for (k=0;k<inst->u.ops.numOps;k++) { |
2082 | 2088 |
MAPPTR(inst->u.ops.ops[k]); |
2083 | 2089 |
if (inst->opcode == OP_BC_CALL_DIRECT) |
... | ... |
@@ -2094,13 +2105,15 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc) |
2094 | 2094 |
if (inst->u.three[1]&0x80000000 || |
2095 | 2095 |
bcfunc->types[inst->u.binop[1]]&0x8000) { |
2096 | 2096 |
cli_errmsg("bytecode: gep1 of alloca is not allowed\n"); |
2097 |
- return CL_EBYTECODE; |
|
2097 |
+ ret = CL_EBYTECODE; |
|
2098 | 2098 |
} |
2099 |
+ if (ret != CL_SUCCESS) |
|
2100 |
+ break; |
|
2099 | 2101 |
MAP(inst->u.three[1]); |
2100 | 2102 |
MAP(inst->u.three[2]); |
2101 | 2103 |
inst->u.three[0] = get_geptypesize(bc, inst->u.three[0]); |
2102 | 2104 |
if (inst->u.three[0] == -1) |
2103 |
- return CL_EBYTECODE; |
|
2105 |
+ ret = CL_EBYTECODE; |
|
2104 | 2106 |
break; |
2105 | 2107 |
case OP_BC_GEPZ: |
2106 | 2108 |
/*three[0] is the type*/ |
... | ... |
@@ -2111,8 +2124,9 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc) |
2111 | 2111 |
inst->interp_op = 5*(inst->interp_op/5)+3; |
2112 | 2112 |
MAP(inst->u.three[1]); |
2113 | 2113 |
if (calc_gepz(bc, bcfunc, inst->u.three[0], inst->u.three[2]) == -1) |
2114 |
- return CL_EBYTECODE; |
|
2115 |
- MAP(inst->u.three[2]); |
|
2114 |
+ ret = CL_EBYTECODE; |
|
2115 |
+ if (ret == CL_SUCCESS) |
|
2116 |
+ MAP(inst->u.three[2]); |
|
2116 | 2117 |
break; |
2117 | 2118 |
/* case OP_BC_GEPN: |
2118 | 2119 |
*TODO |
... | ... |
@@ -2144,14 +2158,15 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc) |
2144 | 2144 |
break; |
2145 | 2145 |
default: |
2146 | 2146 |
cli_warnmsg("Bytecode: unhandled opcode: %d\n", inst->opcode); |
2147 |
- return CL_EBYTECODE; |
|
2147 |
+ ret = CL_EBYTECODE; |
|
2148 | 2148 |
} |
2149 | 2149 |
} |
2150 |
- free(map); |
|
2150 |
+ if (map) |
|
2151 |
+ free(map); |
|
2151 | 2152 |
} |
2152 | 2153 |
free(gmap); |
2153 | 2154 |
bc->state = bc_interp; |
2154 |
- return CL_SUCCESS; |
|
2155 |
+ return ret; |
|
2155 | 2156 |
} |
2156 | 2157 |
|
2157 | 2158 |
static int add_selfcheck(struct cli_all_bc *bcs) |
... | ... |
@@ -2648,6 +2663,9 @@ int cli_bytecode_runhook(cli_ctx *cctx, const struct cl_engine *engine, struct c |
2648 | 2648 |
int ret; |
2649 | 2649 |
unsigned executed = 0, breakflag = 0, errorflag = 0; |
2650 | 2650 |
|
2651 |
+ if (!cctx) |
|
2652 |
+ return CL_ENULLARG; |
|
2653 |
+ |
|
2651 | 2654 |
cli_dbgmsg("Bytecode executing hook id %u (%u hooks)\n", id, hooks_cnt); |
2652 | 2655 |
/* restore match counts */ |
2653 | 2656 |
cli_bytecode_context_setfile(ctx, map); |
... | ... |
@@ -2687,7 +2705,7 @@ int cli_bytecode_runhook(cli_ctx *cctx, const struct cl_engine *engine, struct c |
2687 | 2687 |
char *tempfile; |
2688 | 2688 |
int fd = cli_bytecode_context_getresult_file(ctx, &tempfile); |
2689 | 2689 |
if (fd && fd != -1) { |
2690 |
- if (cctx && cctx->engine->keeptmp) |
|
2690 |
+ if (cctx->engine->keeptmp) |
|
2691 | 2691 |
cli_dbgmsg("Bytecode %u unpacked file saved in %s\n", |
2692 | 2692 |
bc->id, tempfile); |
2693 | 2693 |
else |
... | ... |
@@ -2697,11 +2715,11 @@ int cli_bytecode_runhook(cli_ctx *cctx, const struct cl_engine *engine, struct c |
2697 | 2697 |
cctx->recursion++; |
2698 | 2698 |
ret = cli_magic_scandesc(fd, cctx); |
2699 | 2699 |
cctx->recursion--; |
2700 |
- if (!cctx || !cctx->engine->keeptmp) |
|
2700 |
+ if (!cctx->engine->keeptmp) |
|
2701 | 2701 |
if (ftruncate(fd, 0) == -1) |
2702 | 2702 |
cli_dbgmsg("ftruncate failed on %d\n", fd); |
2703 | 2703 |
close(fd); |
2704 |
- if (!cctx || !cctx->engine->keeptmp) { |
|
2704 |
+ if (!cctx->engine->keeptmp) { |
|
2705 | 2705 |
if (tempfile && cli_unlink(tempfile)) |
2706 | 2706 |
ret = CL_EUNLINK; |
2707 | 2707 |
} |
... | ... |
@@ -2722,7 +2740,7 @@ int cli_bytecode_runhook(cli_ctx *cctx, const struct cl_engine *engine, struct c |
2722 | 2722 |
cli_dbgmsg("Bytecode: executed %u bytecodes for this hook\n", executed); |
2723 | 2723 |
else |
2724 | 2724 |
cli_dbgmsg("Bytecode: no logical signature matched, no bytecode executed\n"); |
2725 |
- if (errorflag && cctx && cctx->engine->bytecode_mode == CL_BYTECODE_MODE_TEST) |
|
2725 |
+ if (errorflag && cctx->engine->bytecode_mode == CL_BYTECODE_MODE_TEST) |
|
2726 | 2726 |
return CL_EBYTECODE_TESTFAIL; |
2727 | 2727 |
return breakflag ? CL_BREAK : CL_CLEAN; |
2728 | 2728 |
} |
... | ... |
@@ -608,7 +608,7 @@ int32_t cli_bcapi_hashset_contains(struct cli_bc_ctx *ctx , int32_t id, uint32_t |
608 | 608 |
int32_t cli_bcapi_hashset_empty(struct cli_bc_ctx *ctx, int32_t id) |
609 | 609 |
{ |
610 | 610 |
struct cli_hashset *s = get_hashset(ctx, id); |
611 |
- return !s->count; |
|
611 |
+ return s ? !s->count : 1; |
|
612 | 612 |
} |
613 | 613 |
|
614 | 614 |
int32_t cli_bcapi_hashset_done(struct cli_bc_ctx *ctx , int32_t id) |
... | ... |
@@ -1113,13 +1113,17 @@ int cli_scanpe(cli_ctx *ctx) |
1113 | 1113 |
cli_bytecode_context_setpe(bc_ctx, &pedata, exe_sections); |
1114 | 1114 |
cli_bytecode_context_setctx(bc_ctx, ctx); |
1115 | 1115 |
ret = cli_bytecode_runhook(ctx, ctx->engine, bc_ctx, BC_PE_ALL, map, ctx->virname); |
1116 |
- if (ret == CL_VIRUS || ret == CL_BREAK) { |
|
1117 |
- free(exe_sections); |
|
1118 |
- cli_bytecode_context_destroy(bc_ctx); |
|
1119 |
- return ret == CL_VIRUS ? CL_VIRUS : CL_CLEAN; |
|
1116 |
+ switch (ret) { |
|
1117 |
+ case CL_ENULLARG: |
|
1118 |
+ cli_warnmsg("cli_scanpe: NULL argument supplied\n"); |
|
1119 |
+ return CL_ENULLARG; |
|
1120 |
+ break; |
|
1121 |
+ case CL_VIRUS: |
|
1122 |
+ case CL_BREAK: |
|
1123 |
+ free(exe_sections); |
|
1124 |
+ cli_bytecode_context_destroy(bc_ctx); |
|
1125 |
+ return ret == CL_VIRUS ? CL_VIRUS : CL_CLEAN; |
|
1120 | 1126 |
} |
1121 |
- cli_bytecode_context_destroy(bc_ctx); |
|
1122 |
- |
|
1123 | 1127 |
/* Attempt to detect some popular polymorphic viruses */ |
1124 | 1128 |
|
1125 | 1129 |
/* W32.Parite.B */ |