Add LZMA & BZip2 decompression to bytecode API

Adds LZMA and BZip2 decompression routines to the bytecode API.
The ability to decompress LZMA and BZip2 streams is particularly
useful for bytecode signatures that extend clamav executable
unpacking capabilities.

Of note, the LZMA format is not well standardized. This API
expects the stream to start with the LZMA_Alone header.

Also fixed a bug in LZMA dictionary size setting.
pull/119/head
Jonas Zaddach (jzaddach) 5 years ago committed by Micah Snyder (micasnyd)
parent b7f8440965
commit cd977727f0
  1. 14
      libclamav/bytecode.c
  2. 221
      libclamav/bytecode_api.c
  3. 111
      libclamav/bytecode_api.h
  4. 180
      libclamav/bytecode_api_decl.c
  5. 6
      libclamav/bytecode_api_impl.h
  6. 8
      libclamav/bytecode_priv.h
  7. 2
      libclamav/clambc.h
  8. 9
      libclamav/lzma_iface.c

@ -201,6 +201,20 @@ static int cli_bytecode_context_reset(struct cli_bc_ctx *ctx)
ctx->inflates = NULL;
ctx->ninflates = 0;
for (i = 0; i < ctx->nlzmas; i++)
cli_bcapi_lzma_done(ctx, i);
free(ctx->lzmas);
ctx->lzmas = NULL;
ctx->nlzmas = 0;
#if HAVE_BZLIB_H
for (i = 0; i < ctx->nbzip2s; i++)
cli_bcapi_bzip2_done(ctx, i);
free(ctx->bzip2s);
ctx->bzip2s = NULL;
ctx->nbzip2s = 0;
#endif
for (i = 0; i < ctx->nbuffers; i++)
cli_bcapi_buffer_pipe_done(ctx, i);
free(ctx->buffers);

