Browse code

More API additions for PDF.

Török Edvin authored on 2010/03/19 22:47:26
Showing 6 changed files
... ...
@@ -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
... ...
@@ -135,6 +135,8 @@ struct cli_bc_ctx {
135 135
     char *tempfile;
136 136
     void *ctx;
137 137
     unsigned written;
138
+    unsigned filewritten;
139
+    unsigned found;
138 140
     bc_dbg_callback_trace trace;
139 141
     bc_dbg_callback_trace_op trace_op;
140 142
     bc_dbg_callback_trace_val trace_val;