From fa7ae4ccbc69b7f326ee1024d9013eccfccc2010 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Tue, 6 May 2014 15:26:30 -0400 Subject: [PATCH] bytecode api: updated copyright information bytecode api: added json properties reading implementation --- libclamav/bytecode_api.c | 294 ++++++++- libclamav/bytecode_api.h | 1092 +++++++++++++++++++-------------- libclamav/bytecode_api_decl.c | 203 +++--- libclamav/bytecode_api_impl.h | 13 +- 4 files changed, 1058 insertions(+), 544 deletions(-) diff --git a/libclamav/bytecode_api.c b/libclamav/bytecode_api.c index 65d68b62b..3c591ae16 100644 --- a/libclamav/bytecode_api.c +++ b/libclamav/bytecode_api.c @@ -54,6 +54,9 @@ #include "hashtab.h" #include "str.h" #include "filetypes.h" +#if HAVE_JSON +#include "json/json.h" +#endif #define EV ctx->bc_events @@ -139,6 +142,8 @@ uint32_t cli_bcapi_debug_print_str(struct cli_bc_ctx *ctx, const uint8_t *str, u uint32_t cli_bcapi_debug_print_uint(struct cli_bc_ctx *ctx, uint32_t a) { cli_event_int(EV, BCEV_DBG_INT, a); + //cli_dbgmsg("bytecode debug: %d\n", a); + //return 0; if (!cli_debug_flag) return 0; return fprintf(stderr, "%d", a); @@ -447,7 +452,7 @@ uint8_t* cli_bcapi_malloc(struct cli_bc_ctx *ctx, uint32_t size) return v; } -int32_t cli_bcapi_get_pe_section(struct cli_bc_ctx *ctx, void* section, uint32_t num) +int32_t cli_bcapi_get_pe_section(struct cli_bc_ctx *ctx, struct cli_exe_section* section, uint32_t num) { if (num < ctx->hooks.pedata->nsections) { memcpy(section, &ctx->sections[num], sizeof(struct cli_exe_section)); @@ -1293,7 +1298,7 @@ int32_t cli_bcapi_input_switch(struct cli_bc_ctx *ctx , int32_t extracted_file) uint32_t cli_bcapi_get_environment(struct cli_bc_ctx *ctx , struct cli_environment* env, uint32_t len) { if (len > sizeof(*env)) { - cli_dbgmsg("cli_bcapi_get_environment len %u > %lu\n", len, sizeof(*env)); + cli_dbgmsg("cli_bcapi_get_environment len %u > %lu\n", len, (unsigned long)sizeof(*env)); return -1; } memcpy(env, ctx->env, len); @@ -1525,3 +1530,288 @@ int32_t cli_bcapi_get_file_reliability(struct cli_bc_ctx *ctx ) cli_ctx *cctx = (cli_ctx*)ctx->ctx; return cctx ? cctx->corrupted_input : 3; } + +int32_t cli_bcapi_json_is_active(struct cli_bc_ctx *ctx ) +{ +#if HAVE_JSON + cli_ctx *cctx = (cli_ctx*)ctx->ctx; + if (cctx->properties != NULL) { + return 1; + } +#else + cli_dbgmsg("bytecode api: libjson is not enabled!\n"); +#endif + return 0; +} + +static int32_t cli_bcapi_json_objs_init(struct cli_bc_ctx *ctx) { +#if HAVE_JSON + unsigned n = ctx->njsonobjs + 1; + json_object **j; + cli_ctx *cctx = (cli_ctx *)ctx->ctx; + + j = cli_realloc(ctx->jsonobjs, sizeof(*ctx->jsonobjs)*n); + if (!j) { /* memory allocation failure */ + cli_event_error_oom(EV, 0); + return -1; + } + ctx->jsonobjs = j; + ctx->njsonobjs = n; + j[n-1] = cctx->properties; + + return 0; +#else + return -1; +#endif +} + +#define INIT_JSON_OBJS(ctx)\ + if (ctx->njsonobjs == 0) { \ + if (cli_bcapi_json_objs_init(ctx)) { \ + return -1; \ + } \ + } \ + +int32_t cli_bcapi_json_get_object(struct cli_bc_ctx *ctx, const int8_t* name, int32_t name_len, int32_t objid) +{ +#if HAVE_JSON + unsigned n; + json_object **j, *jobj; + char *namep; + + INIT_JSON_OBJS(ctx); + if (objid < 0 || objid >= ctx->njsonobjs) { + cli_dbgmsg("bytecode api[json_get_object]: invalid json objid requested\n"); + return -1; + } + + if (!name || name_len < 0) { + cli_dbgmsg("bytecode api[json_get_object]: unnamed object queried\n"); + return -1; + } + + n = ctx->njsonobjs + 1; + jobj = ctx->jsonobjs[objid]; + if (!jobj) /* shouldn't be possible */ + return -1; + namep = (char*)cli_malloc(sizeof(char)*(name_len+1)); + if (!namep) + return -1; + strncpy(namep, (char*)name, name_len); + namep[name_len] = '\0'; + + jobj = json_object_object_get(jobj,namep); + if (!jobj) { /* object not found */ + free(namep); + return 0; + } + + j = cli_realloc(ctx->jsonobjs, sizeof(*ctx->jsonobjs)*n); + if (!j) { /* memory allocation failure */ + free(namep); + cli_event_error_oom(EV, 0); + return -1; + } + ctx->jsonobjs = j; + ctx->njsonobjs = n; + j[n-1] = jobj; + + cli_dbgmsg("bytecode api[json_get_object]: assigned %s => ID %d\n", namep, n-1); + free(namep); + return n-1; +#else + cli_dbgmsg("bytecode api: libjson is not enabled!\n"); + return -1; +#endif +} + +int32_t cli_bcapi_json_get_type(struct cli_bc_ctx *ctx, int32_t objid) +{ +#if HAVE_JSON + enum json_type type; + + INIT_JSON_OBJS(ctx); + if (objid < 0 || objid >= ctx->njsonobjs) { + cli_dbgmsg("bytecode api[json_get_type]: invalid json objid requested\n"); + return -1; + } + + type = json_object_get_type(ctx->jsonobjs[objid]); + switch (type) { + case json_type_null: + return JSON_TYPE_NULL; + case json_type_boolean: + return JSON_TYPE_BOOLEAN; + case json_type_double: + return JSON_TYPE_DOUBLE; + case json_type_int: + return JSON_TYPE_INT; + case json_type_object: + return JSON_TYPE_OBJECT; + case json_type_array: + return JSON_TYPE_ARRAY; + case json_type_string: + return JSON_TYPE_STRING; + default: + cli_dbgmsg("bytecode api[json_get_type]: unrecognized json type %d\n", type); + } + +#else + cli_dbgmsg("bytecode api: libjson is not enabled!\n"); +#endif + return -1; +} + +int32_t cli_bcapi_json_get_array_length(struct cli_bc_ctx *ctx, int32_t objid) +{ +#if HAVE_JSON + enum json_type type; + + INIT_JSON_OBJS(ctx); + if (objid < 0 || objid >= ctx->njsonobjs) { + cli_dbgmsg("bytecode api[json_array_get_length]: invalid json objid requested\n"); + return -1; + } + + type = json_object_get_type(ctx->jsonobjs[objid]); + if (type != json_type_array) { + return -2; /* error code for not an array */ + } + + return json_object_array_length(ctx->jsonobjs[objid]); +#else + cli_dbgmsg("bytecode api: libjson is not enabled!\n"); + return -1; +#endif +} + +int32_t cli_bcapi_json_get_array_idx(struct cli_bc_ctx *ctx, int32_t idx, int32_t objid) +{ +#if HAVE_JSON + enum json_type type; + unsigned n; + int length; + json_object **j, *jarr = NULL, *jobj = NULL; + + INIT_JSON_OBJS(ctx); + if (objid < 0 || objid >= ctx->njsonobjs) { + cli_dbgmsg("bytecode api[json_array_get_idx]: invalid json objid requested\n"); + return -1; + } + + jarr = ctx->jsonobjs[objid]; + if (!jarr) /* shouldn't be possible */ + return -1; + + type = json_object_get_type(jarr); + if (type != json_type_array) { + return -2; /* error code for not an array */ + } + + length = json_object_array_length(jarr); + if (idx >= 0 && idx < length) { + n = ctx->njsonobjs + 1; + + jobj = json_object_array_get_idx(jarr,idx); + if (!jobj) { /* object not found */ + return 0; + } + + j = cli_realloc(ctx->jsonobjs, sizeof(*ctx->jsonobjs)*n); + if (!j) { /* memory allocation failure */ + cli_event_error_oom(EV, 0); + return -1; + } + ctx->jsonobjs = j; + ctx->njsonobjs = n; + j[n-1] = jobj; + + cli_dbgmsg("bytecode api[json_array_get_idx]: assigned array @ %d => ID %d\n", idx, n-1); + return n-1; + } + + return 0; +#else + cli_dbgmsg("bytecode api: libjson is not enabled!\n"); + return -1; +#endif +} + +int32_t cli_bcapi_json_get_string_length(struct cli_bc_ctx *ctx, int32_t objid) +{ +#if HAVE_JSON + enum json_type type; + json_object *jobj; + int32_t len; + const char *jstr; + + INIT_JSON_OBJS(ctx); + if (objid < 0 || objid >= ctx->njsonobjs) { + cli_dbgmsg("bytecode api[json_array_get_idx]: invalid json objid requested\n"); + return -1; + } + + jobj = ctx->jsonobjs[objid]; + if (!jobj) /* shouldn't be possible */ + return -1; + + type = json_object_get_type(jobj); + if (type != json_type_string) { + return -2; /* error code for not an array */ + } + + //len = json_object_get_string_len(jobj); /* not in JSON <0.10 */ + jstr = json_object_get_string(jobj); + len = strlen(jstr); + + return len; +#else + cli_dbgmsg("bytecode api: libjson is not enabled!\n"); + return -1; +#endif +} + +int32_t cli_bcapi_json_get_string(struct cli_bc_ctx *ctx, int8_t* str, int32_t str_len, int32_t objid) +{ +#if HAVE_JSON + enum json_type type; + json_object *jobj; + int32_t len; + const char *jstr; + + INIT_JSON_OBJS(ctx); + if (objid < 0 || objid >= ctx->njsonobjs) { + cli_dbgmsg("bytecode api[json_array_get_idx]: invalid json objid requested\n"); + return -1; + } + + jobj = ctx->jsonobjs[objid]; + if (!jobj) /* shouldn't be possible */ + return -1; + + type = json_object_get_type(jobj); + if (type != json_type_string) { + return -2; /* error code for not an array */ + } + + //len = json_object_get_string_len(jobj); /* not in JSON <0.10 */ + jstr = json_object_get_string(jobj); + len = strlen(jstr); + + if (len+1 > str_len) { + /* limit on str-len */ + strncpy(str, jstr, str_len-1); + str[str_len-1] = '\0'; + return str_len; + } + else { + /* limit on len+1 */ + strncpy(str, jstr, len); + str[len] = '\0'; + return len+1; + } +#else + cli_dbgmsg("bytecode api: libjson is not enabled!\n"); + return -1; +#endif +} diff --git a/libclamav/bytecode_api.h b/libclamav/bytecode_api.h index b8c9985a5..d9e15a264 100644 --- a/libclamav/bytecode_api.h +++ b/libclamav/bytecode_api.h @@ -1,7 +1,8 @@ /* - * Copyright (C) 2009-2010 Sourcefire, Inc. + * Copyright (C) 2009-2013 Sourcefire, Inc. + * Copyright (C) 2014 Cisco Systems, Inc. and/or its affiliates. * All rights reserved. - * Authors: Török Edvin + * Authors: Török Edvin, Kevin Lin * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -41,149 +42,211 @@ struct cli_exe_section; struct DISASM_RESULT; #endif -/** Bytecode trigger kind */ +/** +\group_config + * Specifies the bytecode type and how ClamAV executes it + */ enum BytecodeKind { /** generic bytecode, not tied a specific hook */ BC_GENERIC=0, + /** triggered at startup, only one is allowed per ClamAV startup */ BC_STARTUP=1, _BC_START_HOOKS=256, - /** triggered by a logical signature */ + /** executed on a logical trigger */ BC_LOGICAL=256, - /** a PE unpacker */ + /** specifies a PE unpacker, executed on PE files on a logical trigger */ BC_PE_UNPACKER, - /* PDF hook */ + /** specifies a PDF hook, executes at a predetermined point of PDF parsing for PDF files */ BC_PDF, - BC_PE_ALL,/* both packed and unpacked files */ + /** specifies a PE hook, executes at a predetermined point in PE parsing for PE files, + * both packed and unpacked files */ + BC_PE_ALL, _BC_LAST_HOOK }; enum { - /** Invalid RVA specified */ + /** +\group_pe + * Invalid RVA specified + */ PE_INVALID_RVA = 0xFFFFFFFF }; -/** LibClamAV functionality level constants */ +/** +\group_config + * LibClamAV functionality level constants + */ enum FunctionalityLevels { - FUNC_LEVEL_096 = 51, - FUNC_LEVEL_096_dev, - FUNC_LEVEL_096_1, - FUNC_LEVEL_096_1_dev=54, - FUNC_LEVEL_096_2=54, - FUNC_LEVEL_096_2_dev + FUNC_LEVEL_096 = 51, /**< LibClamAV release 0.96.0: bytecode engine released */ + FUNC_LEVEL_096_dev = 52, + FUNC_LEVEL_096_1 = 53, /**< LibClamAV release 0.96.1: logical signature use of VI/macros + * requires this minimum functionality level */ + FUNC_LEVEL_096_1_dev = 54, + FUNC_LEVEL_096_2 = 54, /**< LibClamAV release 0.96.2: PDF Hooks require this minimum level */ + FUNC_LEVEL_096_2_dev = 55, + FUNC_LEVEL_096_3 = 55, /**< LibClamAV release 0.96.3: BC_PE_ALL bytecodes require this minimum level */ + FUNC_LEVEL_096_4 = 56, /**< LibClamAV release 0.96.4: minimum recommended engine version, older versions + * have quadratic load time */ + FUNC_LEVEL_096_5 = 58, /**< LibClamAV release 0.96.5 */ + FUNC_LEVEL_097 = 60, /**< LibClamAV release 0.97.0: older bytecodes may incorrectly use 57 */ + FUNC_LEVEL_097_1 = 61, /**< LibClamAV release 0.97.1 */ + FUNC_LEVEL_097_2 = 62, /**< LibClamAV release 0.97.2 */ + FUNC_LEVEL_097_3 = 63, /**< LibClamAV release 0.97.3 */ /*last bcc changes as former team resigns*/ + FUNC_LEVEL_097_4 = 64, /**< LibClamAV release 0.97.4 */ + FUNC_LEVEL_097_5 = 65, /**< LibClamAV release 0.97.5 */ + FUNC_LEVEL_097_6 = 67, /**< LibClamAV release 0.97.6 */ + FUNC_LEVEL_097_7 = 68, /**< LibClamAV release 0.97.7 */ + FUNC_LEVEL_097_8 = 69, /**< LibClamAV release 0.97.8 */ + FUNC_LEVEL_098_1 = 76, /**< LibClamAV release 0.98.2 */ /*last syncing to clamav*/ + FUNC_LEVEL_098_2 = 77, /**< LibClamAV release 0.98.2 */ + FUNC_LEVEL_098_3 = 78, /**< LibClamAV release 0.98.3 */ + FUNC_LEVEL_100 = 100 /*future release candidate*/ }; -/** Phase of PDF parsing */ +/** +\group_pdf + * Phase of PDF parsing used for PDF Hooks + */ enum pdf_phase { - PDF_PHASE_NONE /* not a PDF */, - PDF_PHASE_PARSED, /* after parsing a PDF, object flags can be set etc. */ - PDF_PHASE_POSTDUMP, /* after an obj was dumped and scanned */ - PDF_PHASE_END, /* after the pdf scan finished */ - PDF_PHASE_PRE /* before pdf is parsed at all */ + PDF_PHASE_NONE, /* not a PDF */ + PDF_PHASE_PARSED, /**< after parsing a PDF, object flags can be set etc. */ + PDF_PHASE_POSTDUMP, /**< after an obj was dumped and scanned */ + PDF_PHASE_END, /**< after the pdf scan finished */ + PDF_PHASE_PRE /**< before pdf is parsed at all */ }; -/** PDF flags */ +/** +\group_pdf + * PDF flags + */ enum pdf_flag { - BAD_PDF_VERSION=0, - BAD_PDF_HEADERPOS, - BAD_PDF_TRAILER, - BAD_PDF_TOOMANYOBJS, - BAD_STREAM_FILTERS, - BAD_FLATE, - BAD_FLATESTART, - BAD_STREAMSTART, - BAD_ASCIIDECODE, - BAD_INDOBJ, - UNTERMINATED_OBJ_DICT, - ESCAPED_COMMON_PDFNAME, - HEX_JAVASCRIPT, - UNKNOWN_FILTER, - MANY_FILTERS, - HAS_OPENACTION, - BAD_STREAMLEN, - ENCRYPTED_PDF, - LINEARIZED_PDF, /* not bad, just as flag */ - DECRYPTABLE_PDF, - HAS_LAUNCHACTION + BAD_PDF_VERSION=0, /**< */ + BAD_PDF_HEADERPOS, /**< */ + BAD_PDF_TRAILER, /**< */ + BAD_PDF_TOOMANYOBJS, /**< */ + BAD_STREAM_FILTERS, /**< */ + BAD_FLATE, /**< */ + BAD_FLATESTART, /**< */ + BAD_STREAMSTART, /**< */ + BAD_ASCIIDECODE, /**< */ + BAD_INDOBJ, /**< */ + UNTERMINATED_OBJ_DICT, /**< */ + ESCAPED_COMMON_PDFNAME, /**< */ + HEX_JAVASCRIPT, /**< */ + UNKNOWN_FILTER, /**< */ + MANY_FILTERS, /**< */ + HAS_OPENACTION, /**< */ + BAD_STREAMLEN, /**< */ + ENCRYPTED_PDF, /**< */ + LINEARIZED_PDF, /**< */ /* not bad, just as flag */ + DECRYPTABLE_PDF, /**< */ + HAS_LAUNCHACTION /**< */ }; -/** PDF obj flags */ +/** +\group_pdf + * PDF obj flags + */ enum pdf_objflags { - OBJ_STREAM=0, - OBJ_DICT, - OBJ_EMBEDDED_FILE, - OBJ_FILTER_AH, - OBJ_FILTER_A85, - OBJ_FILTER_FLATE, - OBJ_FILTER_LZW, - OBJ_FILTER_RL, - OBJ_FILTER_FAX, - OBJ_FILTER_JBIG2, - OBJ_FILTER_DCT, - OBJ_FILTER_JPX, - OBJ_FILTER_CRYPT, - OBJ_FILTER_UNKNOWN, - OBJ_JAVASCRIPT, - OBJ_OPENACTION, - OBJ_HASFILTERS, - OBJ_SIGNED, - OBJ_IMAGE, - OBJ_TRUNCATED, - OBJ_FORCEDUMP, - OBJ_FILTER_STANDARD, - OBJ_LAUNCHACTION, - OBJ_PAGE, - OBJ_CONTENTS + OBJ_STREAM=0, /**< */ + OBJ_DICT, /**< */ + OBJ_EMBEDDED_FILE, /**< */ + OBJ_FILTER_AH, /**< */ + OBJ_FILTER_A85, /**< */ + OBJ_FILTER_FLATE, /**< */ + OBJ_FILTER_LZW, /**< */ + OBJ_FILTER_RL, /**< */ + OBJ_FILTER_FAX, /**< */ + OBJ_FILTER_JBIG2, /**< */ + OBJ_FILTER_DCT, /**< */ + OBJ_FILTER_JPX, /**< */ + OBJ_FILTER_CRYPT, /**< */ + OBJ_FILTER_UNKNOWN, /**< */ + OBJ_JAVASCRIPT, /**< */ + OBJ_OPENACTION, /**< */ + OBJ_HASFILTERS, /**< */ + OBJ_SIGNED, /**< */ + OBJ_IMAGE, /**< */ + OBJ_TRUNCATED, /**< */ + OBJ_FORCEDUMP, /**< */ + OBJ_FILTER_STANDARD, /**< */ + OBJ_LAUNCHACTION, /**< */ + OBJ_PAGE, /**< */ + OBJ_CONTENTS /**< */ +}; + +/** +\group_json + * JSON types + */ +enum bc_json_type { + JSON_TYPE_NULL=0, /**< */ + JSON_TYPE_BOOLEAN, /**< */ + JSON_TYPE_DOUBLE, /**< */ + JSON_TYPE_INT, /**< */ + JSON_TYPE_OBJECT, /**< */ + JSON_TYPE_ARRAY, /**< */ + JSON_TYPE_STRING /**< */ }; #ifdef __CLAMBC__ /* --------------- BEGIN GLOBALS -------------------------------------------- */ -/** @brief Logical signature match counts - * - * This is a low-level variable, use the Macros in bytecode_local.h instead to - * access it. +/** \group_globals - * */ + * Logical signature match counts + * @brief This is a low-level variable, use the Macros in bytecode_local.h instead to + * access it. + */ extern const uint32_t __clambc_match_counts[64]; -/** @brief Logical signature match offsets - * This is a low-level variable, use the Macros in bytecode_local.h instead to - * access it. +/** \group_globals + * Logical signature match offsets + * @brief This is a low-level variable, use the Macros in bytecode_local.h instead to + * access it. */ extern const uint32_t __clambc_match_offsets[64]; -/** PE data, if this is a PE hook. - \group_globals */ +/** +\group_globals + * PE data, if this is a PE hook. + */ extern const struct cli_pe_hook_data __clambc_pedata; -/** File size (max 4G). - \group_globals */ +/** +\group_globals + * File size (max 4G). + */ extern const uint32_t __clambc_filesize[1]; -/** Kind of the bytecode +/** \group_globals -*/ + * Kind of the bytecode, affects LibClamAV usage + */ const uint16_t __clambc_kind; /* ---------------- END GLOBALS --------------------------------------------- */ /* ---------------- BEGIN 0.96 APIs (don't touch) --------------------------- */ -/** Test api. - @param a 0xf00dbeef - @param b 0xbeeff00d - @return 0x12345678 if parameters match, 0x55 otherwise +/** + * Test api. + * @param[in] a 0xf00dbeef + * @param[in] b 0xbeeff00d + * @return 0x12345678 if parameters match, 0x55 otherwise */ uint32_t test1(uint32_t a, uint32_t b); /** - * @brief Reads specified amount of bytes from the current file +\group_file + * Reads specified amount of bytes from the current file * into a buffer. Also moves current position in the file. - * * @param[in] size amount of bytes to read * @param[out] data pointer to buffer where data is read into * @return amount read. - * \group_file */ int32_t read(uint8_t *data, int32_t size); +/** +\group_file + */ enum { /**set file position to specified absolute position */ SEEK_SET=0, @@ -194,58 +257,56 @@ enum { }; /** - * @brief Writes the specified amount of bytes from a buffer to the +\group_file + * Writes the specified amount of bytes from a buffer to the * current temporary file. * @param[in] data pointer to buffer of data to write * @param[in] size amount of bytes to write * \p size bytes to temporary file, from the buffer pointed to * byte * @return amount of bytes successfully written - * \group_file */ int32_t write(uint8_t *data, int32_t size); /** - * @brief Changes the current file position to the specified one. +\group_file + * Changes the current file position to the specified one. * @sa SEEK_SET, SEEK_CUR, SEEK_END * @param[in] pos offset (absolute or relative depending on \p whence param) * @param[in] whence one of \p SEEK_SET, \p SEEK_CUR, \p SEEK_END * @return absolute position in file - * \group_file */ int32_t seek(int32_t pos, uint32_t whence); /** +\group_scan * Sets the name of the virus found. - * * @param[in] name the name of the virus * @param[in] len length of the virusname * @return 0 - * \group_scan */ uint32_t setvirusname(const uint8_t *name, uint32_t len); /** - * Prints a debug message. - * +\group_debug + * Prints a debug message string. * @param[in] str Message to print * @param[in] len length of message to print * @return 0 - * \group_string */ uint32_t debug_print_str(const uint8_t *str, uint32_t len); /** +\group_debug * Prints a number as a debug message. - * This is like \p debug_print_str_nonl! - * + * This is similar to \p debug_print_str_nonl. * @param[in] a number to print * @return 0 - * \group_string */ uint32_t debug_print_uint(uint32_t a); /** +\group_disasm * Disassembles starting from current file position, the specified amount of * bytes. * @param[out] result pointer to struct holding result @@ -256,11 +317,10 @@ uint32_t debug_print_uint(uint32_t a); * This is a low-level API, the result is in ClamAV type-8 signature format * (64 bytes/instruction). * \sa DisassembleAt - \group_disasm */ uint32_t disasm_x86(struct DISASM_RESULT* result, uint32_t len); -/* tracing API */ +/* tracing API, private */ /* a scope: lexical block, function, or compile unit */ uint32_t trace_directory(const uint8_t* directory, uint32_t dummy); @@ -270,76 +330,88 @@ uint32_t trace_op(const uint8_t* opname, uint32_t column); uint32_t trace_value(const uint8_t* name, uint32_t v); uint32_t trace_ptr(const uint8_t* ptr, uint32_t dummy); -/** Converts a RVA (Relative Virtual Address) to - * an absolute PE file offset. - * @param rva a rva address from the PE file - * @return absolute file offset mapped to the \p rva, - * or PE_INVALID_RVA if the \p rva is invalid. - \group_pe - */ +/** +\group_pe + * Converts a RVA (Relative Virtual Address) to + * an absolute PE file offset. + * @param[in] rva a rva address from the PE file + * @return absolute file offset mapped to the \p rva, + * or PE_INVALID_RVA if the \p rva is invalid. + */ uint32_t pe_rawaddr(uint32_t rva); -/** Looks for the specified sequence of bytes in the current file. - \group_file - * @param[in] data the sequence of bytes to look for - * @param len length of \p data, cannot be more than 1024 - * @return offset in the current file if match is found, -1 otherwise */ +/** +\group_file + * Looks for the specified sequence of bytes in the current file. + * @param[in] data the sequence of bytes to look for + * @param[in] len length of \p data, cannot be more than 1024 + * @return offset in the current file if match is found, -1 otherwise + */ int32_t file_find(const uint8_t* data, uint32_t len); -/** Read a single byte from current file - \group_file - * @param offset file offset - * @return byte at offset \p off in the current file, or -1 if offset is - * invalid */ +/** +\group_file + * Read a single byte from current file + * @param[in] offset file offset + * @return byte at offset \p off in the current file, or -1 if offset is + * invalid + */ int32_t file_byteat(uint32_t offset); -/** Allocates memory. Currently this memory is freed automatically on exit - from the bytecode, and there is no way to free it sooner. - \group_adt - @param size amount of memory to allocate in bytes - @return pointer to allocated memory */ +/** +\group_adt + * Allocates memory. Currently this memory is freed automatically on exit + * from the bytecode, and there is no way to free it sooner. + * @param[in] size amount of memory to allocate in bytes + * @return pointer to allocated memory + */ void* malloc(uint32_t size); -/** Test api2. - * @param a 0xf00d - * @return 0xd00f if parameter matches, 0x5555 otherwise */ +/** + * Test api2. + * @param[in] a 0xf00d + * @return 0xd00f if parameter matches, 0x5555 otherwise + */ uint32_t test2(uint32_t a); -/** Gets information about the specified PE section. - \group_pe +/** +\group_pe + * Gets information about the specified PE section. * @param[out] section PE section information will be stored here * @param[in] num PE section number * @return 0 - success - -1 - failure */ + * @return -1 - failure + */ int32_t get_pe_section(struct cli_exe_section *section, uint32_t num); -/** Fills the specified buffer with at least \p fill bytes. - \group_file - * @param[out] buffer the buffer to fill - * @param[in] len length of buffer - * @param[in] filled how much of the buffer is currently filled - * @param[in] cursor position of cursor in buffer - * @param[in] fill amount of bytes to fill in (0 is valid) - * @return <0 on error, - * 0 on EOF, - * number bytes available in buffer (starting from 0) - * The character at the cursor will be at position 0 after this call. - */ +/** +\group_file + * Fills the specified buffer with at least \p fill bytes. + * @param[out] buffer the buffer to fill + * @param[in] len length of buffer + * @param[in] filled how much of the buffer is currently filled + * @param[in] cursor position of cursor in buffer + * @param[in] fill amount of bytes to fill in (0 is valid) + * @return <0 on error + * @return 0 on EOF + * @return number bytes available in buffer (starting from 0)\n + * The character at the cursor will be at position 0 after this call. + */ int32_t fill_buffer(uint8_t* buffer, uint32_t len, uint32_t filled, uint32_t cursor, uint32_t fill); /** +\group_scan * Prepares for extracting a new file, if we've already extracted one it scans * it. - \group_scan * @param[in] id an id for the new file (for example position in container) * @return 1 if previous extracted file was infected -*/ + */ int32_t extract_new(int32_t id); -/** - * Reads a number in the specified radix starting from the current position. - * \group_file +/** +\group_file + * Reads a number in the specified radix starting from the current position. * Non-numeric characters are ignored. * @param[in] radix 10 or 16 * @return the number read @@ -347,142 +419,161 @@ int32_t extract_new(int32_t id); int32_t read_number(uint32_t radix); /** - * Creates a new hashset and returns its id. - \group_adt - * @return ID for new hashset */ +\group_adt + * Creates a new hashset and returns its id. + * @return ID for new hashset + */ int32_t hashset_new(void); /** - * Add a new 32-bit key to the hashset. - \group_adt - * @param hs ID of hashset (from hashset_new) - * @param key the key to add - * @return 0 on success */ +\group_adt + * Add a new 32-bit key to the hashset. + * @param[in] hs ID of hashset (from hashset_new) + * @param[in] key the key to add + * @return 0 on success + */ int32_t hashset_add(int32_t hs, uint32_t key); /** - * Remove a 32-bit key from the hashset. - \group_adt - * @param hs ID of hashset (from hashset_new) - * @param key the key to add - * @return 0 on success */ +\group_adt + * Remove a 32-bit key from the hashset. + * @param[in] hs ID of hashset (from hashset_new) + * @param[in] key the key to add + * @return 0 on success + */ int32_t hashset_remove(int32_t hs, uint32_t key); /** - * Returns whether the hashset contains the specified key. - \group_adt - * @param hs ID of hashset (from hashset_new) - * @param key the key to lookup - * @return 1 if found, 0 if not found, <0 on invalid hashset ID */ +\group_adt + * Returns whether the hashset contains the specified key. + * @param[in] hs ID of hashset (from hashset_new) + * @param[in] key the key to lookup + * @return 1 if found + * @return 0 if not found + * @return <0 on invalid hashset ID + */ int32_t hashset_contains(int32_t hs, uint32_t key); /** - * Deallocates the memory used by the specified hashset. - \group_adt - * Trying to use the hashset after this will result in an error. - * The hashset may not be used after this. - * All hashsets are automatically deallocated when bytecode - * finishes execution. - * @param id ID of hashset (from hashset_new) - * @return 0 on success */ +\group_adt + * Deallocates the memory used by the specified hashset. + * Trying to use the hashset after this will result in an error. + * The hashset may not be used after this. + * All hashsets are automatically deallocated when bytecode + * finishes execution. + * @param[in] id ID of hashset (from hashset_new) + * @return 0 on success + */ int32_t hashset_done(int32_t id); /** - * Returns whether the hashset is empty. - \group_adt - * @param id of hashset (from hashset_new) - * @return 0 on success */ +\group_adt + * Returns whether the hashset is empty. + * @param[in] id of hashset (from hashset_new) + * @return 0 on success + */ int32_t hashset_empty(int32_t id); /** - * Creates a new pipe with the specified buffer size - \group_adt - * @param size size of buffer - * @return ID of newly created buffer_pipe */ +\group_adt + * Creates a new pipe with the specified buffer size + * @param[in] size size of buffer + * @return ID of newly created buffer_pipe + */ int32_t buffer_pipe_new(uint32_t size); /** - * Same as buffer_pipe_new, except the pipe's input is tied \group_adt - \group_file + * Creates a new pipe with the specified buffer size w/ tied input * to the current file, at the specified position. - * @param pos starting position of pipe input in current file - * @return ID of newly created buffer_pipe */ + * @param[in] pos starting position of pipe input in current file + * @return ID of newly created buffer_pipe + */ int32_t buffer_pipe_new_fromfile(uint32_t pos); /** +\group_adt * Returns the amount of bytes available to read. - \group_adt - * @param id ID of buffer_pipe - * @return amount of bytes available to read */ + * @param[in] id ID of buffer_pipe + * @return amount of bytes available to read + */ uint32_t buffer_pipe_read_avail(int32_t id); /** +\group_adt * Returns a pointer to the buffer for reading. - \group_adt * The 'amount' parameter should be obtained by a call to * buffer_pipe_read_avail(). - * @param id ID of buffer_pipe - * @param amount to read + * @param[in] id ID of buffer_pipe + * @param[in] amount to read * @return pointer to buffer, or NULL if buffer has less than - specified amount */ -uint8_t *buffer_pipe_read_get(int32_t id, uint32_t amount); + * specified amount + */ +//uint8_t *buffer_pipe_read_get(int32_t id, uint32_t amount); +const uint8_t *buffer_pipe_read_get(int32_t id, uint32_t amount); /** - \group_adt +\group_adt * Updates read cursor in buffer_pipe. - * @param id ID of buffer_pipe - * @param amount amount of bytes to move read cursor - * @return 0 on success */ + * @param[in] id ID of buffer_pipe + * @param[in] amount amount of bytes to move read cursor + * @return 0 on success + */ int32_t buffer_pipe_read_stopped(int32_t id, uint32_t amount); /** +\group_adt * Returns the amount of bytes available for writing. - \group_adt - * @param id ID of buffer_pipe - * @return amount of bytes available for writing */ + * @param[in] id ID of buffer_pipe + * @return amount of bytes available for writing + */ uint32_t buffer_pipe_write_avail(int32_t id); /** - \group_adt +\group_adt * Returns pointer to writable buffer. - * The 'amount' parameter should be obtained by a call to + * The 'size' parameter should be obtained by a call to * buffer_pipe_write_avail(). - * @param id ID of buffer_pipe - * @param size amount of bytes to write + * @param[in] id ID of buffer_pipe + * @param[in] size amount of bytes to write * @return pointer to write buffer, or NULL if requested amount - is more than what is available in the buffer */ + * is more than what is available in the buffer + */ uint8_t *buffer_pipe_write_get(int32_t id, uint32_t size); /** +\group_adt * Updates the write cursor in buffer_pipe. - \group_adt - * @param id ID of buffer_pipe - * @param amount amount of bytes to move write cursor - * @return 0 on success */ + * @param[in] id ID of buffer_pipe + * @param[in] amount amount of bytes to move write cursor + * @return 0 on success + */ int32_t buffer_pipe_write_stopped(int32_t id, uint32_t amount); /** +\group_adt * Deallocate memory used by buffer. - \group_adt * After this all attempts to use this buffer will result in error. * All buffer_pipes are automatically deallocated when bytecode * finishes execution. - * @param id ID of buffer_pipe - * @return 0 on success */ + * @param[in] id ID of buffer_pipe + * @return 0 on success + */ int32_t buffer_pipe_done(int32_t id); /** +\group_adt * Initializes inflate data structures for decompressing data - \group_adt * 'from_buffer' and writing uncompressed uncompressed data 'to_buffer'. - * @param from_buffer ID of buffer_pipe to read compressed data from - * @param to_buffer ID of buffer_pipe to write decompressed data to - * @param windowBits (see zlib documentation) - * @return ID of newly created inflate data structure, <0 on failure */ + * @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 + * @param[in] windowBits (see zlib documentation) + * @return ID of newly created inflate data structure, <0 on failure + */ int32_t inflate_init(int32_t from_buffer, int32_t to_buffer, int32_t windowBits); /** +\group_adt * Inflate all available data in the input buffer, and write to output buffer. * Stops when the input buffer becomes empty, or write buffer becomes full. * Also attempts to recover from corrupted inflate stream (via inflateSync). @@ -490,53 +581,57 @@ int32_t inflate_init(int32_t from_buffer, int32_t to_buffer, int32_t windowBits) * buffer, and flushing the output buffer. * The inflate stream is done processing when 0 bytes are available from output * buffer, and input buffer is not empty. - \group_adt - * @param id ID of inflate data structure - * @return 0 on success, zlib error code otherwise */ + * @param[in] id ID of inflate data structure + * @return 0 on success, zlib error code otherwise + */ int32_t inflate_process(int32_t id); /** +\group_adt * Deallocates inflate data structure. * Using the inflate data structure after this will result in an error. * All inflate data structures are automatically deallocated when bytecode * finishes execution. - \group_adt - * @param id ID of inflate data structure - * @return 0 on success.*/ + * @param[in] id ID of inflate data structure + * @return 0 on success. + */ int32_t inflate_done(int32_t id); -/** +/** +\group_scan * Report a runtime error at the specified locationID. - \group_scan - * @param locationid (line << 8) | (column&0xff) - * @return 0 */ + * @param[in] locationid (line << 8) | (column&0xff) + * @return 0 + */ int32_t bytecode_rt_error(int32_t locationid); /** +\group_js * Initializes JS normalizer for reading 'from_buffer'. * Normalized JS will be written to a single tempfile, * one normalized JS per line, and automatically scanned * when the bytecode finishes execution. - \group_js - * @param from_buffer ID of buffer_pipe to read javascript from - * @return ID of JS normalizer, <0 on failure */ + * @param[in] from_buffer ID of buffer_pipe to read javascript from + * @return ID of JS normalizer, <0 on failure + */ int32_t jsnorm_init(int32_t from_buffer); /** +\group_js * Normalize all javascript from the input buffer, and write to tempfile. * You can call this function repeatedly on success, if you (re)fill the input * buffer. - \group_js - * @param id ID of JS normalizer - * @return 0 on success, <0 on failure */ + * @param[in] id ID of JS normalizer + * @return 0 on success, <0 on failure + */ int32_t jsnorm_process(int32_t id); /** +\group_js * Flushes JS normalizer. - \group_js - * @param id ID of js normalizer to flush - * @return 0 - success - -1 - failure */ + * @param[in] id ID of js normalizer to flush + * @return 0 on success, <0 on failure + */ int32_t jsnorm_done(int32_t id); /* ---------------- END 0.96 APIs (don't touch) --------------------------- */ @@ -545,457 +640,558 @@ int32_t jsnorm_done(int32_t id); /* ---------------- Math -------------------------------------------------- */ /** - * Returns 2^26*log2(a/b) - * @param a input - * @param b input +\group_math + * Returns 2^26*log2(a/b) + * @param[in] a input + * @param[in] b input * @return 2^26*log2(a/b) - \group_math */ int32_t ilog2(uint32_t a, uint32_t b); /** +\group_math * Returns c*a^b. - * @param a integer - * @param b integer - * @param c integer + * @param[in] a integer + * @param[in] b integer + * @param[in] c integer * @return c*pow(a,b) - \group_math */ int32_t ipow(int32_t a, int32_t b, int32_t c); /** +\group_math * Returns exp(a/b)*c - * @param a integer - * @param b integer - * @param c integer + * @param[in] a integer + * @param[in] b integer + * @param[in] c integer * @return c*exp(a/b) - \group_math */ uint32_t iexp(int32_t a, int32_t b, int32_t c); /** +\group_math * Returns c*sin(a/b). - * @param a integer - * @param b integer - * @param c integer + * @param[in] a integer + * @param[in] b integer + * @param[in] c integer * @return c*sin(a/b) - \group_math */ int32_t isin(int32_t a, int32_t b, int32_t c); /** +\group_math * Returns c*cos(a/b). - * @param a integer - * @param b integer - * @param c integer + * @param[in] a integer + * @param[in] b integer + * @param[in] c integer * @return c*sin(a/b) - \group_math */ int32_t icos(int32_t a, int32_t b, int32_t c); /* ---------------- String operations --------------------------------------- */ /** +\group_string * Return position of match, -1 otherwise. - * @param haystack buffer to search - * @param haysize size of \p haystack - * @param needle substring to search - * @param needlesize size of needle + * @param[in] haystack buffer to search + * @param[in] haysize size of \p haystack + * @param[in] needle substring to search + * @param[in] needlesize size of needle * @return location of match, -1 otherwise - \group_string */ int32_t memstr(const uint8_t* haystack, int32_t haysize, const uint8_t* needle, int32_t needlesize); /** +\group_string * Returns hexadecimal characters \p hex1 and \p hex2 converted to 8-bit * number. - * @param hex1 hexadecimal character - * @param hex2 hexadecimal character + * @param[in] hex1 hexadecimal character + * @param[in] hex2 hexadecimal character * @return hex1 hex2 converted to 8-bit integer, -1 on error - \group_string */ int32_t hex2ui(uint32_t hex1, uint32_t hex2); /** +\group_string * Converts string to positive number. - * @param str buffer - * @param size size of \p str + * @param[in] str buffer + * @param[in] size size of \p str * @return >0 string converted to number if possible, -1 on error - \group_string */ int32_t atoi(const uint8_t* str, int32_t size); /** +\group_debug * Prints a debug message with a trailing newline, * but preceded by 'LibClamAV debug'. - * @param str the string - * @param len length of \p str + * @param[in] str the string + * @param[in] len length of \p str * @return 0 - \group_string */ uint32_t debug_print_str_start(const uint8_t *str, uint32_t len); /** +\group_debug * Prints a debug message with a trailing newline, * and not preceded by 'LibClamAV debug'. - * @param str the string - * @param len length of \p str + * @param[in] str the string + * @param[in] len length of \p str * @return 0 - \group_string */ uint32_t debug_print_str_nonl(const uint8_t *str, uint32_t len); /** +\group_string * Returns an approximation for the entropy of \p buffer. - * @param buffer input buffer - * @param size size of buffer + * @param[in] buffer input buffer + * @param[in] size size of buffer * @return entropy estimation * 2^26 - \group_string */ uint32_t entropy_buffer(uint8_t* buffer, int32_t size); /* ------------------ Data Structures --------------------------------------- */ /** - * Creates a new map and returns its id. - * @param keysize size of key - * @param valuesize size of value, if 0 then value is allocated separately - * @return ID of new map \group_adt + * Creates a new map and returns its id. + * @param[in] keysize size of key + * @param[in] valuesize size of value, if 0 then value is allocated separately + * @return ID of new map */ int32_t map_new(int32_t keysize, int32_t valuesize); /** - * Inserts the specified key/value pair into the map. - * @param id id of table - * @param key key - * @param ksize size of \p key - * @return 0 - if key existed before - 1 - if key didn't exist before - <0 - if ksize doesn't match keysize specified at table creation \group_adt + * Inserts the specified key/value pair into the map. + * @param[in] id id of table + * @param[in] key key + * @param[in] ksize size of \p key + * @return 0 - if key existed before + * @return 1 - if key didn't exist before + * @return <0 - if ksize doesn't match keysize specified at table creation */ int32_t map_addkey(const uint8_t *key, int32_t ksize, int32_t id); /** - * Sets the value for the last inserted key with map_addkey. - * @param id id of table - * @param value value - * @param vsize size of \p value - * @return 0 - if update was successful - <0 - if there is no last key \group_adt + * Sets the value for the last inserted key with map_addkey. + * @param[in] id id of table + * @param[in] value value + * @param[in] vsize size of \p value + * @return 0 - if update was successful + * @return <0 - if there is no last key */ int32_t map_setvalue(const uint8_t *value, int32_t vsize, int32_t id); /** - * Remove an element from the map. - * @param id id of map - * @param key key - * @param ksize size of key - * @return 0 on success, key was present - 1 if key was not present - <0 if ksize doesn't match keysize specified at table creation \group_adt + * Remove an element from the map. + * @param[in] id id of map + * @param[in] key key + * @param[in] ksize size of key + * @return 0 on success, key was present + * @return 1 if key was not present + * @return <0 if ksize doesn't match keysize specified at table creation */ int32_t map_remove(const uint8_t* key, int32_t ksize, int32_t id); /** +\group_adt * Looks up key in map. * The map remember the last looked up key (so you can retrieve the * value). - * - * @param id id of map - * @param key key - * @param ksize size of key + * @param[in] id id of map + * @param[in] key key + * @param[in] ksize size of key * @return 0 - if not found - 1 - if found - <0 - if ksize doesn't match the size specified at table creation -\group_adt + * @return 1 - if found + * @return <0 - if ksize doesn't match the size specified at table creation */ int32_t map_find(const uint8_t* key, int32_t ksize, int32_t id); /** - * Returns the size of value obtained during last map_find. - * @param id id of map. - * @return size of value \group_adt + * Returns the size of value obtained during last map_find. + * @param[in] id id of map. + * @return size of value */ int32_t map_getvaluesize(int32_t id); /** - * Returns the value obtained during last map_find. - * @param id id of map. - * @param size size of value (obtained from map_getvaluesize) - * @return value \group_adt + * Returns the value obtained during last map_find. + * @param[in] id id of map. + * @param[in] size size of value (obtained from map_getvaluesize) + * @return value */ uint8_t* map_getvalue(int32_t id, int32_t size); /** +\group_adt * Deallocates the memory used by the specified map. * Trying to use the map after this will result in an error. * All maps are automatically deallocated when the bytecode finishes * execution. - * @param id id of map + * @param[in] id id of map * @return 0 - success - -1 - invalid map -\group_adt + * @return -1 - invalid map */ int32_t map_done(int32_t id); /* -------------- File Operations ------------------------------------------- */ -/** Looks for the specified sequence of bytes in the current file, up to the - * specified position. - * @param[in] data the sequence of bytes to look for - * @param len length of \p data, cannot be more than 1024 - * @param maxpos maximum position to look for a match, - * note that this is 1 byte after the end of last possible match: - * match_pos + \p len < \p maxpos - * @return offset in the current file if match is found, -1 otherwise - * \group_file - */ +/** +\group_file + * Looks for the specified sequence of bytes in the current file, up to the + * specified position. + * @param[in] data the sequence of bytes to look for + * @param[in] len length of \p data, cannot be more than 1024 + * @param[in] maxpos maximum position to look for a match, + * note that this is 1 byte after the end of last possible match: + * match_pos + \p len < \p maxpos + * @return offset in the current file if match is found, -1 otherwise + */ int32_t file_find_limit(const uint8_t *data, uint32_t len, int32_t maxpos); /* ------------- Engine Query ----------------------------------------------- */ /** +\group_engine * Returns the current engine (feature) functionality level. * To map these to ClamAV releases, compare it with #FunctionalityLevels. * @return an integer representing current engine functionality level. - * \group_engine */ uint32_t engine_functionality_level(void); /** +\group_engine * Returns the current engine (dconf) functionality level. * Usually identical to engine_functionality_level(), unless distro backported * patches. Compare with #FunctionalityLevels. * @return an integer representing the DCONF (security fixes) level. - * \group_engine */ uint32_t engine_dconf_level(void); /** +\group_engine * Returns the current engine's scan options. * @return CL_SCAN* flags - * \group_engine */ uint32_t engine_scan_options(void); /** +\group_engine * Returns the current engine's db options. * @return CL_DB_* flags - * \group_engine */ uint32_t engine_db_options(void); /* ---------------- Scan Control -------------------------------------------- */ /** +\group_scan * Sets the container type for the currently extracted file. - * @param container container type (CL_TYPE_*) + * @param[in] container container type (CL_TYPE_*) * @return current setting for container (CL_TYPE_ANY default) - * \group_scan */ int32_t extract_set_container(uint32_t container); /** +\group_scan * Toggles the read/seek API to read from the currently extracted file, and * back. * You must call seek after switching inputs to position the cursor to a valid * position. - * @param extracted_file 1 - switch to reading from extracted file, - 0 - switch back to original input + * @param[in] extracted_file 1 - switch to reading from extracted file\n + 0 - switch back to original input * @return -1 on error (if no extracted file exists) - 0 on success - * \group_scan + * @return 0 on success */ int32_t input_switch(int32_t extracted_file); /* ---------------- END 0.96.1 APIs ------------------------------------- */ /* ---------------- BEGIN 0.96.2 APIs ----------------------------------- */ -/** Queries the environment this bytecode runs in. +/** +\group_env + * Queries the environment this bytecode runs in. * Used by BC_STARTUP to disable bytecode when bugs are known for the current * platform. * @param[out] env - the full environment - * @param len - size of \p env + * @param[in] len - size of \p env * @return 0 - \group_env */ uint32_t get_environment(struct cli_environment *env, uint32_t len); -/** Disables the bytecode completely if condition is true. - Can only be called from the BC_STARTUP bytecode. - @param reason - why the bytecode had to be disabled - @param len - length of reason - @param cond - condition - @return 0 - auto mode - 1 - JIT disabled - 2 - fully disabled - \group_env +/** +\group_env + * Disables the bytecode completely if condition is true. + * Can only be called from the BC_STARTUP bytecode. + * @param[in] reason - why the bytecode had to be disabled + * @param[in] len - length of reason + * @param[in] cond - condition + * @return 0 - auto mode + * @return 1 - JIT disabled + * @return 2 - fully disabled */ uint32_t disable_bytecode_if(const int8_t *reason, uint32_t len, uint32_t cond); -/** Disables the JIT completely if condition is true. - Can only be called from the BC_STARTUP bytecode. - @param reason - why the JIT had to be disabled - @param len - length of reason - @param cond - condition - @return 0 - auto mode - 1 - JIT disabled - 2 - fully disabled - \group_env +/** +\group_env + * Disables the JIT completely if condition is true. + * Can only be called from the BC_STARTUP bytecode. + * @param[in] reason - why the JIT had to be disabled + * @param[in] len - length of reason + * @param[in] cond - condition + * @return 0 - auto mode + * @return 1 - JIT disabled + * @return 2 - fully disabled */ uint32_t disable_jit_if(const int8_t* reason, uint32_t len, uint32_t cond); -/** Compares two version numbers. +/** + \group_env + * Compares two version numbers. * @param[in] lhs - left hand side of comparison - @param lhs_len - length of \p lhs - @param[in] rhs - right hand side of comparison - @param rhs_len - length of \p rhs - @return -1 - lhs < rhs - 0 - lhs == rhs - 1 - lhs > rhs - \group_env + * @param[in] lhs_len - length of \p lhs + * @param[in] rhs - right hand side of comparison + * @param[in] rhs_len - length of \p rhs + * @return -1 - lhs < rhs + * @return 0 - lhs == rhs + * @return 1 - lhs > rhs */ int32_t version_compare(const uint8_t* lhs, uint32_t lhs_len, const uint8_t* rhs, uint32_t rhs_len); -/** Disables the JIT if the platform id matches. +/** +\group_env + * Disables the JIT if the platform id matches. * 0xff can be used instead of a field to mark ANY. - * @param a - os_category << 24 | arch << 20 | compiler << 16 | flevel << 8 | dconf - @param b - big_endian << 28 | sizeof_ptr << 24 | cpp_version - @param c - os_features << 24 | c_version - @return 0 - no match - 1 - match - \group_env + * @param[in] a - os_category << 24 | arch << 20 | compiler << 16 | flevel << 8 | dconf + * @param[in] b - big_endian << 28 | sizeof_ptr << 24 | cpp_version + * @param[in] c - os_features << 24 | c_version + * @return 0 - no match + * @return 1 - match */ uint32_t check_platform(uint32_t a, uint32_t b, uint32_t c); /* --------------------- PDF APIs ----------------------------------- */ -/** Return number of pdf objects +/** +\group_pdf + * Return number of pdf objects * @return -1 - if not called from PDF hook - >=0 - number of PDF objects - \group_pdf + * @return >=0 - number of PDF objects */ int32_t pdf_get_obj_num(void); -/** Return the flags for the entire PDF (as set so far). +/** +\group_pdf + * Return the flags for the entire PDF (as set so far). * @return -1 - if not called from PDF hook - >=0 - pdf flags - \group_pdf + * @return >=0 - pdf flags */ int32_t pdf_get_flags(void); -/** Sets the flags for the entire PDF. +/** +\group_pdf + * Sets the flags for the entire PDF. * It is recommended that you retrieve old flags, and just add new ones. - \group_pdf - * @param flags - flags to set. + * @param[in] flags - flags to set. * @return 0 - success -1 - invalid phase */ int32_t pdf_set_flags(int32_t flags); -/** Lookup pdf object with specified id. - \group_pdf - * @param id - pdf id (objnumber << 8 | generationid) - @return -1 - if object id doesn't exist - >=0 - object index +/** +\group_pdf + * Lookup pdf object with specified id. + * @param[in] id - pdf id (objnumber << 8 | generationid) + * @return -1 - if object id doesn't exist + * @return >=0 - object index */ int32_t pdf_lookupobj(uint32_t id); -/** Return the size of the specified PDF obj. - \group_pdf - * @param objidx - object index (from 0), not object id! +/** +\group_pdf + * Return the size of the specified PDF obj. + * @param[in] objidx - object index (from 0), not object id! * @return 0 - if not called from PDF hook, or invalid objnum - >=0 - size of object */ + * @return >=0 - size of object */ uint32_t pdf_getobjsize(int32_t objidx); -/** Return the undecoded object. - \group_pdf - Meant only for reading, write modifies the fmap buffer, so avoid! - @param objidx - object index (from 0), not object id! - @param amount - size returned by pdf_getobjsize (or smaller) - @return NULL - invalid objidx/amount - pointer - pointer to original object */ -uint8_t *pdf_getobj(int32_t objidx, uint32_t amount); +/** +\group_pdf + * Return the undecoded object. + * Meant only for reading, write modifies the fmap buffer, so avoid! + * @param[in] objidx - object index (from 0), not object id! + * @param[in] amount - size returned by pdf_getobjsize (or smaller) + * @return NULL - invalid objidx/amount + * @return pointer - pointer to original object */ +//uint8_t *pdf_getobj(int32_t objidx, uint32_t amount); +const uint8_t *pdf_getobj(int32_t objidx, uint32_t amount); -/* Return the object id for the specified object index. - \group_pdf - @param objidx - object index (from 0) - @return -1 - object index invalid - >=0 - object id (obj id << 8 | generation id) -*/ +/** +\group_pdf + * Return the object id for the specified object index. + * @param[in] objidx - object index (from 0) + * @return -1 - object index invalid + * @return >=0 - object id (obj id << 8 | generation id) + */ int32_t pdf_getobjid(int32_t objidx); -/* Return the object flags for the specified object index. - \group_pdf - @param objidx - object index (from 0) - @return -1 - object index invalid - >=0 - object flags -*/ +/** +\group_pdf + * Return the object flags for the specified object index. + * @param[in] objidx - object index (from 0) + * @return -1 - object index invalid + * @return >=0 - object flags + */ int32_t pdf_getobjflags(int32_t objidx); -/* Sets the object flags for the specified object index. - \group_pdf - This can be used to force dumping of a certain obj, by setting the - OBJ_FORCEDUMP flag for example. - @param objidx - object index (from 0) - @return -1 - object index invalid - >=0 - flags set -*/ +/** +\group_pdf + * Sets the object flags for the specified object index. + * This can be used to force dumping of a certain obj, by setting the + * OBJ_FORCEDUMP flag for example. + * @param[in] objidx - object index (from 0) + * @param[in] flags - value to set flags + * @return -1 - object index invalid + * @return >=0 - flags set + */ int32_t pdf_setobjflags(int32_t objidx, int32_t flags); -/* Return the object's offset in the PDF. - \group_pdf - @param objidx - object index (from 0) - @return -1 - object index invalid - >=0 - offset -*/ +/** +\group_pdf + * Return the object's offset in the PDF. + * @param[in] objidx - object index (from 0) + * @return -1 - object index invalid + * @return >=0 - offset + */ int32_t pdf_get_offset(int32_t objidx); -/** Return an 'enum pdf_phase'. - \group_pdf +/** +\group_pdf + * Return an 'enum pdf_phase'. * Identifies at which phase this bytecode was called. * @return the current #pdf_phase */ int32_t pdf_get_phase(void); -/** Return the currently dumped obj index. - \group_pdf +/** +\group_pdf + * Return the currently dumped obj index. * Valid only in PDF_PHASE_POSTDUMP. * @return >=0 - object index - -1 - invalid phase + * @return -1 - invalid phase */ int32_t pdf_get_dumpedobjid(void); /* ----------------------------- Icon APIs -------------------------- */ -/** Attempts to match current executable's icon against the specified icon +/** +\group_icon + * Attempts to match current executable's icon against the specified icon * groups. - \group_icon * @param[in] group1 - same as GROUP1 in LDB signatures - * @param group1_len - length of \p group1 + * @param[in] group1_len - length of \p group1 * @param[in] group2 - same as GROUP2 in LDB signatures - * @param group2_len - length of \p group2 + * @param[in] group2_len - length of \p group2 * @return -1 - invalid call, or sizes (only valid for PE hooks) - 0 - not a match - 1 - match + * @return 0 - not a match + * @return 1 - match */ - int32_t matchicon(const uint8_t* group1, int32_t group1_len, const uint8_t* group2, int32_t group2_len); /* ---------------- END 0.96.2 APIs ----------------------------------- */ /* ----------------- BEGIN 0.96.4 APIs ---------------------------------- */ -/* Returns whether running on JIT. As side-effect it disables - * interp / JIT comparisons in test mode (errors are still checked) */ +/** +\group_engine + * Returns whether running on JIT. As side-effect it disables + * interp / JIT comparisons in test mode (errors are still checked) + * @return 1 - running on JIT + * @return 0 - running on ClamAV interpreter + */ int32_t running_on_jit(void); -/* Get file reliability flag, higher value means less reliable - * 0 - normal - * 1 - embedded PE - * 2 - unpacker created file (not impl. yet) - * - * when >0 import tables and such are not reliable */ +/** +\group_file + * Get file reliability flag, higher value means less reliable. + * When >0 import tables and such are not reliable + * @return 0 - normal + * @return 1 - embedded PE + * @return 2 - unpacker created file (not impl. yet) + */ int32_t get_file_reliability(void); /* ----------------- END 0.96.4 APIs ---------------------------------- */ +/* ----------------- BEGIN 0.98.3 APIs -------------------------------- */ +/* ----------------- JSON Parsing APIs -------------------------------- */ +/* +\group_json + * @return 0 - json is disabled or option not specified + * @return 1 - json is active and properties are available + */ +int32_t json_is_active(void); + +/* +\group_json + * @return objid of json object with specified name + * @return 0 if json object of specified name cannot be found + * @return -1 if an error has occurred + * @param[in] name - name of object in ASCII + * @param[in] name_len - length of specified name (not including terminating NULL), + * must be >= 0 + * @param[in] objid - id value of json object to query + */ +int32_t json_get_object(const int8_t* name, int32_t name_len, int32_t objid); + +/* +\group_json + * @return type (json_type) of json object specified + * @return -1 if type unknown or invalid id + * @param[in] objid - id value of json object to query + */ +int32_t json_get_type(int32_t objid); + + +//int32_t json_get_boolean(int32_t objid); +//double json_get_double(int32_t objid); +//int32_t json_get_int(int32_t objid); + +/* +\group_json + * @return number of elements in the json array of objid + * @return -1 if an error has occurred + * @return -2 if object is not JSON_TYPE_ARRAY + * @param[in] objid - id value of json object (should be JSON_TYPE_ARRAY) to query + */ +int32_t json_get_array_length(int32_t objid); + +/* +\group_json + * @return objid of json object at idx of json array of objid + * @return 0 if invalid idx + * @return -1 if an error has occurred + * @return -2 if object is not JSON_TYPE_ARRAY + * @param[in] idx - index of array to query, must be >= 0 and less than array length + * @param[in] objid - id value of json object (should be JSON_TYPE_ARRAY) to query + */ +int32_t json_get_array_idx(int32_t idx, int32_t objid); + +/* +\group_json + * @return length of json string of objid + * @return -1 if an error has occurred + * @return -2 if object is not JSON_TYPE_STRING + * @param[in] objid - id value of json object (should be JSON_TYPE_STRING) to query + */ +int32_t json_get_string_length(int32_t objid); + +/* +\group_json + * @return number of characters transferred (capped by str_len) + * @return -1 if an error has occurred + * @return -2 if object is not JSON_TYPE_STRING + * @param[out] str - user location to store string data + * @param[in] str_len - length of str or limit of string data to read + * @param[in] objid - id value of json object (should be JSON_TYPE_STRING) to query + */ +int32_t json_get_string(int8_t* str, int32_t str_len, int32_t objid); + +/* ----------------- END 0.98.3 APIs ---------------------------------- */ #endif #endif diff --git a/libclamav/bytecode_api_decl.c b/libclamav/bytecode_api_decl.c index 0c5bca969..93cd34760 100644 --- a/libclamav/bytecode_api_decl.c +++ b/libclamav/bytecode_api_decl.c @@ -2,8 +2,8 @@ * ClamAV bytecode internal API * This is an automatically generated file! * - * Copyright (C) 2009-2010 Sourcefire, Inc. - * All rights reserved. + * Copyright (C) 2009-2013 Sourcefire, Inc. + * Copyright (C) 2014 Cisco Systems, Inc. and/or its affiliates. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -52,7 +52,7 @@ int32_t cli_bcapi_file_find(struct cli_bc_ctx *ctx , const uint8_t*, uint32_t); int32_t cli_bcapi_file_byteat(struct cli_bc_ctx *ctx , uint32_t); uint8_t* cli_bcapi_malloc(struct cli_bc_ctx *ctx , uint32_t); uint32_t cli_bcapi_test2(struct cli_bc_ctx *ctx , uint32_t); -int32_t cli_bcapi_get_pe_section(struct cli_bc_ctx *ctx , void*, uint32_t); +int32_t cli_bcapi_get_pe_section(struct cli_bc_ctx *ctx , struct cli_exe_section*, uint32_t); int32_t cli_bcapi_fill_buffer(struct cli_bc_ctx *ctx , uint8_t*, uint32_t, uint32_t, uint32_t, uint32_t); int32_t cli_bcapi_extract_new(struct cli_bc_ctx *ctx , int32_t); int32_t cli_bcapi_read_number(struct cli_bc_ctx *ctx , uint32_t); @@ -124,6 +124,13 @@ int32_t cli_bcapi_pdf_get_dumpedobjid(struct cli_bc_ctx *ctx ); int32_t cli_bcapi_matchicon(struct cli_bc_ctx *ctx , const uint8_t*, int32_t, const uint8_t*, int32_t); int32_t cli_bcapi_running_on_jit(struct cli_bc_ctx *ctx ); int32_t cli_bcapi_get_file_reliability(struct cli_bc_ctx *ctx ); +int32_t cli_bcapi_json_is_active(struct cli_bc_ctx *ctx ); +int32_t cli_bcapi_json_get_object(struct cli_bc_ctx *ctx , const int8_t*, int32_t, int32_t); +int32_t cli_bcapi_json_get_type(struct cli_bc_ctx *ctx , int32_t); +int32_t cli_bcapi_json_get_array_length(struct cli_bc_ctx *ctx , int32_t); +int32_t cli_bcapi_json_get_array_idx(struct cli_bc_ctx *ctx , int32_t, int32_t); +int32_t cli_bcapi_json_get_string_length(struct cli_bc_ctx *ctx , int32_t); +int32_t cli_bcapi_json_get_string(struct cli_bc_ctx *ctx , int8_t*, int32_t, int32_t); const struct cli_apiglobal cli_globals[] = { /* Bytecode globals BEGIN */ @@ -148,13 +155,13 @@ 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}; -static uint16_t cli_tmp9[]={32, 65, 32, 65, 32}; -static uint16_t cli_tmp10[]={32, 32}; -static uint16_t cli_tmp11[]={32, 32, 32}; -static uint16_t cli_tmp12[]={65, 32, 32}; -static uint16_t cli_tmp13[]={32, 32, 32, 32}; -static uint16_t cli_tmp14[]={32, 65, 32, 32}; +static uint16_t cli_tmp8[]={32, 65, 32, 32}; +static uint16_t cli_tmp9[]={32, 32}; +static uint16_t cli_tmp10[]={32, 32, 32}; +static uint16_t cli_tmp11[]={32}; +static uint16_t cli_tmp12[]={32, 65, 32, 65, 32}; +static uint16_t cli_tmp13[]={65, 32, 32}; +static uint16_t cli_tmp14[]={32, 32, 32, 32}; static uint16_t cli_tmp15[]={32, 85, 32}; static uint16_t cli_tmp16[]={86}; static uint16_t cli_tmp17[]={32, 32, 32, 32, 32, 32, 32, 87, 87, 87, 87, 87, 87, 87, 8, 8, 8, 8, 8, 8, 8, 8, 8}; @@ -181,12 +188,12 @@ 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, 1, 0, 0}, - {DFunctionType, cli_tmp9, 5, 0, 0}, - {DFunctionType, cli_tmp10, 2, 0, 0}, - {DFunctionType, cli_tmp11, 3, 0, 0}, - {DFunctionType, cli_tmp12, 3, 0, 0}, - {DFunctionType, cli_tmp13, 4, 0, 0}, + {DFunctionType, cli_tmp8, 4, 0, 0}, + {DFunctionType, cli_tmp9, 2, 0, 0}, + {DFunctionType, cli_tmp10, 3, 0, 0}, + {DFunctionType, cli_tmp11, 1, 0, 0}, + {DFunctionType, cli_tmp12, 5, 0, 0}, + {DFunctionType, cli_tmp13, 3, 0, 0}, {DFunctionType, cli_tmp14, 4, 0, 0}, {DFunctionType, cli_tmp15, 3, 0, 0}, {DPointerType, cli_tmp16, 1, 0, 0}, @@ -209,13 +216,13 @@ 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}, + {"test1", 10, 0, 0}, {"read", 19, 0, 1}, {"write", 19, 1, 1}, - {"seek", 11, 1, 0}, + {"seek", 10, 1, 0}, {"setvirusname", 19, 2, 1}, {"debug_print_str", 19, 3, 1}, - {"debug_print_uint", 10, 0, 2}, + {"debug_print_uint", 9, 0, 2}, {"disasm_x86", 25, 4, 1}, {"trace_directory", 19, 5, 1}, {"trace_scope", 19, 6, 1}, @@ -223,83 +230,90 @@ const struct cli_apicall cli_apicalls[]={ {"trace_op", 19, 8, 1}, {"trace_value", 19, 9, 1}, {"trace_ptr", 19, 10, 1}, - {"pe_rawaddr", 10, 1, 2}, + {"pe_rawaddr", 9, 1, 2}, {"file_find", 19, 11, 1}, - {"file_byteat", 10, 2, 2}, + {"file_byteat", 9, 2, 2}, {"malloc", 24, 0, 3}, - {"test2", 10, 3, 2}, + {"test2", 9, 3, 2}, {"get_pe_section", 21, 12, 1}, {"fill_buffer", 20, 0, 4}, - {"extract_new", 10, 4, 2}, - {"read_number", 10, 5, 2}, - {"hashset_new", 8, 0, 5}, - {"hashset_add", 11, 2, 0}, - {"hashset_remove", 11, 3, 0}, - {"hashset_contains", 11, 4, 0}, - {"hashset_done", 10, 6, 2}, - {"hashset_empty", 10, 7, 2}, - {"buffer_pipe_new", 10, 8, 2}, - {"buffer_pipe_new_fromfile", 10, 9, 2}, - {"buffer_pipe_read_avail", 10, 10, 2}, - {"buffer_pipe_read_get", 12, 0, 6}, - {"buffer_pipe_read_stopped", 11, 5, 0}, - {"buffer_pipe_write_avail", 10, 11, 2}, - {"buffer_pipe_write_get", 12, 1, 6}, - {"buffer_pipe_write_stopped", 11, 6, 0}, - {"buffer_pipe_done", 10, 12, 2}, - {"inflate_init", 13, 0, 7}, - {"inflate_process", 10, 13, 2}, - {"inflate_done", 10, 14, 2}, - {"bytecode_rt_error", 10, 15, 2}, - {"jsnorm_init", 10, 16, 2}, - {"jsnorm_process", 10, 17, 2}, - {"jsnorm_done", 10, 18, 2}, - {"ilog2", 11, 7, 0}, - {"ipow", 13, 1, 7}, - {"iexp", 13, 2, 7}, - {"isin", 13, 3, 7}, - {"icos", 13, 4, 7}, - {"memstr", 9, 0, 8}, - {"hex2ui", 11, 8, 0}, + {"extract_new", 9, 4, 2}, + {"read_number", 9, 5, 2}, + {"hashset_new", 11, 0, 5}, + {"hashset_add", 10, 2, 0}, + {"hashset_remove", 10, 3, 0}, + {"hashset_contains", 10, 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}, + {"buffer_pipe_read_get", 13, 0, 6}, + {"buffer_pipe_read_stopped", 10, 5, 0}, + {"buffer_pipe_write_avail", 9, 11, 2}, + {"buffer_pipe_write_get", 13, 1, 6}, + {"buffer_pipe_write_stopped", 10, 6, 0}, + {"buffer_pipe_done", 9, 12, 2}, + {"inflate_init", 14, 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", 10, 7, 0}, + {"ipow", 14, 1, 7}, + {"iexp", 14, 2, 7}, + {"isin", 14, 3, 7}, + {"icos", 14, 4, 7}, + {"memstr", 12, 0, 8}, + {"hex2ui", 10, 8, 0}, {"atoi", 19, 13, 1}, {"debug_print_str_start", 19, 14, 1}, {"debug_print_str_nonl", 19, 15, 1}, {"entropy_buffer", 19, 16, 1}, - {"map_new", 11, 9, 0}, - {"map_addkey", 14, 0, 9}, - {"map_setvalue", 14, 1, 9}, - {"map_remove", 14, 2, 9}, - {"map_find", 14, 3, 9}, - {"map_getvaluesize", 10, 19, 2}, - {"map_getvalue", 12, 2, 6}, - {"map_done", 10, 20, 2}, - {"file_find_limit", 14, 4, 9}, - {"engine_functionality_level", 8, 1, 5}, - {"engine_dconf_level", 8, 2, 5}, - {"engine_scan_options", 8, 3, 5}, - {"engine_db_options", 8, 4, 5}, - {"extract_set_container", 10, 21, 2}, - {"input_switch", 10, 22, 2}, + {"map_new", 10, 9, 0}, + {"map_addkey", 8, 0, 9}, + {"map_setvalue", 8, 1, 9}, + {"map_remove", 8, 2, 9}, + {"map_find", 8, 3, 9}, + {"map_getvaluesize", 9, 19, 2}, + {"map_getvalue", 13, 2, 6}, + {"map_done", 9, 20, 2}, + {"file_find_limit", 8, 4, 9}, + {"engine_functionality_level", 11, 1, 5}, + {"engine_dconf_level", 11, 2, 5}, + {"engine_scan_options", 11, 3, 5}, + {"engine_db_options", 11, 4, 5}, + {"extract_set_container", 9, 21, 2}, + {"input_switch", 9, 22, 2}, {"get_environment", 15, 17, 1}, - {"disable_bytecode_if", 14, 5, 9}, - {"disable_jit_if", 14, 6, 9}, - {"version_compare", 9, 1, 8}, - {"check_platform", 13, 5, 7}, - {"pdf_get_obj_num", 8, 5, 5}, - {"pdf_get_flags", 8, 6, 5}, - {"pdf_set_flags", 10, 23, 2}, - {"pdf_lookupobj", 10, 24, 2}, - {"pdf_getobjsize", 10, 25, 2}, - {"pdf_getobj", 12, 3, 6}, - {"pdf_getobjid", 10, 26, 2}, - {"pdf_getobjflags", 10, 27, 2}, - {"pdf_setobjflags", 11, 10, 0}, - {"pdf_get_offset", 10, 28, 2}, - {"pdf_get_phase", 8, 7, 5}, - {"pdf_get_dumpedobjid", 8, 8, 5}, - {"matchicon", 9, 2, 8}, - {"running_on_jit", 8, 9, 5}, - {"get_file_reliability", 8, 10, 5} + {"disable_bytecode_if", 8, 5, 9}, + {"disable_jit_if", 8, 6, 9}, + {"version_compare", 12, 1, 8}, + {"check_platform", 14, 5, 7}, + {"pdf_get_obj_num", 11, 5, 5}, + {"pdf_get_flags", 11, 6, 5}, + {"pdf_set_flags", 9, 23, 2}, + {"pdf_lookupobj", 9, 24, 2}, + {"pdf_getobjsize", 9, 25, 2}, + {"pdf_getobj", 13, 3, 6}, + {"pdf_getobjid", 9, 26, 2}, + {"pdf_getobjflags", 9, 27, 2}, + {"pdf_setobjflags", 10, 10, 0}, + {"pdf_get_offset", 9, 28, 2}, + {"pdf_get_phase", 11, 7, 5}, + {"pdf_get_dumpedobjid", 11, 8, 5}, + {"matchicon", 12, 2, 8}, + {"running_on_jit", 11, 9, 5}, + {"get_file_reliability", 11, 10, 5}, + {"json_is_active", 11, 11, 5}, + {"json_get_object", 8, 7, 9}, + {"json_get_type", 9, 29, 2}, + {"json_get_array_length", 9, 30, 2}, + {"json_get_array_idx", 10, 11, 0}, + {"json_get_string_length", 9, 31, 2}, + {"json_get_string", 8, 8, 9} /* Bytecode APIcalls END */ }; const cli_apicall_int2 cli_apicalls0[] = { @@ -313,7 +327,8 @@ const cli_apicall_int2 cli_apicalls0[] = { (cli_apicall_int2)cli_bcapi_ilog2, (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_pdf_setobjflags, + (cli_apicall_int2)cli_bcapi_json_get_array_idx }; const cli_apicall_pointer cli_apicalls1[] = { (cli_apicall_pointer)cli_bcapi_read, @@ -364,7 +379,10 @@ const cli_apicall_int1 cli_apicalls2[] = { (cli_apicall_int1)cli_bcapi_pdf_getobjsize, (cli_apicall_int1)cli_bcapi_pdf_getobjid, (cli_apicall_int1)cli_bcapi_pdf_getobjflags, - (cli_apicall_int1)cli_bcapi_pdf_get_offset + (cli_apicall_int1)cli_bcapi_pdf_get_offset, + (cli_apicall_int1)cli_bcapi_json_get_type, + (cli_apicall_int1)cli_bcapi_json_get_array_length, + (cli_apicall_int1)cli_bcapi_json_get_string_length }; const cli_apicall_malloclike cli_apicalls3[] = { (cli_apicall_malloclike)cli_bcapi_malloc @@ -383,7 +401,8 @@ const cli_apicall_allocobj cli_apicalls5[] = { (cli_apicall_allocobj)cli_bcapi_pdf_get_phase, (cli_apicall_allocobj)cli_bcapi_pdf_get_dumpedobjid, (cli_apicall_allocobj)cli_bcapi_running_on_jit, - (cli_apicall_allocobj)cli_bcapi_get_file_reliability + (cli_apicall_allocobj)cli_bcapi_get_file_reliability, + (cli_apicall_allocobj)cli_bcapi_json_is_active }; const cli_apicall_bufget cli_apicalls6[] = { (cli_apicall_bufget)cli_bcapi_buffer_pipe_read_get, @@ -411,6 +430,8 @@ const cli_apicall_ptrbufid cli_apicalls9[] = { (cli_apicall_ptrbufid)cli_bcapi_map_find, (cli_apicall_ptrbufid)cli_bcapi_file_find_limit, (cli_apicall_ptrbufid)cli_bcapi_disable_bytecode_if, - (cli_apicall_ptrbufid)cli_bcapi_disable_jit_if + (cli_apicall_ptrbufid)cli_bcapi_disable_jit_if, + (cli_apicall_ptrbufid)cli_bcapi_json_get_object, + (cli_apicall_ptrbufid)cli_bcapi_json_get_string }; const unsigned cli_apicall_maxapi = sizeof(cli_apicalls)/sizeof(cli_apicalls[0]); diff --git a/libclamav/bytecode_api_impl.h b/libclamav/bytecode_api_impl.h index 40492d12f..5b24e1f97 100644 --- a/libclamav/bytecode_api_impl.h +++ b/libclamav/bytecode_api_impl.h @@ -2,8 +2,8 @@ * ClamAV bytecode internal API * This is an automatically generated file! * - * Copyright (C) 2009-2010 Sourcefire, Inc. - * All rights reserved. + * Copyright (C) 2009-2013 Sourcefire, Inc. + * Copyright (C) 2014 Cisco Systems, Inc. and/or its affiliates. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -50,7 +50,7 @@ int32_t cli_bcapi_file_find(struct cli_bc_ctx *ctx , const uint8_t*, uint32_t); int32_t cli_bcapi_file_byteat(struct cli_bc_ctx *ctx , uint32_t); uint8_t* cli_bcapi_malloc(struct cli_bc_ctx *ctx , uint32_t); uint32_t cli_bcapi_test2(struct cli_bc_ctx *ctx , uint32_t); -int32_t cli_bcapi_get_pe_section(struct cli_bc_ctx *ctx , void*, uint32_t); +int32_t cli_bcapi_get_pe_section(struct cli_bc_ctx *ctx , struct cli_exe_section*, uint32_t); int32_t cli_bcapi_fill_buffer(struct cli_bc_ctx *ctx , uint8_t*, uint32_t, uint32_t, uint32_t, uint32_t); int32_t cli_bcapi_extract_new(struct cli_bc_ctx *ctx , int32_t); int32_t cli_bcapi_read_number(struct cli_bc_ctx *ctx , uint32_t); @@ -122,5 +122,12 @@ int32_t cli_bcapi_pdf_get_dumpedobjid(struct cli_bc_ctx *ctx ); int32_t cli_bcapi_matchicon(struct cli_bc_ctx *ctx , const uint8_t*, int32_t, const uint8_t*, int32_t); int32_t cli_bcapi_running_on_jit(struct cli_bc_ctx *ctx ); int32_t cli_bcapi_get_file_reliability(struct cli_bc_ctx *ctx ); +int32_t cli_bcapi_json_is_active(struct cli_bc_ctx *ctx ); +int32_t cli_bcapi_json_get_object(struct cli_bc_ctx *ctx , const int8_t*, int32_t, int32_t); +int32_t cli_bcapi_json_get_type(struct cli_bc_ctx *ctx , int32_t); +int32_t cli_bcapi_json_get_array_length(struct cli_bc_ctx *ctx , int32_t); +int32_t cli_bcapi_json_get_array_idx(struct cli_bc_ctx *ctx , int32_t, int32_t); +int32_t cli_bcapi_json_get_string_length(struct cli_bc_ctx *ctx , int32_t); +int32_t cli_bcapi_json_get_string(struct cli_bc_ctx *ctx , int8_t*, int32_t, int32_t); #endif