Browse code

BB#5455

Shawn webb authored on 2012/07/11 02:17:45
Showing 3 changed files
... ...
@@ -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 */