... | ... |
@@ -28,7 +28,9 @@ |
28 | 28 |
#include "shared/optparser.h" |
29 | 29 |
#include "shared/misc.h" |
30 | 30 |
|
31 |
+#include <fcntl.h> |
|
31 | 32 |
#include <stdlib.h> |
33 |
+#include <errno.h> |
|
32 | 34 |
|
33 | 35 |
static void help(void) |
34 | 36 |
{ |
... | ... |
@@ -52,8 +54,10 @@ int main(int argc, char *argv[]) |
52 | 52 |
struct cli_bc_ctx *ctx; |
53 | 53 |
int rc, dbgargc; |
54 | 54 |
struct optstruct *opts; |
55 |
+ const struct optstruct *opt; |
|
55 | 56 |
unsigned funcid=0, i; |
56 | 57 |
struct cli_all_bc bcs; |
58 |
+ unsigned int fd = -1; |
|
57 | 59 |
|
58 | 60 |
opts = optparse(NULL, argc, argv, 1, OPT_CLAMBC, 0, NULL); |
59 | 61 |
if (!opts) { |
... | ... |
@@ -151,6 +155,22 @@ int main(int argc, char *argv[]) |
151 | 151 |
} |
152 | 152 |
} |
153 | 153 |
|
154 |
+ if ((opt = optget(opts,"input"))->enabled) { |
|
155 |
+ fd = open(opt->strarg, O_RDONLY); |
|
156 |
+ if (fd == -1) { |
|
157 |
+ fprintf(stderr, "Unable to open input file %s: %s\n", opt->strarg, strerror(errno)); |
|
158 |
+ optfree(opts); |
|
159 |
+ exit(5); |
|
160 |
+ } |
|
161 |
+ rc = cli_bytecode_context_setfile(ctx, fd); |
|
162 |
+ if (rc != CL_SUCCESS) { |
|
163 |
+ fprintf(stderr, "Unable to set file %s: %s\n", opt->strarg, cl_strerror(rc)); |
|
164 |
+ optfree(opts); |
|
165 |
+ exit(5); |
|
166 |
+ } |
|
167 |
+ } |
|
168 |
+ |
|
169 |
+ |
|
154 | 170 |
rc = cli_bytecode_run(&bcs, bc, ctx); |
155 | 171 |
if (rc != CL_SUCCESS) { |
156 | 172 |
fprintf(stderr,"Unable to run bytecode: %s\n", cl_strerror(rc)); |
... | ... |
@@ -165,6 +185,8 @@ int main(int argc, char *argv[]) |
165 | 165 |
cli_bytecode_done(&bcs); |
166 | 166 |
free(bc); |
167 | 167 |
optfree(opts); |
168 |
+ if (fd != -1) |
|
169 |
+ close(fd); |
|
168 | 170 |
printf("Exiting\n"); |
169 | 171 |
return 0; |
170 | 172 |
} |
... | ... |
@@ -1249,3 +1249,13 @@ int cli_bytecode_done(struct cli_all_bc *allbc) |
1249 | 1249 |
return cli_bytecode_done_jit(allbc); |
1250 | 1250 |
} |
1251 | 1251 |
|
1252 |
+int cli_bytecode_context_setfile(struct cli_bc_ctx *ctx, int fd) |
|
1253 |
+{ |
|
1254 |
+ struct stat buf; |
|
1255 |
+ ctx->fd = fd; |
|
1256 |
+ if (fstat(fd, &buf) == -1) |
|
1257 |
+ return CL_ESTAT; |
|
1258 |
+ ctx->file_size = buf.st_size; |
|
1259 |
+ return 0; |
|
1260 |
+} |
|
1261 |
+ |
... | ... |
@@ -64,6 +64,7 @@ struct cli_bc_ctx *cli_bytecode_context_alloc(void); |
64 | 64 |
int cli_bytecode_context_setfuncid(struct cli_bc_ctx *ctx, const struct cli_bc *bc, unsigned funcid); |
65 | 65 |
int cli_bytecode_context_setparam_int(struct cli_bc_ctx *ctx, unsigned i, uint64_t c); |
66 | 66 |
int cli_bytecode_context_setparam_ptr(struct cli_bc_ctx *ctx, unsigned i, void *data, unsigned datalen); |
67 |
+int cli_bytecode_context_setfile(struct cli_bc_ctx *ctx, int fd); |
|
67 | 68 |
int cli_bytecode_context_clear(struct cli_bc_ctx *ctx); |
68 | 69 |
uint64_t cli_bytecode_context_getresult_int(struct cli_bc_ctx *ctx); |
69 | 70 |
void cli_bytecode_context_destroy(struct cli_bc_ctx *ctx); |
... | ... |
@@ -50,6 +50,8 @@ int32_t cli_bcapi_read(struct cli_bc_ctx* ctx, uint8_t *data, int32_t size) |
50 | 50 |
int32_t cli_bcapi_seek(struct cli_bc_ctx* ctx, int32_t pos, uint32_t whence) |
51 | 51 |
{ |
52 | 52 |
off_t off; |
53 |
+ if (ctx->fd == -1) |
|
54 |
+ return -1; |
|
53 | 55 |
switch (whence) { |
54 | 56 |
case 0: |
55 | 57 |
off = pos; |
... | ... |
@@ -379,6 +379,7 @@ public: |
379 | 379 |
case OP_GEP2: |
380 | 380 |
case OP_GEPN: |
381 | 381 |
case OP_STORE: |
382 |
+ case OP_COPY: |
|
382 | 383 |
// these instructions represents operands differently |
383 | 384 |
break; |
384 | 385 |
default: |
... | ... |
@@ -529,8 +530,13 @@ public: |
529 | 529 |
Store(inst->dest, Builder.CreateSelect(Op0, Op1, Op2)); |
530 | 530 |
break; |
531 | 531 |
case OP_COPY: |
532 |
- Builder.CreateStore(Op0, Op1); |
|
532 |
+ { |
|
533 |
+ Value *Dest = Values[inst->u.binop[1]]; |
|
534 |
+ const PointerType *PTy = cast<PointerType>(Dest->getType()); |
|
535 |
+ Op0 = convertOperand(func, PTy->getElementType(), inst->u.binop[0]); |
|
536 |
+ Builder.CreateStore(Op0, Dest); |
|
533 | 537 |
break; |
538 |
+ } |
|
534 | 539 |
case OP_CALL_DIRECT: |
535 | 540 |
{ |
536 | 541 |
Function *DestF = Functions[inst->u.ops.funcid]; |
... | ... |
@@ -594,6 +600,7 @@ public: |
594 | 594 |
break; |
595 | 595 |
} |
596 | 596 |
case OP_LOAD: |
597 |
+ Op0 = Builder.CreateLoad(Op0); |
|
597 | 598 |
Store(inst->dest, Op0); |
598 | 599 |
break; |
599 | 600 |
default: |
... | ... |
@@ -154,6 +154,7 @@ CLAMAV_PRIVATE { |
154 | 154 |
cli_bytecode_context_setfuncid; |
155 | 155 |
cli_bytecode_context_setparam_int; |
156 | 156 |
cli_bytecode_context_setparam_ptr; |
157 |
+ cli_bytecode_context_setfile; |
|
157 | 158 |
cli_bytecode_context_getresult_int; |
158 | 159 |
cli_bytecode_context_clear; |
159 | 160 |
cli_bytecode_init; |
... | ... |
@@ -118,7 +118,8 @@ const struct clam_option clam_options[] = { |
118 | 118 |
{ NULL, "non-default", 'n', TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMCONF, "", "" }, |
119 | 119 |
{ NULL, "generate-config", 'g', TYPE_STRING, NULL, -1, NULL, 0, OPT_CLAMCONF, "", "" }, |
120 | 120 |
|
121 |
- { NULL, "force-interpreter", 'f', TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMBC, "", "" }, |
|
121 |
+ { NULL, "force-interpreter", 'f', TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMBC, "Force using the interpreter instead of the JIT", "" }, |
|
122 |
+ { NULL, "input", 'i', TYPE_STRING, NULL, -1, NULL, 0, OPT_CLAMBC, "Input file to run the bytecode n", ""}, |
|
122 | 123 |
|
123 | 124 |
/* cmdline only - deprecated */ |
124 | 125 |
{ NULL, "http-proxy", 0, TYPE_STRING, NULL, 0, NULL, 0, OPT_FRESHCLAM | OPT_DEPRECATED, "", "" }, |