... | ... |
@@ -40,35 +40,7 @@ |
40 | 40 |
static const uint32_t nomatch[64]; |
41 | 41 |
struct cli_bc_ctx *cli_bytecode_context_alloc(void) |
42 | 42 |
{ |
43 |
- struct cli_bc_ctx *ctx = cli_malloc(sizeof(*ctx)); |
|
44 |
- ctx->bc = NULL; |
|
45 |
- ctx->func = NULL; |
|
46 |
- ctx->values = NULL; |
|
47 |
- ctx->operands = NULL; |
|
48 |
- ctx->opsizes = NULL; |
|
49 |
- ctx->fmap = NULL; |
|
50 |
- ctx->off = 0; |
|
51 |
- ctx->ctx = NULL; |
|
52 |
- ctx->hooks.match_counts = nomatch; |
|
53 |
- /* TODO: init all hooks with safe values */ |
|
54 |
- ctx->virname = NULL; |
|
55 |
- ctx->outfd = -1; |
|
56 |
- ctx->tempfile = NULL; |
|
57 |
- ctx->written = 0; |
|
58 |
- ctx->trace_level = trace_none; |
|
59 |
- ctx->trace = NULL; |
|
60 |
- ctx->trace_op = NULL; |
|
61 |
- ctx->trace_val = NULL; |
|
62 |
- ctx->trace_ptr = NULL; |
|
63 |
- ctx->scope = NULL; |
|
64 |
- ctx->scopeid = 0; |
|
65 |
- ctx->file = "??"; |
|
66 |
- ctx->directory = ""; |
|
67 |
- ctx->line = 0; |
|
68 |
- ctx->col = 0; |
|
69 |
- ctx->mpool = NULL; |
|
70 |
- ctx->numGlobals = 0; |
|
71 |
- ctx->globals = NULL; |
|
43 |
+ struct cli_bc_ctx *ctx = cli_calloc(1, sizeof(*ctx)); |
|
72 | 44 |
return ctx; |
73 | 45 |
} |
74 | 46 |
|
... | ... |
@@ -84,7 +56,7 @@ int cli_bytecode_context_getresult_file(struct cli_bc_ctx *ctx, char **tempfilen |
84 | 84 |
*tempfilename = ctx->tempfile; |
85 | 85 |
fd = ctx->outfd; |
86 | 86 |
ctx->tempfile = NULL; |
87 |
- ctx->outfd = -1; |
|
87 |
+ ctx->outfd = 0; |
|
88 | 88 |
return fd; |
89 | 89 |
} |
90 | 90 |
|
... | ... |
@@ -97,18 +69,15 @@ static int cli_bytecode_context_reset(struct cli_bc_ctx *ctx) |
97 | 97 |
ctx->operands = NULL; |
98 | 98 |
ctx->values = NULL; |
99 | 99 |
ctx->opsizes = NULL; |
100 |
- ctx->written = 0; |
|
101 |
- if (ctx->outfd != -1) { |
|
102 |
- cli_dbgmsg("Bytecode: nobody cared about FD %d, %s\n", ctx->outfd, |
|
103 |
- ctx->tempfile); |
|
104 |
- if (ftruncate(ctx->outfd, 0) == -1) |
|
105 |
- cli_dbgmsg("ftruncate failed\n"); |
|
106 |
- close(ctx->outfd); |
|
107 |
- cli_unlink(ctx->tempfile); |
|
100 |
+ if (ctx->outfd) { |
|
101 |
+ cli_bcapi_extract_new(ctx, -1); |
|
102 |
+ if (ctx->outfd) |
|
103 |
+ close(ctx->outfd); |
|
108 | 104 |
free(ctx->tempfile); |
109 | 105 |
ctx->tempfile = NULL; |
110 |
- ctx->outfd = -1; |
|
106 |
+ ctx->outfd = 0; |
|
111 | 107 |
} |
108 |
+ ctx->written = 0; |
|
112 | 109 |
#if USE_MPOOL |
113 | 110 |
if (ctx->mpool) { |
114 | 111 |
mpool_destroy(ctx->mpool); |
... | ... |
@@ -1721,6 +1690,7 @@ int cli_bytecode_runlsig(cli_ctx *cctx, const struct cli_all_bc *bcs, unsigned b |
1721 | 1721 |
memset(&ctx, 0, sizeof(ctx)); |
1722 | 1722 |
cli_bytecode_context_setfuncid(&ctx, bc, 0); |
1723 | 1723 |
ctx.hooks.match_counts = lsigcnt; |
1724 |
+ ctx.ctx = cctx; |
|
1724 | 1725 |
cli_bytecode_context_setfile(&ctx, map); |
1725 | 1726 |
|
1726 | 1727 |
cli_dbgmsg("Running bytecode for logical signature match\n"); |
... | ... |
@@ -141,7 +141,7 @@ int32_t cli_bcapi_write(struct cli_bc_ctx *ctx, uint8_t*data, int32_t len) |
141 | 141 |
cli_warnmsg("Bytecode API: called with negative length!\n"); |
142 | 142 |
return -1; |
143 | 143 |
} |
144 |
- if (ctx->outfd == -1) { |
|
144 |
+ if (!ctx->outfd) { |
|
145 | 145 |
ctx->tempfile = cli_gentemp(cctx ? cctx->engine->tmpdir : NULL); |
146 | 146 |
if (!ctx->tempfile) { |
147 | 147 |
cli_dbgmsg("Bytecode API: Unable to allocate memory for tempfile\n"); |
... | ... |
@@ -149,10 +149,12 @@ int32_t cli_bcapi_write(struct cli_bc_ctx *ctx, uint8_t*data, int32_t len) |
149 | 149 |
} |
150 | 150 |
ctx->outfd = open(ctx->tempfile, O_RDWR|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600); |
151 | 151 |
if (ctx->outfd == -1) { |
152 |
+ ctx->outfd = 0; |
|
152 | 153 |
cli_warnmsg("Bytecode API: Can't create file %s\n", ctx->tempfile); |
153 | 154 |
free(ctx->tempfile); |
154 | 155 |
return -1; |
155 | 156 |
} |
157 |
+ cli_dbgmsg("bytecode opened new tempfile: %s\n", ctx->tempfile); |
|
156 | 158 |
} |
157 | 159 |
if (cli_checklimits("bytecode api", cctx, ctx->written + len, 0, 0)) |
158 | 160 |
return -1; |
... | ... |
@@ -365,21 +367,59 @@ int32_t cli_bcapi_fill_buffer(struct cli_bc_ctx *ctx, uint8_t* buf, |
365 | 365 |
uint32_t pos, uint32_t fill) |
366 | 366 |
{ |
367 | 367 |
int32_t res, remaining, tofill; |
368 |
- if (!buf || !buflen || buflen > CLI_MAX_ALLOCATION || filled > buflen) |
|
368 |
+ if (!buf || !buflen || buflen > CLI_MAX_ALLOCATION || filled > buflen) { |
|
369 |
+ cli_dbgmsg("fill_buffer1\n"); |
|
369 | 370 |
return -1; |
370 |
- if (ctx->off >= ctx->file_size) |
|
371 |
+ } |
|
372 |
+ if (ctx->off >= ctx->file_size) { |
|
373 |
+ cli_dbgmsg("fill_buffer2\n"); |
|
371 | 374 |
return 0; |
375 |
+ } |
|
372 | 376 |
remaining = filled - pos; |
373 | 377 |
if (remaining) { |
374 |
- if (!CLI_ISCONTAINED(buf, buflen, buf+pos, remaining)) |
|
378 |
+ if (!CLI_ISCONTAINED(buf, buflen, buf+pos, remaining)) { |
|
379 |
+ cli_dbgmsg("fill_buffer3\n"); |
|
375 | 380 |
return -1; |
381 |
+ } |
|
376 | 382 |
memmove(buf, buf+pos, remaining); |
377 | 383 |
} |
378 | 384 |
tofill = buflen - remaining; |
379 |
- if (!CLI_ISCONTAINED(buf, buflen, buf+remaining, tofill)) |
|
385 |
+ if (!CLI_ISCONTAINED(buf, buflen, buf+remaining, tofill)) { |
|
386 |
+ cli_dbgmsg("fill_buffer4\n"); |
|
380 | 387 |
return -1; |
388 |
+ } |
|
381 | 389 |
res = cli_bcapi_read(ctx, buf+remaining, tofill); |
382 | 390 |
if (res <= 0) |
383 | 391 |
return res; |
384 | 392 |
return remaining + res; |
385 | 393 |
} |
394 |
+ |
|
395 |
+int32_t cli_bcapi_extract_new(struct cli_bc_ctx *ctx, int32_t id) |
|
396 |
+{ |
|
397 |
+ cli_ctx *cctx; |
|
398 |
+ int res; |
|
399 |
+ cli_dbgmsg("previous tempfile had %u bytes\n", ctx->written); |
|
400 |
+ if (!ctx->written) |
|
401 |
+ return 0; |
|
402 |
+ if (cli_updatelimits(ctx->ctx, ctx->written)) |
|
403 |
+ return -1; |
|
404 |
+ ctx->written = 0; |
|
405 |
+ lseek(ctx->outfd, 0, SEEK_SET); |
|
406 |
+ cli_dbgmsg("bytecode: scanning extracted file %s\n", ctx->tempfile); |
|
407 |
+ res = cli_magic_scandesc(ctx->outfd, ctx->ctx); |
|
408 |
+ if (res == CL_VIRUS) |
|
409 |
+ ctx->found = 1; |
|
410 |
+ cctx = (cli_ctx*)ctx->ctx; |
|
411 |
+ if ((cctx && cctx->engine->keeptmp) || |
|
412 |
+ (ftruncate(ctx->outfd, 0) == -1)) { |
|
413 |
+ |
|
414 |
+ close(ctx->outfd); |
|
415 |
+ if (!(cctx && cctx->engine->keeptmp)) |
|
416 |
+ cli_unlink(ctx->tempfile); |
|
417 |
+ free(ctx->tempfile); |
|
418 |
+ ctx->tempfile = NULL; |
|
419 |
+ ctx->outfd = 0; |
|
420 |
+ } |
|
421 |
+ cli_dbgmsg("bytecode: extracting new file with id %u\n", id); |
|
422 |
+ return res; |
|
423 |
+} |
... | ... |
@@ -208,5 +208,13 @@ int32_t get_pe_section(struct cli_exe_section *section, uint32_t num); |
208 | 208 |
*/ |
209 | 209 |
int32_t fill_buffer(uint8_t* buffer, uint32_t len, uint32_t filled, uint32_t cur, uint32_t fill); |
210 | 210 |
|
211 |
+/** |
|
212 |
+ * Prepares for extracting a new file, if we've already extracted one it scans |
|
213 |
+ * it. |
|
214 |
+ * @param[in] id an id for the new file (for example position in container) |
|
215 |
+ * @return 1 if previous extracted file was infected |
|
216 |
+*/ |
|
217 |
+int32_t extract_new(int32_t id); |
|
218 |
+ |
|
211 | 219 |
#endif |
212 | 220 |
#endif |
... | ... |
@@ -54,6 +54,7 @@ uint8_t* cli_bcapi_malloc(struct cli_bc_ctx *ctx, uint32_t); |
54 | 54 |
uint32_t cli_bcapi_test2(struct cli_bc_ctx *ctx, uint32_t); |
55 | 55 |
int32_t cli_bcapi_get_pe_section(struct cli_bc_ctx *ctx, struct cli_exe_section*, uint32_t); |
56 | 56 |
int32_t cli_bcapi_fill_buffer(struct cli_bc_ctx *ctx, uint8_t*, uint32_t, uint32_t, uint32_t, uint32_t); |
57 |
+int32_t cli_bcapi_extract_new(struct cli_bc_ctx *ctx, int32_t); |
|
57 | 58 |
|
58 | 59 |
const struct cli_apiglobal cli_globals[] = { |
59 | 60 |
/* Bytecode globals BEGIN */ |
... | ... |
@@ -76,11 +77,11 @@ static uint16_t cli_tmp4[]={16, 8, 8, 32, 32, 32, 32, 32, 32, 32, 32, 32, 16, 16 |
76 | 76 |
static uint16_t cli_tmp5[]={32, 16, 16, 32, 32, 32, 16, 16}; |
77 | 77 |
static uint16_t cli_tmp6[]={32}; |
78 | 78 |
static uint16_t cli_tmp7[]={32}; |
79 |
-static uint16_t cli_tmp8[]={32, 65, 32, 32, 32, 32}; |
|
80 |
-static uint16_t cli_tmp9[]={32, 79, 32}; |
|
81 |
-static uint16_t cli_tmp10[]={80}; |
|
82 |
-static uint16_t cli_tmp11[]={32, 32, 32, 32, 32, 32, 32, 32, 32}; |
|
83 |
-static uint16_t cli_tmp12[]={32, 32}; |
|
79 |
+static uint16_t cli_tmp8[]={32, 32}; |
|
80 |
+static uint16_t cli_tmp9[]={32, 65, 32, 32, 32, 32}; |
|
81 |
+static uint16_t cli_tmp10[]={32, 80, 32}; |
|
82 |
+static uint16_t cli_tmp11[]={81}; |
|
83 |
+static uint16_t cli_tmp12[]={32, 32, 32, 32, 32, 32, 32, 32, 32}; |
|
84 | 84 |
static uint16_t cli_tmp13[]={65, 32}; |
85 | 85 |
static uint16_t cli_tmp14[]={32, 65, 32}; |
86 | 86 |
static uint16_t cli_tmp15[]={32, 85, 32}; |
... | ... |
@@ -100,11 +101,11 @@ const struct cli_bc_type cli_apicall_types[]={ |
100 | 100 |
{DStructType, cli_tmp5, 8, 0, 0}, |
101 | 101 |
{DArrayType, cli_tmp6, 1, 0, 0}, |
102 | 102 |
{DArrayType, cli_tmp7, 64, 0, 0}, |
103 |
- {DFunctionType, cli_tmp8, 6, 0, 0}, |
|
104 |
- {DFunctionType, cli_tmp9, 3, 0, 0}, |
|
105 |
- {DPointerType, cli_tmp10, 1, 0, 0}, |
|
106 |
- {DStructType, cli_tmp11, 9, 0, 0}, |
|
107 |
- {DFunctionType, cli_tmp12, 2, 0, 0}, |
|
103 |
+ {DFunctionType, cli_tmp8, 2, 0, 0}, |
|
104 |
+ {DFunctionType, cli_tmp9, 6, 0, 0}, |
|
105 |
+ {DFunctionType, cli_tmp10, 3, 0, 0}, |
|
106 |
+ {DPointerType, cli_tmp11, 1, 0, 0}, |
|
107 |
+ {DStructType, cli_tmp12, 9, 0, 0}, |
|
108 | 108 |
{DFunctionType, cli_tmp13, 2, 0, 0}, |
109 | 109 |
{DFunctionType, cli_tmp14, 3, 0, 0}, |
110 | 110 |
{DFunctionType, cli_tmp15, 3, 0, 0}, |
... | ... |
@@ -125,7 +126,7 @@ const struct cli_apicall cli_apicalls[]={ |
125 | 125 |
{"seek", 21, 1, 0}, |
126 | 126 |
{"setvirusname", 14, 2, 1}, |
127 | 127 |
{"debug_print_str", 14, 3, 1}, |
128 |
- {"debug_print_uint", 12, 0, 2}, |
|
128 |
+ {"debug_print_uint", 8, 0, 2}, |
|
129 | 129 |
{"disasm_x86", 15, 4, 1}, |
130 | 130 |
{"trace_directory", 14, 5, 1}, |
131 | 131 |
{"trace_scope", 14, 6, 1}, |
... | ... |
@@ -133,13 +134,14 @@ const struct cli_apicall cli_apicalls[]={ |
133 | 133 |
{"trace_op", 14, 8, 1}, |
134 | 134 |
{"trace_value", 14, 9, 1}, |
135 | 135 |
{"trace_ptr", 14, 10, 1}, |
136 |
- {"pe_rawaddr", 12, 1, 2}, |
|
136 |
+ {"pe_rawaddr", 8, 1, 2}, |
|
137 | 137 |
{"file_find", 14, 11, 1}, |
138 |
- {"file_byteat", 12, 2, 2}, |
|
138 |
+ {"file_byteat", 8, 2, 2}, |
|
139 | 139 |
{"malloc", 13, 0, 3}, |
140 |
- {"test2", 12, 3, 2}, |
|
141 |
- {"get_pe_section", 9, 12, 1}, |
|
142 |
- {"fill_buffer", 8, 0, 4} |
|
140 |
+ {"test2", 8, 3, 2}, |
|
141 |
+ {"get_pe_section", 10, 12, 1}, |
|
142 |
+ {"fill_buffer", 9, 0, 4}, |
|
143 |
+ {"extract_new", 8, 4, 2} |
|
143 | 144 |
/* Bytecode APIcalls END */ |
144 | 145 |
}; |
145 | 146 |
const cli_apicall_int2 cli_apicalls0[] = { |
... | ... |
@@ -165,7 +167,8 @@ const cli_apicall_int1 cli_apicalls2[] = { |
165 | 165 |
(cli_apicall_int1)cli_bcapi_debug_print_uint, |
166 | 166 |
(cli_apicall_int1)cli_bcapi_pe_rawaddr, |
167 | 167 |
(cli_apicall_int1)cli_bcapi_file_byteat, |
168 |
- (cli_apicall_int1)cli_bcapi_test2 |
|
168 |
+ (cli_apicall_int1)cli_bcapi_test2, |
|
169 |
+ (cli_apicall_int1)cli_bcapi_extract_new |
|
169 | 170 |
}; |
170 | 171 |
const cli_apicall_malloclike cli_apicalls3[] = { |
171 | 172 |
(cli_apicall_malloclike)cli_bcapi_malloc |
... | ... |
@@ -51,5 +51,6 @@ uint8_t* cli_bcapi_malloc(struct cli_bc_ctx *ctx, uint32_t); |
51 | 51 |
uint32_t cli_bcapi_test2(struct cli_bc_ctx *ctx, uint32_t); |
52 | 52 |
int32_t cli_bcapi_get_pe_section(struct cli_bc_ctx *ctx, struct cli_exe_section*, uint32_t); |
53 | 53 |
int32_t cli_bcapi_fill_buffer(struct cli_bc_ctx *ctx, uint8_t*, uint32_t, uint32_t, uint32_t, uint32_t); |
54 |
+int32_t cli_bcapi_extract_new(struct cli_bc_ctx *ctx, int32_t); |
|
54 | 55 |
|
55 | 56 |
#endif |