@ -51,9 +51,13 @@
#include "hashtab.h"
#include "str.h"
#include "filetypes.h"
#include "lzma_iface.h"
#if HAVE_JSON
#include "json.h"
#endif
#if HAVE_BZLIB_H
#include <bzlib.h>
#endif
#define EV ctx->bc_events
@ -61,6 +65,20 @@
#define TOSTRING(x) STRINGIFY(x)
#define API_MISUSE() cli_event_error_str(EV, "API misuse @" TOSTRING(__LINE__))
struct bc_lzma {
struct CLI_LZMA stream;
int32_t from;
int32_t to;
};
#if HAVE_BZLIB_H
struct bc_bzip2 {
bz_stream stream;
int32_t from;
int32_t to;
};
#endif
uint32_t cli_bcapi_test1(struct cli_bc_ctx *ctx, uint32_t a, uint32_t b)
{
UNUSEDPARAM(ctx);
@ -928,6 +946,209 @@ int32_t cli_bcapi_inflate_done(struct cli_bc_ctx *ctx, int32_t id)
return ret;
}
int32_t cli_bcapi_lzma_init(struct cli_bc_ctx *ctx, int32_t from, int32_t to)
{
int ret;
struct bc_lzma *b;
unsigned n = ctx->nlzmas + 1;
unsigned avail_in_orig;
if (!get_buffer(ctx, from) || !get_buffer(ctx, to)) {
cli_dbgmsg("bytecode api: lzma_init: invalid buffers!\n");
return -1;
}
avail_in_orig = cli_bcapi_buffer_pipe_read_avail(ctx, from);
if (avail_in_orig < LZMA_PROPS_SIZE + 8) {
cli_dbgmsg("bytecode api: lzma_init: not enough bytes in pipe to read LZMA header!\n");
return -1;
}
b = cli_realloc(ctx->lzmas, sizeof(*ctx->lzmas) * n);
if (!b) {
return -1;
}
ctx->lzmas = b;
ctx->nlzmas = n;
b = &b[n - 1];
b->from = from;
b->to = to;
memset(&b->stream, 0, sizeof(b->stream));
b->stream.avail_in = avail_in_orig;
b->stream.next_in = (void *)cli_bcapi_buffer_pipe_read_get(ctx, b->from,
b->stream.avail_in);
if ((ret = cli_LzmaInit(&b->stream, 0)) != LZMA_RESULT_OK) {
cli_dbgmsg("bytecode api: LzmaInit: Failed to initialize LZMA decompressor: %d!\n", ret);
cli_bcapi_buffer_pipe_read_stopped(ctx, b->from, avail_in_orig - b->stream.avail_in);
return ret;
}
cli_bcapi_buffer_pipe_read_stopped(ctx, b->from, avail_in_orig - b->stream.avail_in);
return n - 1;
}
static struct bc_lzma *get_lzma(struct cli_bc_ctx *ctx, int32_t id)
{
if (id < 0 || (unsigned int)id >= ctx->nlzmas || !ctx->lzmas)
return NULL;
return &ctx->lzmas[id];
}
int32_t cli_bcapi_lzma_process(struct cli_bc_ctx *ctx, int32_t id)
{
int ret;
unsigned avail_in_orig, avail_out_orig;
struct bc_lzma *b = get_lzma(ctx, id);
if (!b || b->from == -1 || b->to == -1)
return -1;
b->stream.avail_in = avail_in_orig =
cli_bcapi_buffer_pipe_read_avail(ctx, b->from);
b->stream.next_in = (void *)cli_bcapi_buffer_pipe_read_get(ctx, b->from,
b->stream.avail_in);
b->stream.avail_out = avail_out_orig =
cli_bcapi_buffer_pipe_write_avail(ctx, b->to);
b->stream.next_out = (uint8_t *)cli_bcapi_buffer_pipe_write_get(ctx, b->to,
b->stream.avail_out);
if (!b->stream.avail_in || !b->stream.avail_out || !b->stream.next_in || !b->stream.next_out)
return -1;
ret = cli_LzmaDecode(&b->stream);
cli_bcapi_buffer_pipe_read_stopped(ctx, b->from, avail_in_orig - b->stream.avail_in);
cli_bcapi_buffer_pipe_write_stopped(ctx, b->to, avail_out_orig - b->stream.avail_out);
if (ret != LZMA_RESULT_OK && ret != LZMA_STREAM_END) {
cli_dbgmsg("bytecode api: LzmaDecode: Error %d while decoding\n", ret);
cli_bcapi_lzma_done(ctx, id);
}
return ret;
}
int32_t cli_bcapi_lzma_done(struct cli_bc_ctx *ctx, int32_t id)
{
struct bc_lzma *b = get_lzma(ctx, id);
if (!b || b->from == -1 || b->to == -1)
return -1;
cli_LzmaShutdown(&b->stream);
b->from = b->to = -1;
return 0;
}
int32_t cli_bcapi_bzip2_init(struct cli_bc_ctx *ctx, int32_t from, int32_t to)
{
#if HAVE_BZLIB_H
int ret;
struct bc_bzip2 *b;
unsigned n = ctx->nbzip2s + 1;
if (!get_buffer(ctx, from) || !get_buffer(ctx, to)) {
cli_dbgmsg("bytecode api: bzip2_init: invalid buffers!\n");
return -1;
}
b = cli_realloc(ctx->bzip2s, sizeof(*ctx->bzip2s) * n);
if (!b) {
return -1;
}
ctx->bzip2s = b;
ctx->nbzip2s = n;
b = &b[n - 1];
b->from = from;
b->to = to;
memset(&b->stream, 0, sizeof(b->stream));
ret = BZ2_bzDecompressInit(&b->stream, 0, 0);
switch (ret) {
case BZ_CONFIG_ERROR:
cli_dbgmsg("bytecode api: BZ2_bzDecompressInit: Library has been mis-compiled!\n");
return -1;
case BZ_PARAM_ERROR:
cli_dbgmsg("bytecode api: BZ2_bzDecompressInit: Invalid arguments!\n");
return -1;
case BZ_MEM_ERROR:
cli_dbgmsg("bytecode api: BZ2_bzDecompressInit: Insufficient memory available!\n");
return -1;
case BZ_OK:
break;
default:
cli_dbgmsg("bytecode api: BZ2_bzDecompressInit: unknown error %d\n", ret);
return -1;
}
return n - 1;
#else
return -1;
#endif
}
#if HAVE_BZLIB_H
static struct bc_bzip2 *get_bzip2(struct cli_bc_ctx *ctx, int32_t id)
{
if (id < 0 || (unsigned int)id >= ctx->nbzip2s || !ctx->bzip2s)
return NULL;
return &ctx->bzip2s[id];
}
#endif
int32_t cli_bcapi_bzip2_process(struct cli_bc_ctx *ctx, int32_t id)
{
#if HAVE_BZLIB_H
int ret;
unsigned avail_in_orig, avail_out_orig;
struct bc_bzip2 *b = get_bzip2(ctx, id);
if (!b || b->from == -1 || b->to == -1)
return -1;
b->stream.avail_in = avail_in_orig =
cli_bcapi_buffer_pipe_read_avail(ctx, b->from);
b->stream.next_in = (void *)cli_bcapi_buffer_pipe_read_get(ctx, b->from,
b->stream.avail_in);
b->stream.avail_out = avail_out_orig =
cli_bcapi_buffer_pipe_write_avail(ctx, b->to);
b->stream.next_out = (char *)cli_bcapi_buffer_pipe_write_get(ctx, b->to,
b->stream.avail_out);
if (!b->stream.avail_in || !b->stream.avail_out || !b->stream.next_in || !b->stream.next_out)
return -1;
/* try hard to extract data, skipping over corrupted data */
ret = BZ2_bzDecompress(&b->stream);
cli_bcapi_buffer_pipe_read_stopped(ctx, b->from, avail_in_orig - b->stream.avail_in);
cli_bcapi_buffer_pipe_write_stopped(ctx, b->to, avail_out_orig - b->stream.avail_out);
/* check if nothing written whatsoever */
if ((ret != BZ_OK) && (b->stream.avail_out == avail_out_orig)) {
/* Inflation failed */
cli_errmsg("cli_bcapi_bzip2_process: failed to decompress data\n");
}
return ret;
#else
return -1;
#endif
}
int32_t cli_bcapi_bzip2_done(struct cli_bc_ctx *ctx, int32_t id)
{
#if HAVE_BZLIB_H
struct bc_bzip2 *b = get_bzip2(ctx, id);
if (!b || b->from == -1 || b->to == -1)
return -1;
BZ2_bzDecompressEnd(&b->stream);
b->from = b->to = -1;
return 0;
#else
return -1;
#endif
}
int32_t cli_bcapi_bytecode_rt_error(struct cli_bc_ctx *ctx, int32_t id)
{
int32_t line = id >> 8;

@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2020 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Copyright (C) 2013-2019 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Copyright (C) 2009-2013 Sourcefire, Inc.
* Authors: Török Edvin, Kevin Lin
@ -234,6 +234,37 @@ enum bc_json_type {
JSON_TYPE_STRING /* */
};
/**
\group_adt
* LZMA return codes
*/
enum lzma_returncode {
LZMA_RESULT_OK = 0, /* Function completed successfully */
LZMA_RESULT_DATA_ERROR = 1, /* The LZMA stream contained invalid data */
LZMA_STREAM_END = 2 /* The LZMA stream ended unexpectedly */
};
/**
\group adt
* Bzip2 return codes
*/
enum bzip2_returncode {
BZIP2_OK = 0, /* Function returned without error */
BZIP2_SEQUENCE_ERROR = -1,
BZIP2_PARAM_ERROR = -2,
BZIP2_MEM_ERROR = -3,
BZIP2_DATA_ERROR = -4,
BZIP2_DATA_ERROR_MAGIC = -5,
BZIP2_IO_ERROR = -6,
BZIP2_UNEXPECTED_EOF = -7,
BZIP2_OUTBUFF_FULL = -8,
BZIP2_CONFIG_ERROR = -9,
BZIP2_RUN_OK = 1,
BZIP2_FLUSH_OK = 2,
BZIP2_FINISH_OK = 3,
BZIP2_STREAM_END = 4
};
/**
\group_engine
* Scan option flag values for engine_scan_options(). *DEPRECATED*
@ -1339,5 +1370,83 @@ int32_t json_get_int(int32_t objid);
uint32_t engine_scan_options_ex(const uint8_t* option_name, uint32_t name_len);
/* ----------------- END 0.101 APIs ---------------------------------- */
/* ----------------- BEGIN 0.103 APIs -------------------------------- */
/**
\group_adt
* Initializes LZMA data structures for decompressing data
* 'from_buffer' and writing uncompressed data 'to_buffer'.
* This function expects the LZMA data to be prefixed with an 'LZMA_ALONE' header:
* - One byte of lzma parameters lc, lp and pb converted into a byte value like this: lc + 9 * (5 * pb + lp).
* lc The number of high bits of the previous byte to use as a context for literal encoding.
* lp The number of low bits of the dictionary position to include in literal_pos_state.
* pb The number of low bits of the dictionary position to include in pos_state.
* - Four bytes of dictionary size. In case of doubt you can set this to zero.
* - Eight bytes of uncompressed size. Can be set to -1 if the size is unknown
* and the lzma stream is terminated with an end marker.
* @param[in] from_buffer ID of buffer_pipe to read compressed data from
* @param[in] to_buffer ID of buffer_pipe to write decompressed data to
* @return ID of newly created lzma data structure, <0 on failure.
*/
int32_t lzma_init(int32_t from, int32_t to);
/**
\group_adt
* Decompress all available data in the input buffer, and write to output buffer.
* Stops when the input buffer becomes empty, or write buffer becomes full.
* This function can be called repeatedly on success after filling the input
* buffer, and flushing the output buffer.
* The lzma stream is done processing when 0 bytes are available from output
* buffer, and input buffer is not empty.
* @param[in] id ID of lzma data structure.
* @return 0 on success, lzma error code otherwise.
*/
int32_t lzma_process(int32_t id);
/**
\group_adt
* Deallocates lzma data structure.
* Using the lzma data structure after this will result in an error.
* All lzma data structures are automatically deallocated when bytecode
* finishes execution.
* @param[in] id ID of lzma data structure
* @return 0 on success.
*/
int32_t lzma_done(int32_t id);
/**
\group_adt
* Initializes Bzip2 data structures for decompressing data
* 'from_buffer' and writing uncompressed data 'to_buffer'.
* @param[in] from_buffer ID of buffer_pipe to read compressed data from
* @param[in] to_buffer ID of buffer_pipe to write decompressed data to
* @return ID of newly created bzip2 data structure, <0 on failure.
*/
int32_t bzip2_init(int32_t from, int32_t to);
/**
\group_adt
* Decompress all available data in the input buffer, and write to output buffer.
* Stops when the input buffer becomes empty, or write buffer becomes full.
* This function can be called repeatedly on success after filling the input
* buffer, and flushing the output buffer.
* The bzip2 stream is done processing when 0 bytes are available from output
* buffer, and input buffer is not empty.
* @param[in] id ID of lzma data structure.
* @return 0 on success, bzip2 error code otherwise.
*/
int32_t bzip2_process(int32_t id);
/**
\group_adt
* Deallocates bzip2 data structure.
* Using the bzip2 data structure after this will result in an error.
* All bzip2 data structures are automatically deallocated when bytecode
* finishes execution.
* @param[in] id ID of bzip2 data structure
* @return 0 on success.
*/
int32_t bzip2_done(int32_t id);
/* ----------------- END 0.103 APIs ---------------------------------- */
#endif
#endif

@ -134,6 +134,12 @@ int32_t cli_bcapi_json_get_string(struct cli_bc_ctx *ctx , int8_t*, int32_t, int
int32_t cli_bcapi_json_get_boolean(struct cli_bc_ctx *ctx , int32_t);
int32_t cli_bcapi_json_get_int(struct cli_bc_ctx *ctx , int32_t);
uint32_t cli_bcapi_engine_scan_options_ex(struct cli_bc_ctx *ctx , const uint8_t*, uint32_t);
int32_t cli_bcapi_lzma_init(struct cli_bc_ctx *ctx , int32_t, int32_t);
int32_t cli_bcapi_lzma_process(struct cli_bc_ctx *ctx , int32_t);
int32_t cli_bcapi_lzma_done(struct cli_bc_ctx *ctx , int32_t);
int32_t cli_bcapi_bzip2_init(struct cli_bc_ctx *ctx , int32_t, int32_t);
int32_t cli_bcapi_bzip2_process(struct cli_bc_ctx *ctx , int32_t);
int32_t cli_bcapi_bzip2_done(struct cli_bc_ctx *ctx , int32_t);
const struct cli_apiglobal cli_globals[] = {
/* Bytecode globals BEGIN */
@ -158,10 +164,10 @@ static uint16_t cli_tmp4[]={16, 8, 8, 32, 32, 32, 32, 32, 32, 32, 32, 32, 16, 16
static uint16_t cli_tmp5[]={32, 16, 16, 32, 32, 32, 16, 16};
static uint16_t cli_tmp6[]={32};
static uint16_t cli_tmp7[]={32};
static uint16_t cli_tmp8[]={32, 65, 32};
static uint16_t cli_tmp9[]={32, 32};
static uint16_t cli_tmp10[]={32, 65, 32, 32};
static uint16_t cli_tmp11[]={32, 32, 32};
static uint16_t cli_tmp8[]={32, 32};
static uint16_t cli_tmp9[]={32, 32, 32};
static uint16_t cli_tmp10[]={32, 65, 32};
static uint16_t cli_tmp11[]={32, 65, 32, 32};
static uint16_t cli_tmp12[]={32};
static uint16_t cli_tmp13[]={32, 65, 32, 65, 32};
static uint16_t cli_tmp14[]={65, 32, 32};
@ -191,10 +197,10 @@ const struct cli_bc_type cli_apicall_types[]={
{DStructType, cli_tmp5, 8, 0, 0},
{DArrayType, cli_tmp6, 1, 0, 0},
{DArrayType, cli_tmp7, 64, 0, 0},
{DFunctionType, cli_tmp8, 3, 0, 0},
{DFunctionType, cli_tmp9, 2, 0, 0},
{DFunctionType, cli_tmp10, 4, 0, 0},
{DFunctionType, cli_tmp11, 3, 0, 0},
{DFunctionType, cli_tmp8, 2, 0, 0},
{DFunctionType, cli_tmp9, 3, 0, 0},
{DFunctionType, cli_tmp10, 3, 0, 0},
{DFunctionType, cli_tmp11, 4, 0, 0},
{DFunctionType, cli_tmp12, 1, 0, 0},
{DFunctionType, cli_tmp13, 5, 0, 0},
{DFunctionType, cli_tmp14, 3, 0, 0},
@ -219,107 +225,113 @@ const struct cli_bc_type cli_apicall_types[]={
const unsigned cli_apicall_maxtypes=sizeof(cli_apicall_types)/sizeof(cli_apicall_types[0]);
const struct cli_apicall cli_apicalls[]={
/* Bytecode APIcalls BEGIN */
{"test1", 11, 0, 0},
{"read", 8, 0, 1},
{"write", 8, 1, 1},
{"seek", 11, 1, 0},
{"setvirusname", 8, 2, 1},
{"debug_print_str", 8, 3, 1},
{"debug_print_uint", 9, 0, 2},
{"test1", 9, 0, 0},
{"read", 10, 0, 1},
{"write", 10, 1, 1},
{"seek", 9, 1, 0},
{"setvirusname", 10, 2, 1},
{"debug_print_str", 10, 3, 1},
{"debug_print_uint", 8, 0, 2},
{"disasm_x86", 25, 4, 1},
{"trace_directory", 8, 5, 1},
{"trace_scope", 8, 6, 1},
{"trace_source", 8, 7, 1},
{"trace_op", 8, 8, 1},
{"trace_value", 8, 9, 1},
{"trace_ptr", 8, 10, 1},
{"pe_rawaddr", 9, 1, 2},
{"file_find", 8, 11, 1},
{"file_byteat", 9, 2, 2},
{"trace_directory", 10, 5, 1},
{"trace_scope", 10, 6, 1},
{"trace_source", 10, 7, 1},
{"trace_op", 10, 8, 1},
{"trace_value", 10, 9, 1},
{"trace_ptr", 10, 10, 1},
{"pe_rawaddr", 8, 1, 2},
{"file_find", 10, 11, 1},
{"file_byteat", 8, 2, 2},
{"malloc", 24, 0, 3},
{"test2", 9, 3, 2},
{"test2", 8, 3, 2},
{"get_pe_section", 21, 12, 1},
{"fill_buffer", 20, 0, 4},
{"extract_new", 9, 4, 2},
{"read_number", 9, 5, 2},
{"extract_new", 8, 4, 2},
{"read_number", 8, 5, 2},
{"hashset_new", 12, 0, 5},
{"hashset_add", 11, 2, 0},
{"hashset_remove", 11, 3, 0},
{"hashset_contains", 11, 4, 0},
{"hashset_done", 9, 6, 2},
{"hashset_empty", 9, 7, 2},
{"buffer_pipe_new", 9, 8, 2},
{"buffer_pipe_new_fromfile", 9, 9, 2},
{"buffer_pipe_read_avail", 9, 10, 2},
{"hashset_add", 9, 2, 0},
{"hashset_remove", 9, 3, 0},
{"hashset_contains", 9, 4, 0},
{"hashset_done", 8, 6, 2},
{"hashset_empty", 8, 7, 2},
{"buffer_pipe_new", 8, 8, 2},
{"buffer_pipe_new_fromfile", 8, 9, 2},
{"buffer_pipe_read_avail", 8, 10, 2},
{"buffer_pipe_read_get", 14, 0, 6},
{"buffer_pipe_read_stopped", 11, 5, 0},
{"buffer_pipe_write_avail", 9, 11, 2},
{"buffer_pipe_read_stopped", 9, 5, 0},
{"buffer_pipe_write_avail", 8, 11, 2},
{"buffer_pipe_write_get", 14, 1, 6},
{"buffer_pipe_write_stopped", 11, 6, 0},
{"buffer_pipe_done", 9, 12, 2},
{"buffer_pipe_write_stopped", 9, 6, 0},
{"buffer_pipe_done", 8, 12, 2},
{"inflate_init", 15, 0, 7},
{"inflate_process", 9, 13, 2},
{"inflate_done", 9, 14, 2},
{"bytecode_rt_error", 9, 15, 2},
{"jsnorm_init", 9, 16, 2},
{"jsnorm_process", 9, 17, 2},
{"jsnorm_done", 9, 18, 2},
{"ilog2", 11, 7, 0},
{"inflate_process", 8, 13, 2},
{"inflate_done", 8, 14, 2},
{"bytecode_rt_error", 8, 15, 2},
{"jsnorm_init", 8, 16, 2},
{"jsnorm_process", 8, 17, 2},
{"jsnorm_done", 8, 18, 2},
{"ilog2", 9, 7, 0},
{"ipow", 15, 1, 7},
{"iexp", 15, 2, 7},
{"isin", 15, 3, 7},
{"icos", 15, 4, 7},
{"memstr", 13, 0, 8},
{"hex2ui", 11, 8, 0},
{"atoi", 8, 13, 1},
{"debug_print_str_start", 8, 14, 1},
{"debug_print_str_nonl", 8, 15, 1},
{"entropy_buffer", 8, 16, 1},
{"map_new", 11, 9, 0},
{"map_addkey", 10, 0, 9},
{"map_setvalue", 10, 1, 9},
{"map_remove", 10, 2, 9},
{"map_find", 10, 3, 9},
{"map_getvaluesize", 9, 19, 2},
{"hex2ui", 9, 8, 0},
{"atoi", 10, 13, 1},
{"debug_print_str_start", 10, 14, 1},
{"debug_print_str_nonl", 10, 15, 1},
{"entropy_buffer", 10, 16, 1},
{"map_new", 9, 9, 0},
{"map_addkey", 11, 0, 9},
{"map_setvalue", 11, 1, 9},
{"map_remove", 11, 2, 9},
{"map_find", 11, 3, 9},
{"map_getvaluesize", 8, 19, 2},
{"map_getvalue", 14, 2, 6},
{"map_done", 9, 20, 2},
{"file_find_limit", 10, 4, 9},
{"map_done", 8, 20, 2},
{"file_find_limit", 11, 4, 9},
{"engine_functionality_level", 12, 1, 5},
{"engine_dconf_level", 12, 2, 5},
{"engine_scan_options", 12, 3, 5},
{"engine_db_options", 12, 4, 5},
{"extract_set_container", 9, 21, 2},
{"input_switch", 9, 22, 2},
{"extract_set_container", 8, 21, 2},
{"input_switch", 8, 22, 2},
{"get_environment", 16, 17, 1},
{"disable_bytecode_if", 10, 5, 9},
{"disable_jit_if", 10, 6, 9},
{"disable_bytecode_if", 11, 5, 9},
{"disable_jit_if", 11, 6, 9},
{"version_compare", 13, 1, 8},
{"check_platform", 15, 5, 7},
{"pdf_get_obj_num", 12, 5, 5},
{"pdf_get_flags", 12, 6, 5},
{"pdf_set_flags", 9, 23, 2},
{"pdf_lookupobj", 9, 24, 2},
{"pdf_getobjsize", 9, 25, 2},
{"pdf_set_flags", 8, 23, 2},
{"pdf_lookupobj", 8, 24, 2},
{"pdf_getobjsize", 8, 25, 2},
{"pdf_getobj", 14, 3, 6},
{"pdf_getobjid", 9, 26, 2},
{"pdf_getobjflags", 9, 27, 2},
{"pdf_setobjflags", 11, 10, 0},
{"pdf_get_offset", 9, 28, 2},
{"pdf_getobjid", 8, 26, 2},
{"pdf_getobjflags", 8, 27, 2},
{"pdf_setobjflags", 9, 10, 0},
{"pdf_get_offset", 8, 28, 2},
{"pdf_get_phase", 12, 7, 5},
{"pdf_get_dumpedobjid", 12, 8, 5},
{"matchicon", 13, 2, 8},
{"running_on_jit", 12, 9, 5},
{"get_file_reliability", 12, 10, 5},
{"json_is_active", 12, 11, 5},
{"json_get_object", 10, 7, 9},
{"json_get_type", 9, 29, 2},
{"json_get_array_length", 9, 30, 2},
{"json_get_array_idx", 11, 11, 0},
{"json_get_string_length", 9, 31, 2},
{"json_get_string", 10, 8, 9},
{"json_get_boolean", 9, 32, 2},
{"json_get_int", 9, 33, 2},
{"engine_scan_options_ex", 8, 18, 1}
{"json_get_object", 11, 7, 9},
{"json_get_type", 8, 29, 2},
{"json_get_array_length", 8, 30, 2},
{"json_get_array_idx", 9, 11, 0},
{"json_get_string_length", 8, 31, 2},
{"json_get_string", 11, 8, 9},
{"json_get_boolean", 8, 32, 2},
{"json_get_int", 8, 33, 2},
{"engine_scan_options_ex", 10, 18, 1},
{"lzma_init", 9, 12, 0},
{"lzma_process", 8, 34, 2},
{"lzma_done", 8, 35, 2},
{"bzip2_init", 9, 13, 0},
{"bzip2_process", 8, 36, 2},
{"bzip2_done", 8, 37, 2}
/* Bytecode APIcalls END */
};
const unsigned cli_numapicalls=sizeof(cli_apicalls)/sizeof(cli_apicalls[0]);
@ -336,7 +348,9 @@ const cli_apicall_int2 cli_apicalls0[] = {
(cli_apicall_int2)cli_bcapi_hex2ui,
(cli_apicall_int2)cli_bcapi_map_new,
(cli_apicall_int2)cli_bcapi_pdf_setobjflags,
(cli_apicall_int2)cli_bcapi_json_get_array_idx
(cli_apicall_int2)cli_bcapi_json_get_array_idx,
(cli_apicall_int2)cli_bcapi_lzma_init,
(cli_apicall_int2)cli_bcapi_bzip2_init
};
const cli_apicall_pointer cli_apicalls1[] = {
(cli_apicall_pointer)cli_bcapi_read,
@ -393,7 +407,11 @@ const cli_apicall_int1 cli_apicalls2[] = {
(cli_apicall_int1)cli_bcapi_json_get_array_length,
(cli_apicall_int1)cli_bcapi_json_get_string_length,
(cli_apicall_int1)cli_bcapi_json_get_boolean,
(cli_apicall_int1)cli_bcapi_json_get_int
(cli_apicall_int1)cli_bcapi_json_get_int,
(cli_apicall_int1)cli_bcapi_lzma_process,
(cli_apicall_int1)cli_bcapi_lzma_done,
(cli_apicall_int1)cli_bcapi_bzip2_process,
(cli_apicall_int1)cli_bcapi_bzip2_done
};
const cli_apicall_malloclike cli_apicalls3[] = {
(cli_apicall_malloclike)cli_bcapi_malloc

@ -132,5 +132,11 @@ int32_t cli_bcapi_json_get_string(struct cli_bc_ctx *ctx , int8_t*, int32_t, int
int32_t cli_bcapi_json_get_boolean(struct cli_bc_ctx *ctx , int32_t);
int32_t cli_bcapi_json_get_int(struct cli_bc_ctx *ctx , int32_t);
uint32_t cli_bcapi_engine_scan_options_ex(struct cli_bc_ctx *ctx , const uint8_t*, uint32_t);
int32_t cli_bcapi_lzma_init(struct cli_bc_ctx *ctx , int32_t, int32_t);
int32_t cli_bcapi_lzma_process(struct cli_bc_ctx *ctx , int32_t);
int32_t cli_bcapi_lzma_done(struct cli_bc_ctx *ctx , int32_t);
int32_t cli_bcapi_bzip2_init(struct cli_bc_ctx *ctx , int32_t, int32_t);
int32_t cli_bcapi_bzip2_process(struct cli_bc_ctx *ctx , int32_t);
int32_t cli_bcapi_bzip2_done(struct cli_bc_ctx *ctx , int32_t);
#endif

@ -198,6 +198,10 @@ struct cli_bc_ctx {
unsigned filewritten;
unsigned found;
unsigned ninflates;
unsigned nlzmas;
#if HAVE_BZLIB_H
unsigned nbzip2s;
#endif
bc_dbg_callback_trace trace;
bc_dbg_callback_trace_op trace_op;
bc_dbg_callback_trace_val trace_val;
@ -211,6 +215,10 @@ struct cli_bc_ctx {
unsigned col;
mpool_t *mpool;
struct bc_inflate *inflates;
struct bc_lzma *lzmas;
#if HAVE_BZLIB_H
struct bc_bzip2 *bzip2s;
#endif
struct bc_buffer *buffers;
unsigned nbuffers;
unsigned nhashsets;

@ -1,7 +1,7 @@
/*
* ClamAV bytecode definitions.
*
* Copyright (C) 2013-2020 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Copyright (C) 2013-2019 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Copyright (C) 2009-2013 Sourcefire, Inc.
*
* Authors: Török Edvin

@ -70,10 +70,13 @@ int cli_LzmaInit(struct CLI_LZMA *L, uint64_t size_override)
if (!L->init) {
L->p_cnt = LZMA_PROPS_SIZE;
if (size_override)
if (size_override) {
L->s_cnt = 0;
L->usize = size_override;
else
} else {
L->s_cnt = 8;
L->usize = 0;
}
L->init = 1;
} else if (size_override)
cli_warnmsg("cli_LzmaInit: ignoring late size override\n");
@ -89,7 +92,7 @@ int cli_LzmaInit(struct CLI_LZMA *L, uint64_t size_override)
while (L->s_cnt) {
uint64_t c = (uint64_t)lzma_getbyte(L, &fail);
if (fail) return LZMA_RESULT_OK;
L->usize = c << (8 * (8 - L->s_cnt));
L->usize |= c << (8 * (8 - L->s_cnt));
L->s_cnt--;
}

Loading…
Cancel
Save