~ubuntu-branches/ubuntu/saucy/clamav/saucy-backports

« back to all changes in this revision

Viewing changes to .pc/0010-Call-cl_initialize_crypto-in-cl_init.patch/clambc/bcrun.c

  • Committer: Package Import Robot
  • Author(s): Scott Kitterman
  • Date: 2014-07-15 01:08:10 UTC
  • mfrom: (0.35.47 sid)
  • Revision ID: package-import@ubuntu.com-20140715010810-ru66ek4fun2iseba
Tags: 0.98.4+dfsg-2~ubuntu13.10.1
No-change backport to saucy (LP: #1341962)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  ClamAV bytecode handler tool.
 
3
 *
 
4
 *  Copyright (C) 2009-2012 Sourcefire, Inc.
 
5
 *
 
6
 *  Authors: Török Edvin
 
7
 *
 
8
 *  This program is free software; you can redistribute it and/or modify
 
9
 *  it under the terms of the GNU General Public License version 2 as
 
10
 *  published by the Free Software Foundation.
 
11
 *
 
12
 *  This program is distributed in the hope that it will be useful,
 
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 *  GNU General Public License for more details.
 
16
 *
 
17
 *  You should have received a copy of the GNU General Public License
 
18
 *  along with this program; if not, write to the Free Software
 
19
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
20
 *  MA 02110-1301, USA.
 
21
 */
 
22
#if HAVE_CONFIG_H
 
23
#include "clamav-config.h"
 
24
#endif
 
25
#include "cltypes.h"
 
26
#ifndef _WIN32
 
27
#include <sys/time.h>
 
28
#endif
 
29
#include <stdlib.h>
 
30
 
 
31
#include <openssl/ssl.h>
 
32
#include <openssl/err.h>
 
33
#include "libclamav/crypto.h"
 
34
 
 
35
#include "bytecode.h"
 
36
#include "bytecode_priv.h"
 
37
#include "clamav.h"
 
38
#include "shared/optparser.h"
 
39
#include "shared/misc.h"
 
40
#include "libclamav/dconf.h"
 
41
#include "libclamav/others.h"
 
42
 
 
43
#include <fcntl.h>
 
44
#include <stdlib.h>
 
45
#include <errno.h>
 
46
#include <string.h>
 
47
#ifdef HAVE_UNISTD_H
 
48
#include <unistd.h>
 
49
#endif
 
50
 
 
51
static void help(void)
 
52
{
 
53
    printf("\n");
 
54
    printf("           Clam AntiVirus: Bytecode Testing Tool %s\n",
 
55
           get_version());
 
56
    printf("           By The ClamAV Team: http://www.clamav.net/team\n");
 
57
    printf("           (C) 2009 Sourcefire, Inc.\n\n");
 
58
    printf("clambc <file> [function] [param1 ...]\n\n");
 
59
    printf("    --help                 -h         Show help\n");
 
60
    printf("    --version              -V         Show version\n");
 
61
    printf("    --info                 -i         Print information about bytecode\n");
 
62
    printf("    --printsrc             -p         Print bytecode source\n");
 
63
    printf("    --trace <level>                   Set bytecode trace level 0..7 (default 7)\n");
 
64
    printf("    --no-trace-showsource             Don't show source line during tracing\n");
 
65
    printf("    file                              file to test\n");
 
66
    printf("\n");
 
67
    return;
 
68
}
 
69
 
 
70
static struct dbg_state {
 
71
    const char *directory;
 
72
    const char *file;
 
73
    const char *scope;
 
74
    uint32_t scopeid;
 
75
    unsigned line;
 
76
    unsigned col;
 
77
    unsigned showline;
 
78
} dbg_state;
 
79
 
 
80
static void tracehook(struct cli_bc_ctx *ctx, unsigned event)
 
81
{
 
82
    dbg_state.directory = ctx->directory;
 
83
    if (*ctx->file == '?')
 
84
        return;
 
85
    switch (event) {
 
86
        case trace_func:
 
87
            fprintf(stderr, "[trace] %s:%u:%u -> %s:%u:%u Entered function %s\n",
 
88
                   dbg_state.file, dbg_state.line, dbg_state.col,
 
89
                   ctx->file, ctx->line, ctx->col, ctx->scope);
 
90
            dbg_state.scope = ctx->scope;
 
91
            break;
 
92
        case trace_param:
 
93
            fprintf(stderr, "[trace] function parameter:\n");
 
94
            return;
 
95
        case trace_scope:
 
96
            fprintf(stderr, "[trace] %s:%u:%u -> %s:%u:%u\n",
 
97
                   dbg_state.file, dbg_state.line, dbg_state.col,
 
98
                   ctx->file, ctx->line, ctx->col);
 
99
            dbg_state.scope = ctx->scope;
 
100
            break;
 
101
        case trace_line:
 
102
        case trace_col:
 
103
            if (dbg_state.showline)
 
104
                cli_bytecode_debug_printsrc(ctx);
 
105
            else
 
106
                fprintf(stderr, "[trace] %s:%u:%u\n",
 
107
                       dbg_state.file, dbg_state.line, dbg_state.col);
 
108
            break;
 
109
        default:
 
110
            break;
 
111
    }
 
112
    dbg_state.file = ctx->file;
 
113
    dbg_state.line = ctx->line;
 
114
    dbg_state.col = ctx->col;
 
115
}
 
116
 
 
117
static void tracehook_op(struct cli_bc_ctx *ctx, const char *op)
 
118
{
 
119
    fprintf(stderr, "[trace] %s\n", op);
 
120
}
 
121
 
 
122
static void tracehook_val(struct cli_bc_ctx *ctx, const char *name, uint32_t value)
 
123
{
 
124
    fprintf(stderr, "[trace] %s = %u\n", name, value);
 
125
}
 
126
 
 
127
static void tracehook_ptr(struct cli_bc_ctx *ctx, const void *ptr)
 
128
{
 
129
    fprintf(stderr, "[trace] %p\n", ptr);
 
130
}
 
131
 
 
132
static uint8_t debug_flag = 0;
 
133
static void print_src(const char *file)
 
134
{
 
135
  char buf[4096];
 
136
  int nread, i, found = 0;
 
137
  FILE *f = fopen(file, "r");
 
138
  if (!f) {
 
139
    fprintf(stderr,"Unable to reopen %s\n", file);
 
140
    return;
 
141
  }
 
142
  do {
 
143
    nread = fread(buf, 1, sizeof(buf), f);
 
144
    for (i=0;i<nread-1;i++) {
 
145
      if (buf[i] == '\n' && buf[i+1] == 'S') {
 
146
        found = 1;
 
147
        i+=2;
 
148
        break;
 
149
      }
 
150
    }
 
151
  } while (!found && (nread == sizeof(buf)));
 
152
  if (debug_flag)
 
153
      printf("[clambc] Source code:");
 
154
  do {
 
155
    for (;i+1<nread;i++) {
 
156
      if (buf[i] == 'S' || buf[i] == '\n') {
 
157
        putc('\n', stdout);
 
158
        continue;
 
159
      }
 
160
      putc(((buf[i]&0xf) | ((buf[i+1]&0xf)<<4)), stdout);
 
161
      i++;
 
162
    }
 
163
    if (i == nread-1 && nread != 1)
 
164
        fseek(f, -1, SEEK_CUR);
 
165
    i=0;
 
166
    nread = fread(buf, 1, sizeof(buf), f);
 
167
  } while (nread > 0);
 
168
  fclose(f);
 
169
}
 
170
static uint32_t deadbeefcounts[64] = {
 
171
    0xdeadbeef,
 
172
    0,
 
173
    0xbeefdead,
 
174
    0,
 
175
    0xdeadbeef,
 
176
    0xdeadbeef,
 
177
    0xdeadbeef,
 
178
    0xdeadbeef,
 
179
    0xdeadbeef,
 
180
    0xdeadbeef,
 
181
    0xdeadbeef,
 
182
    0xdeadbeef,
 
183
    0xdeadbeef,
 
184
    0xdeadbeef,
 
185
    0xdeadbeef,
 
186
    0xdeadbeef,
 
187
    0xdeadbeef,
 
188
    0xdeadbeef,
 
189
    0xdeadbeef,
 
190
    0xdeadbeef,
 
191
    0xdeadbeef,
 
192
    0xdeadbeef,
 
193
    0xdeadbeef,
 
194
    0xdeadbeef,
 
195
    0xdeadbeef,
 
196
    0xdeadbeef,
 
197
    0xdeadbeef,
 
198
    0xdeadbeef,
 
199
    0xdeadbeef,
 
200
    0xdeadbeef,
 
201
    0xdeadbeef,
 
202
    0xdeadbeef,
 
203
    0xdeadbeef,
 
204
    0xdeadbeef,
 
205
    0xdeadbeef,
 
206
    0xdeadbeef,
 
207
    0xdeadbeef,
 
208
    0xdeadbeef,
 
209
    0xdeadbeef,
 
210
    0xdeadbeef,
 
211
    0xdeadbeef,
 
212
    0xdeadbeef,
 
213
    0xdeadbeef,
 
214
    0xdeadbeef,
 
215
    0xdeadbeef,
 
216
    0xdeadbeef,
 
217
    0xdeadbeef,
 
218
    0xdeadbeef,
 
219
    0xdeadbeef,
 
220
    0xdeadbeef,
 
221
    0xdeadbeef,
 
222
    0xdeadbeef,
 
223
    0xdeadbeef,
 
224
    0xdeadbeef,
 
225
    0xdeadbeef,
 
226
    0xdeadbeef,
 
227
    0xdeadbeef,
 
228
    0xdeadbeef,
 
229
    0xdeadbeef,
 
230
    0xdeadbeef,
 
231
    0xdeadbeef,
 
232
    0xdeadbeef,
 
233
    0xdeadbeef,
 
234
    0xdeadbeef,
 
235
};
 
236
int main(int argc, char *argv[])
 
237
{
 
238
    FILE *f;
 
239
    struct cli_bc *bc;
 
240
    struct cli_bc_ctx *ctx;
 
241
    int rc, dbgargc;
 
242
    struct optstruct *opts;
 
243
    const struct optstruct *opt;
 
244
    unsigned funcid=0, i;
 
245
    struct cli_all_bc bcs;
 
246
    int fd = -1;
 
247
    unsigned tracelevel;
 
248
 
 
249
    cl_initialize_crypto();
 
250
 
 
251
    if(check_flevel())
 
252
        exit(1);
 
253
 
 
254
    opts = optparse(NULL, argc, argv, 1, OPT_CLAMBC, 0, NULL);
 
255
    if (!opts) {
 
256
        fprintf(stderr, "ERROR: Can't parse command line options\n");
 
257
        exit(1);
 
258
    }
 
259
    if(optget(opts, "version")->enabled) {
 
260
        printf("Clam AntiVirus Bytecode Testing Tool %s\n", get_version());
 
261
        cl_init(CL_INIT_DEFAULT);
 
262
        cli_bytecode_printversion();
 
263
        optfree(opts);
 
264
        exit(0);
 
265
    }
 
266
    if(optget(opts, "help")->enabled || !opts->filename) {
 
267
        optfree(opts);
 
268
        help();
 
269
        exit(0);
 
270
    }
 
271
    f = fopen(opts->filename[0], "r");
 
272
    if (!f) {
 
273
        fprintf(stderr, "Unable to load %s\n", argv[1]);
 
274
        optfree(opts);
 
275
        exit(2);
 
276
    }
 
277
 
 
278
    bc = malloc(sizeof(*bc));
 
279
    if (!bc) {
 
280
        fprintf(stderr, "Out of memory\n");
 
281
        optfree(opts);
 
282
        exit(3);
 
283
    }
 
284
 
 
285
    if (optget(opts,"debug")->enabled) {
 
286
        cl_debug();
 
287
        debug_flag=1;
 
288
    }
 
289
    rc = cl_init(CL_INIT_DEFAULT);
 
290
    if (rc != CL_SUCCESS) {
 
291
        fprintf(stderr,"Unable to init libclamav: %s\n", cl_strerror(rc));
 
292
        optfree(opts);
 
293
        exit(4);
 
294
    }
 
295
 
 
296
    dbgargc=1;
 
297
    while (opts->filename[dbgargc]) dbgargc++;
 
298
 
 
299
    if (dbgargc > 1)
 
300
        cli_bytecode_debug(dbgargc, opts->filename);
 
301
 
 
302
    if (optget(opts, "force-interpreter")->enabled) {
 
303
        bcs.engine = NULL;
 
304
    } else {
 
305
        rc = cli_bytecode_init(&bcs);
 
306
        if (rc != CL_SUCCESS) {
 
307
            fprintf(stderr,"Unable to init bytecode engine: %s\n", cl_strerror(rc));
 
308
            optfree(opts);
 
309
            exit(4);
 
310
        }
 
311
    }
 
312
 
 
313
    bcs.all_bcs = bc;
 
314
    bcs.count = 1;
 
315
 
 
316
    rc = cli_bytecode_load(bc, f, NULL, optget(opts, "trust-bytecode")->enabled, 
 
317
                           optget(opts, "bytecode-statistics")->enabled);
 
318
    if (rc != CL_SUCCESS) {
 
319
        fprintf(stderr,"Unable to load bytecode: %s\n", cl_strerror(rc));
 
320
        optfree(opts);
 
321
        exit(4);
 
322
    }
 
323
    fclose(f);
 
324
    if (bc->state == bc_skip) {
 
325
        fprintf(stderr,"bytecode load skipped\n");
 
326
        exit(0);
 
327
    }
 
328
    if (debug_flag)
 
329
        printf("[clambc] Bytecode loaded\n");
 
330
    if (optget(opts, "info")->enabled) {
 
331
        cli_bytecode_describe(bc);
 
332
    } else if (optget(opts, "printsrc")->enabled) {
 
333
        print_src(opts->filename[0]);
 
334
    } else {
 
335
        cli_ctx cctx;
 
336
        struct cl_engine *engine = cl_engine_new();
 
337
        fmap_t *map = NULL;
 
338
        memset(&cctx, 0, sizeof(cctx));
 
339
        if (!engine) {
 
340
            fprintf(stderr,"Unable to create engine\n");
 
341
            optfree(opts);
 
342
            exit(3);
 
343
        }
 
344
        rc = cl_engine_compile(engine);
 
345
        if (rc) {
 
346
            fprintf(stderr,"Unable to compile engine: %s\n", cl_strerror(rc));
 
347
            optfree(opts);
 
348
            exit(4);
 
349
        }
 
350
        rc = cli_bytecode_prepare2(engine, &bcs, BYTECODE_ENGINE_MASK);
 
351
        if (rc != CL_SUCCESS) {
 
352
            fprintf(stderr,"Unable to prepare bytecode: %s\n", cl_strerror(rc));
 
353
            optfree(opts);
 
354
            exit(4);
 
355
        }
 
356
        if (debug_flag)
 
357
            printf("[clambc] Bytecode prepared\n");
 
358
 
 
359
        ctx = cli_bytecode_context_alloc();
 
360
        if (!ctx) {
 
361
            fprintf(stderr,"Out of memory\n");
 
362
            exit(3);
 
363
        }
 
364
        ctx->ctx = &cctx;
 
365
        cctx.engine = engine;
 
366
        cctx.fmap = cli_calloc(sizeof(fmap_t*), engine->maxreclevel+2);
 
367
        if (!cctx.fmap) {
 
368
            fprintf(stderr,"Out of memory\n");
 
369
            exit(3);
 
370
        }
 
371
        memset(&dbg_state, 0, sizeof(dbg_state));
 
372
        dbg_state.file = "<libclamav>";
 
373
        dbg_state.line = 0;
 
374
        dbg_state.col = 0;
 
375
        dbg_state.showline = !optget(opts, "no-trace-showsource")->enabled;
 
376
        tracelevel = optget(opts, "trace")->numarg;
 
377
        cli_bytecode_context_set_trace(ctx, tracelevel,
 
378
                                       tracehook,
 
379
                                       tracehook_op,
 
380
                                       tracehook_val,
 
381
                                       tracehook_ptr);
 
382
 
 
383
        if (opts->filename[1]) {
 
384
            funcid = atoi(opts->filename[1]);
 
385
        }
 
386
        cli_bytecode_context_setfuncid(ctx, bc, funcid);
 
387
        if (debug_flag)
 
388
            printf("[clambc] Running bytecode function :%u\n", funcid);
 
389
 
 
390
        if (opts->filename[1]) {
 
391
            i=2;
 
392
            while (opts->filename[i]) {
 
393
                rc = cli_bytecode_context_setparam_int(ctx, i-2, atoi(opts->filename[i]));
 
394
                if (rc != CL_SUCCESS) {
 
395
                    fprintf(stderr,"Unable to set param %u: %s\n", i-2, cl_strerror(rc));
 
396
                }
 
397
                i++;
 
398
            }
 
399
        }
 
400
 
 
401
        if ((opt = optget(opts,"input"))->enabled) {
 
402
            fd = open(opt->strarg, O_RDONLY);
 
403
            if (fd == -1) {
 
404
                fprintf(stderr, "Unable to open input file %s: %s\n", opt->strarg, strerror(errno));
 
405
                optfree(opts);
 
406
                exit(5);
 
407
            }
 
408
            map = fmap(fd, 0, 0);
 
409
            if (!map) {
 
410
                fprintf(stderr, "Unable to map input file %s\n", opt->strarg);
 
411
                exit(5);
 
412
            }
 
413
            rc = cli_bytecode_context_setfile(ctx, map);
 
414
            if (rc != CL_SUCCESS) {
 
415
                fprintf(stderr, "Unable to set file %s: %s\n", opt->strarg, cl_strerror(rc));
 
416
                optfree(opts);
 
417
                exit(5);
 
418
            }
 
419
        }
 
420
        /* for testing */
 
421
        ctx->hooks.match_counts = deadbeefcounts;
 
422
        ctx->hooks.match_offsets = deadbeefcounts;
 
423
        rc = cli_bytecode_run(&bcs, bc, ctx);
 
424
        if (rc != CL_SUCCESS) {
 
425
            fprintf(stderr,"Unable to run bytecode: %s\n", cl_strerror(rc));
 
426
        } else {
 
427
            uint64_t v;
 
428
            if (debug_flag)
 
429
                printf("[clambc] Bytecode run finished\n");
 
430
            v = cli_bytecode_context_getresult_int(ctx);
 
431
            if (debug_flag)
 
432
                printf("[clambc] Bytecode returned: 0x%llx\n", (long long)v);
 
433
        }
 
434
        cli_bytecode_context_destroy(ctx);
 
435
        if (map)
 
436
            funmap(map);
 
437
        cl_engine_free(engine);
 
438
        free(cctx.fmap);
 
439
    }
 
440
    cli_bytecode_destroy(bc);
 
441
    cli_bytecode_done(&bcs);
 
442
    free(bc);
 
443
    optfree(opts);
 
444
    if (fd != -1)
 
445
        close(fd);
 
446
    if (debug_flag)
 
447
        printf("[clambc] Exiting\n");
 
448
    cl_cleanup_crypto();
 
449
    return 0;
 
450
}