[Pkg-clamav-commits] [SCM] Debian repository for ClamAV branch, debian/unstable, updated. debian/0.95+dfsg-1-6156-g094ec9b
Török Edvin
edwin at clamav.net
Sun Apr 4 00:59:59 UTC 2010
The following commit has been merged in the debian/unstable branch:
commit cf0cd429e9d75947f6e657033386216f2e42dd6b
Author: Török Edvin <edwin at clamav.net>
Date: Thu Aug 20 16:23:43 2009 +0300
Implement API calls from bytecode.
diff --git a/libclamav/Makefile.am b/libclamav/Makefile.am
index c24aa51..2589972 100644
--- a/libclamav/Makefile.am
+++ b/libclamav/Makefile.am
@@ -324,7 +324,10 @@ libclamav_la_SOURCES = \
macho.h \
ishield.c \
ishield.h \
- type_desc.h
+ type_desc.h \
+ bytecode_api.c \
+ bytecode_api_decl.c \
+ bytecode_api.h
if !LINK_TOMMATH
libclamav_la_SOURCES += bignum.c \
diff --git a/libclamav/Makefile.in b/libclamav/Makefile.in
index ce8d659..ac6b0de 100644
--- a/libclamav/Makefile.in
+++ b/libclamav/Makefile.in
@@ -131,7 +131,8 @@ am__libclamav_la_SOURCES_DIST = clamav.h matcher-ac.c matcher-ac.h \
uniq.h version.c version.h mpool.c mpool.h default.h sha256.c \
sha256.h bignum.h bytecode.c bytecode.h bytecode_vm.c \
bytecode_priv.h clambc.h cpio.c cpio.h macho.c macho.h \
- ishield.c ishield.h type_desc.h bignum.c bignum_class.h
+ ishield.c ishield.h type_desc.h bytecode_api.c \
+ bytecode_api_decl.c bytecode_api.h bignum.c bignum_class.h
@LINK_TOMMATH_FALSE at am__objects_1 = libclamav_la-bignum.lo
am_libclamav_la_OBJECTS = libclamav_la-matcher-ac.lo \
libclamav_la-matcher-bm.lo libclamav_la-matcher.lo \
@@ -177,7 +178,9 @@ am_libclamav_la_OBJECTS = libclamav_la-matcher-ac.lo \
libclamav_la-version.lo libclamav_la-mpool.lo \
libclamav_la-sha256.lo libclamav_la-bytecode.lo \
libclamav_la-bytecode_vm.lo libclamav_la-cpio.lo \
- libclamav_la-macho.lo libclamav_la-ishield.lo $(am__objects_1)
+ libclamav_la-macho.lo libclamav_la-ishield.lo \
+ libclamav_la-bytecode_api.lo libclamav_la-bytecode_api_decl.lo \
+ $(am__objects_1)
libclamav_la_OBJECTS = $(am_libclamav_la_OBJECTS)
libclamav_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libclamav_la_CFLAGS) \
@@ -547,7 +550,8 @@ libclamav_la_SOURCES = clamav.h matcher-ac.c matcher-ac.h matcher-bm.c \
uniq.h version.c version.h mpool.c mpool.h default.h sha256.c \
sha256.h bignum.h bytecode.c bytecode.h bytecode_vm.c \
bytecode_priv.h clambc.h cpio.c cpio.h macho.c macho.h \
- ishield.c ishield.h type_desc.h $(am__append_7)
+ ishield.c ishield.h type_desc.h bytecode_api.c \
+ bytecode_api_decl.c bytecode_api.h $(am__append_7)
noinst_LTLIBRARIES = libclamav_internal_utils.la libclamav_internal_utils_nothreads.la
COMMON_CLEANFILES = version.h version.h.tmp *.gcda *.gcno
@MAINTAINER_MODE_TRUE at BUILT_SOURCES = jsparse/generated/operators.h jsparse/generated/keywords.h jsparse-keywords.gperf
@@ -678,6 +682,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libclamav_la-binhex.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libclamav_la-blob.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libclamav_la-bytecode.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libclamav_la-bytecode_api.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libclamav_la-bytecode_api_decl.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libclamav_la-bytecode_vm.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libclamav_la-bzlib.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libclamav_la-cab.Plo at am__quote@
@@ -1417,6 +1423,20 @@ libclamav_la-ishield.lo: ishield.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-ishield.lo `test -f 'ishield.c' || echo '$(srcdir)/'`ishield.c
+libclamav_la-bytecode_api.lo: bytecode_api.c
+ at am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-bytecode_api.lo -MD -MP -MF $(DEPDIR)/libclamav_la-bytecode_api.Tpo -c -o libclamav_la-bytecode_api.lo `test -f 'bytecode_api.c' || echo '$(srcdir)/'`bytecode_api.c
+ at am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libclamav_la-bytecode_api.Tpo $(DEPDIR)/libclamav_la-bytecode_api.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bytecode_api.c' object='libclamav_la-bytecode_api.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-bytecode_api.lo `test -f 'bytecode_api.c' || echo '$(srcdir)/'`bytecode_api.c
+
+libclamav_la-bytecode_api_decl.lo: bytecode_api_decl.c
+ at am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-bytecode_api_decl.lo -MD -MP -MF $(DEPDIR)/libclamav_la-bytecode_api_decl.Tpo -c -o libclamav_la-bytecode_api_decl.lo `test -f 'bytecode_api_decl.c' || echo '$(srcdir)/'`bytecode_api_decl.c
+ at am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libclamav_la-bytecode_api_decl.Tpo $(DEPDIR)/libclamav_la-bytecode_api_decl.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bytecode_api_decl.c' object='libclamav_la-bytecode_api_decl.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-bytecode_api_decl.lo `test -f 'bytecode_api_decl.c' || echo '$(srcdir)/'`bytecode_api_decl.c
+
libclamav_la-bignum.lo: bignum.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-bignum.lo -MD -MP -MF $(DEPDIR)/libclamav_la-bignum.Tpo -c -o libclamav_la-bignum.lo `test -f 'bignum.c' || echo '$(srcdir)/'`bignum.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libclamav_la-bignum.Tpo $(DEPDIR)/libclamav_la-bignum.Plo
diff --git a/libclamav/bytecode.c b/libclamav/bytecode.c
index 838b39b..4a29922 100644
--- a/libclamav/bytecode.c
+++ b/libclamav/bytecode.c
@@ -203,6 +203,18 @@ static inline funcid_t readFuncID(struct cli_bc *bc, unsigned char *p,
return id;
}
+static inline funcid_t readAPIFuncID(struct cli_bc *bc, unsigned char *p,
+ unsigned *off, unsigned len, char *ok)
+{
+ funcid_t id = readNumber(p, off, len, ok)-1;
+ if (*ok && !cli_bitset_test(bc->uses_apis, id)) {
+ cli_errmsg("Called undeclared API function: %u\n", id);
+ *ok = 0;
+ return ~0;
+ }
+ return id;
+}
+
static inline unsigned readFixedNumber(const unsigned char *p, unsigned *off,
unsigned len, char *ok, unsigned width)
{
@@ -291,7 +303,7 @@ static inline unsigned char *readData(const unsigned char *p, unsigned *off, uns
*datalen = l;
return NULL;
}
- newoff = *off + l;
+ newoff = *off + 2*l;
if (newoff > len) {
cli_errmsg("Line ended while reading data\n");
*ok = 0;
@@ -304,14 +316,15 @@ static inline unsigned char *readData(const unsigned char *p, unsigned *off, uns
return NULL;
}
q = dat;
- for (i=*off;i<newoff;i++) {
- const unsigned char v = p[i];
- if (UNLIKELY((v&0xf0) != 0x60)) {
- cli_errmsg("Invalid data part: %c\n", v);
+ for (i=*off;i<newoff;i += 2) {
+ const unsigned char v0 = p[i];
+ const unsigned char v1 = p[i+1];
+ if (UNLIKELY((v0&0xf0) != 0x60 || (v1&0xf0) != 0x60)) {
+ cli_errmsg("Invalid data part: %c%c\n", v0, v1);
*ok = 0;
return 0;
}
- *q++ = v;
+ *q++ = (v0&0xf) | ((v1&0xf) << 4);
}
*off = newoff;
*datalen = l;
@@ -323,6 +336,8 @@ static inline char *readString(const unsigned char *p, unsigned *off, unsigned l
unsigned stringlen;
char *str = (char*)readData(p, off, len, ok, &stringlen);
if (*ok && stringlen && str[stringlen-1] != '\0') {
+ str[stringlen-1] = '\0';
+ cli_errmsg("bytecode: string missing \\0 terminator: %s\n", str);
free(str);
*ok = 0;
return NULL;
@@ -362,6 +377,7 @@ static int parseHeader(struct cli_bc *bc, unsigned char *buffer)
bc->num_types = readNumber(buffer, &offset, len, &ok);
bc->num_func = readNumber(buffer, &offset, len, &ok);
bc->state = bc_loaded;
+ bc->uses_apis = NULL;
if (!ok) {
cli_errmsg("Invalid bytecode header at %u\n", offset);
return CL_EMALFDB;
@@ -444,7 +460,7 @@ static void add_static_types(struct cli_bc *bc)
static int parseTypes(struct cli_bc *bc, unsigned char *buffer)
{
- unsigned i, offset = 1, len = strlen(buffer);
+ unsigned i, offset = 1, len = strlen((const char*)buffer);
char ok=1;
if (buffer[0] != 'T') {
@@ -516,9 +532,104 @@ static int parseTypes(struct cli_bc *bc, unsigned char *buffer)
return CL_SUCCESS;
}
+/* checks whether the type described by tid is the same as the one described by
+ * expectty. */
+static int types_equal(const struct cli_bc *bc, uint16_t *apity2ty, uint16_t tid, uint16_t apitid)
+{
+ unsigned i;
+ const struct cli_bc_type *ty = &bc->types[tid - 63];
+ const struct cli_bc_type *apity = &cli_apicall_types[apitid];
+ /* If we've already verified type equality, return.
+ * Since we need to check equality of recursive types, we assume types are
+ * equal while checking equality of contained types, unless proven
+ * otherwise. */
+ if (apity2ty[apitid] == tid + 1)
+ return 1;
+ apity2ty[apitid] = tid+1;
+
+ if (ty->kind != apity->kind) {
+ cli_dbgmsg("bytecode: type kind mismatch: %u != %u\n", ty->kind, apity->kind);
+ return 0;
+ }
+ if (ty->numElements != apity->numElements) {
+ cli_dbgmsg("bytecode: type numElements mismatch: %u != %u\n", ty->numElements, apity->numElements);
+ return 0;
+ }
+ for (i=0;i<ty->numElements;i++) {
+ if (apity->containedTypes[i] < BC_START_TID) {
+ if (ty->containedTypes[i] != apity->containedTypes[i])
+ return 0;
+ } else if (!types_equal(bc, apity2ty, ty->containedTypes[i], apity->containedTypes[i] - BC_START_TID))
+ return 0;
+ }
+ return 1;
+}
+
static int parseApis(struct cli_bc *bc, unsigned char *buffer)
{
- //TODO
+ unsigned i, offset = 1, len = strlen((const char*)buffer), maxapi, calls;
+ char ok =1;
+ uint16_t *apity2ty;/*map of api type to current bytecode type ID */
+
+ if (buffer[0] != 'E') {
+ cli_errmsg("bytecode: Invalid api header: %c\n", buffer[0]);
+ return CL_EMALFDB;
+ }
+
+ maxapi = readNumber(buffer, &offset, len, &ok);
+ if (!ok)
+ return CL_EMALFDB;
+ if (maxapi > cli_apicall_maxapi) {
+ cli_dbgmsg("bytecode using API %u, but highest API known to libclamav is %u, skipping\n", maxapi, cli_apicall_maxapi);
+ return CL_BREAK;
+ }
+ calls = readNumber(buffer, &offset, len, &ok);
+ if (!ok)
+ return CL_EMALFDB;
+ if (calls > maxapi) {
+ cli_errmsg("bytecode: attempting to describe more APIs than max: %u > %u\n", calls, maxapi);
+ return CL_EMALFDB;
+ }
+ bc->uses_apis = cli_bitset_init();
+ if (!bc->uses_apis) {
+ cli_errmsg("Out of memory allocating apis bitset\n");
+ return CL_EMEM;
+ }
+ apity2ty = cli_calloc(cli_apicall_maxtypes, sizeof(*cli_apicall_types));
+ if (!apity2ty) {
+ cli_errmsg("Out of memory allocating apity2ty\n");
+ return CL_EMEM;
+ }
+ for (i=0;i < calls; i++) {
+ unsigned id = readNumber(buffer, &offset, len, &ok);
+ uint16_t tid = readTypeID(bc, buffer, &offset, len, &ok);
+ char *name = readString(buffer, &offset, len, &ok);
+
+ /* validate APIcall prototype */
+ if (id > maxapi) {
+ cli_errmsg("bytecode: API id %u out of range, max %u\n", id, maxapi);
+ ok = 0;
+ }
+ /* API ids start from 1 */
+ id--;
+ if (ok && name && strcmp(cli_apicalls[id].name, name)) {
+ cli_errmsg("bytecode: API %u name mismatch: %s expected %s\n", id, name, cli_apicalls[id].name);
+ ok = 0;
+ }
+ if (ok && !types_equal(bc, apity2ty, tid, cli_apicalls[id].type)) {
+ cli_errmsg("bytecode: API %u prototype doesn't match\n", id);
+ ok = 0;
+ }
+ /* don't need the name anymore */
+ free(name);
+ if (!ok)
+ return CL_EMALFDB;
+
+ /* APIcall is valid */
+ cli_bitset_set(bc->uses_apis, id);
+ }
+ free(apity2ty); /* free temporary map */
+ cli_dbgmsg("bytecode: Parsed %u APIcalls, maxapi %u\n", calls, maxapi);
return CL_SUCCESS;
}
@@ -672,6 +783,7 @@ static int parseBB(struct cli_bc *bc, unsigned func, unsigned bb, unsigned char
inst.u.branch.br_true = readBBID(bcfunc, buffer, &offset, len, &ok);
inst.u.branch.br_false = readBBID(bcfunc, buffer, &offset, len, &ok);
break;
+ case OP_CALL_API:/* fall-through */
case OP_CALL_DIRECT:
numOp = readFixedNumber(buffer, &offset, len, &ok, 1);
if (ok) {
@@ -682,7 +794,10 @@ static int parseBB(struct cli_bc *bc, unsigned func, unsigned bb, unsigned char
cli_errmsg("Out of memory allocating operands\n");
return CL_EMALFDB;
}
- inst.u.ops.funcid = readFuncID(bc, buffer, &offset, len, &ok);
+ if (inst.opcode == OP_CALL_DIRECT)
+ inst.u.ops.funcid = readFuncID(bc, buffer, &offset, len, &ok);
+ else
+ inst.u.ops.funcid = readAPIFuncID(bc, buffer, &offset, len, &ok);
for (i=0;i<numOp;i++) {
inst.u.ops.ops[i] = readOperand(bcfunc, buffer, &offset, len, &ok);
}
@@ -931,6 +1046,8 @@ void cli_bytecode_destroy(struct cli_bc *bc)
free(f->constants);
}
free(bc->funcs);
+ if (bc->uses_apis)
+ cli_bitset_free(bc->uses_apis);
}
#define MAP(val) do { operand_t o = val; \
@@ -1013,16 +1130,26 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc)
MAP(inst->u.three[1]);
MAP(inst->u.three[2]);
break;
+ case OP_CALL_API:/* fall-through */
case OP_CALL_DIRECT:
{
- struct cli_bc_func *target = &bc->funcs[inst->u.ops.funcid];
- if (inst->u.ops.funcid > bc->num_func) {
- cli_errmsg("bytecode: called function out of range: %u > %u\n", inst->u.ops.funcid, bc->num_func);
- return CL_EBYTECODE;
- }
- if (inst->u.ops.numOps != target->numArgs) {
- cli_errmsg("bytecode: call operands don't match function prototype\n");
- return CL_EBYTECODE;
+ struct cli_bc_func *target = NULL;
+ if (inst->opcode == OP_CALL_DIRECT) {
+ target = &bc->funcs[inst->u.ops.funcid];
+ if (inst->u.ops.funcid > bc->num_func) {
+ cli_errmsg("bytecode: called function out of range: %u > %u\n", inst->u.ops.funcid, bc->num_func);
+ return CL_EBYTECODE;
+ }
+ if (inst->u.ops.numOps != target->numArgs) {
+ cli_errmsg("bytecode: call operands don't match function prototype\n");
+ return CL_EBYTECODE;
+ }
+ } else {
+ /* APIs have 2 parameters always */
+ if (inst->u.ops.numOps != 2) {
+ cli_errmsg("bytecode: call operands don't match function prototype\n");
+ return CL_EBYTECODE;
+ }
}
if (inst->u.ops.numOps) {
inst->u.ops.opsizes = cli_malloc(sizeof(*inst->u.ops.opsizes)*inst->u.ops.numOps);
@@ -1033,7 +1160,10 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc)
}
for (k=0;k<inst->u.ops.numOps;k++) {
MAP(inst->u.ops.ops[k]);
- inst->u.ops.opsizes[k] = typesize(bc, target->types[k]);
+ if (inst->opcode == OP_CALL_DIRECT)
+ inst->u.ops.opsizes[k] = typesize(bc, target->types[k]);
+ else
+ inst->u.ops.opsizes[k] = 32; /*XXX*/
}
break;
}
diff --git a/libclamav/bytecode.h b/libclamav/bytecode.h
index 965145a..1721f98 100644
--- a/libclamav/bytecode.h
+++ b/libclamav/bytecode.h
@@ -24,6 +24,8 @@
#include <stdio.h>
#include "clambc.h"
#include "cltypes.h"
+#include "others.h"
+
struct cli_dbio;
struct cli_bc_ctx;
struct cli_bc_func;
@@ -48,6 +50,7 @@ struct cli_bc {
struct cli_bc_type *types;
enum bc_state state;
uint16_t start_tid;
+ bitset_t *uses_apis;
};
struct cli_bc_ctx *cli_bytecode_context_alloc(void);
diff --git a/clamdscan/client.h b/libclamav/bytecode_api.c
similarity index 67%
copy from clamdscan/client.h
copy to libclamav/bytecode_api.c
index db73f3e..df75295 100644
--- a/clamdscan/client.h
+++ b/libclamav/bytecode_api.c
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2009 Sourcefire, Inc.
+ * ClamAV bytecode internal API
*
- * Authors: Tomasz Kojm, aCaB
+ * Copyright (C) 2009 Sourcefire, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -18,20 +18,16 @@
* MA 02110-1301, USA.
*/
-#ifndef __CLIENT_H
-#define __CLIENT_H
-
-#include "shared/optparser.h"
-
-enum {
- CONT,
- MULTI,
- STREAM,
- FILDES
-};
+#include "cltypes.h"
+#include "type_desc.h"
+#include "bytecode_api.h"
-int client(const struct optstruct *opts, int *infected);
-int get_clamd_version(const struct optstruct *opts);
-int reload_clamd_database(const struct optstruct *opts);
+int32_t cli_bcapi_test0(struct foo* s, uint32_t u)
+{
+ return (s && s->nxt == s && u == 0xdeadbeef) ? 0x12345678 : 0x55;
+}
-#endif
+int32_t cli_bcapi_test1(int32_t a, int32_t b)
+{
+ return (a==0xf00dbeef && b==0xbeeff00d) ? 0x12345678 : 0x55;
+}
diff --git a/libclamav/bytecode_api.h b/libclamav/bytecode_api.h
new file mode 100644
index 0000000..ed7338f
--- /dev/null
+++ b/libclamav/bytecode_api.h
@@ -0,0 +1,6 @@
+struct foo {
+ struct foo *nxt;
+};
+
+int32_t cli_bcapi_test0(struct foo*, uint32_t);
+int32_t cli_bcapi_test1(int32_t, int32_t);
diff --git a/libclamav/bytecode_api_decl.c b/libclamav/bytecode_api_decl.c
new file mode 100644
index 0000000..fe23bbe
--- /dev/null
+++ b/libclamav/bytecode_api_decl.c
@@ -0,0 +1,51 @@
+/*
+ * ClamAV bytecode internal API
+ * This is an automatically generated file!
+ *
+ * Copyright (C) 2009 Sourcefire, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include "cltypes.h"
+#include "type_desc.h"
+#include "bytecode_api.h"
+
+static uint16_t cli_tmp0[]={32, 70, 32};
+static uint16_t cli_tmp1[]={71};
+static uint16_t cli_tmp2[]={70};
+static uint16_t cli_tmp3[]={32, 32, 32};
+
+const struct cli_bc_type cli_apicall_types[]={
+ {FunctionType, cli_tmp0, 3},
+ {PointerType, cli_tmp1, 1},
+ {StructType, cli_tmp2, 1},
+ {FunctionType, cli_tmp3, 3}
+};
+
+const unsigned cli_apicall_maxtypes=sizeof(cli_apicall_types)/sizeof(cli_apicall_types[0]);
+const struct cli_apicall cli_apicalls[]={
+/* Bytecode APIcalls BEGIN */
+ {"cli_bcapi_test0", 0, 0, 1},
+ {"cli_bcapi_test1", 3, 0, 0}
+/* Bytecode APIcalls END */
+};
+const cli_apicall_int2 cli_apicalls0[] = {
+ cli_bcapi_test1
+};
+const cli_apicall_pointer cli_apicalls1[] = {
+ (cli_apicall_pointer)cli_bcapi_test0
+};
+const unsigned cli_apicall_maxapi = sizeof(cli_apicalls)/sizeof(cli_apicalls[0]);
diff --git a/libclamav/bytecode_vm.c b/libclamav/bytecode_vm.c
index caa62dc..672cec2 100644
--- a/libclamav/bytecode_vm.c
+++ b/libclamav/bytecode_vm.c
@@ -26,6 +26,7 @@
#include "others.h"
#include "bytecode.h"
#include "bytecode_priv.h"
+#include "type_desc.h"
#include "readdb.h"
#include <string.h>
@@ -42,6 +43,8 @@ static int bcfail(const char *msg, long a, long b,
#define CHECK_UNREACHABLE do { cli_dbgmsg("bytecode: unreachable executed!\n"); return CL_EBYTECODE; } while(0)
#define CHECK_FUNCID(funcid) do { if (funcid >= bc->num_func) return \
bcfail("funcid out of bounds!",funcid, bc->num_func,__FILE__,__LINE__); } while(0)
+#define CHECK_APIID(funcid) do { if (funcid >= cli_apicall_maxapi) return \
+ bcfail("APIid out of bounds!",funcid, cli_apicall_maxapi,__FILE__,__LINE__); } while(0)
#define CHECK_EQ(a, b) do { if ((a) != (b)) return \
bcfail("Values "#a" and "#b" don't match!",(a),(b),__FILE__,__LINE__); } while(0)
#define CHECK_GT(a, b) do {if ((a) <= (b)) return \
@@ -55,6 +58,7 @@ static int bcfail(const char *msg, long a, long b,
#define TRACE_EXEC(id, dest, ty, stack)
#define CHECK_UNREACHABLE return CL_EBYTECODE
#define CHECK_FUNCID(x);
+#define CHECK_APIID(x);
#define CHECK_EQ(a,b)
#define CHECK_GT(a,b)
#endif
@@ -553,6 +557,34 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
break;
}
+ DEFINE_OP(OP_CALL_API) {
+ const struct cli_apicall *api = &cli_apicalls[inst->u.ops.funcid];
+ int32_t res;
+ CHECK_APIID(inst->u.ops.funcid);
+ TRACE_EXEC(-inst->u.ops.funcid, inst->dest, inst->type, stack_depth);
+ switch (api->kind) {
+ case 0: {
+ int32_t a, b, r;
+ READ32(a, inst->u.ops.ops[0]);
+ READ32(b, inst->u.ops.ops[1]);
+ res = cli_apicalls0[api->idx](a, b);
+ break;
+ }
+ case 1: {
+ cli_errmsg("bytecode: type 1 apicalls not yet implemented!\n");
+ stop = CL_EBYTECODE;
+ /* void *p;
+ uint32_t u;
+ p = ...;
+ u = READ32(v, inst->u.ops.ops[1]);
+ res = cli_apicalls1[api->idx](p, u);
+ break;*/
+ }
+ }
+ WRITE32(inst->dest, res);
+ break;
+ }
+
DEFINE_OP(OP_CALL_DIRECT)
CHECK_FUNCID(inst->u.ops.funcid);
func2 = &bc->funcs[inst->u.ops.funcid];
diff --git a/libclamav/type_desc.h b/libclamav/type_desc.h
index 966644f..c90451b 100644
--- a/libclamav/type_desc.h
+++ b/libclamav/type_desc.h
@@ -1,3 +1,27 @@
+/*
+ * ClamAV bytecode internal API
+ *
+ * Copyright (C) 2009 Sourcefire, Inc.
+ *
+ * Authors: Török Edvin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+#ifndef TYPE_DESC_H
+#define TYPE_DESC_H
+
enum derived_t {
FunctionType,
PointerType,
@@ -17,13 +41,16 @@ typedef int32_t (*cli_apicall_pointer)(void*, uint32_t);
struct cli_apicall {
const char *name;
- const struct cli_bc_type *type;
+ uint16_t type;/* type id in cli_apicall_types array */
+ uint16_t idx;
uint8_t kind;
};
extern const struct cli_bc_type cli_apicall_types[];
+extern const unsigned cli_apicall_maxtypes;
extern const struct cli_apicall cli_apicalls[];
extern const cli_apicall_int2 cli_apicalls0[];
extern const cli_apicall_pointer cli_apicalls1[];
extern const unsigned cli_apicall_maxapi;
+#endif
diff --git a/unit_tests/check_bytecode.c b/unit_tests/check_bytecode.c
index c80165a..9fc0eee 100644
--- a/unit_tests/check_bytecode.c
+++ b/unit_tests/check_bytecode.c
@@ -81,6 +81,14 @@ START_TEST (test_arith)
runtest("input/arith.cbc", 0xd5555555);
}
END_TEST
+
+START_TEST (test_apicalls)
+{
+ runtest("input/apicalls.cbc", 0xf00d);
+}
+END_TEST
+
+
Suite *test_bytecode_suite(void)
{
Suite *s = suite_create("bytecode");
@@ -89,5 +97,6 @@ Suite *test_bytecode_suite(void)
tcase_add_test(tc_cli_arith, test_retmagic);
tcase_add_test(tc_cli_arith, test_arith);
+ tcase_add_test(tc_cli_arith, test_apicalls);
return s;
}
diff --git a/unit_tests/input/apicalls.cbc b/unit_tests/input/apicalls.cbc
new file mode 100644
index 0000000..ace9167
--- /dev/null
+++ b/unit_tests/input/apicalls.cbc
@@ -0,0 +1,15 @@
+ClamBCaa`|`````|`agafp`clamcoincidencejb
+Tedebfdacb`bb`bb`b
+Eabaaabbed|b`acflfifoebfcfaf`gifoedgefcgdgac``
+A`Lacb`baab`bFadaa
+Bb`b``bbabHonnkm``odHm``oonnkdaaaadab`b`Hhgfedcbadb`babnaaaDm``odDmjnmdTcab`babE
+AaLabahaab`bFacaa
+Baaaadaah`Bgaab`babnaaaDm``odDmjnmdTcab`babE
+AaLabb`aaab`bFacaa
+Baaaadab`a`Dhbgabb`babnaaaDm``odDmjnmdTcab`babE
+AaLabb`baab`bFacaa
+Baaaadab`b`Fichbgadb`babnaaaDm``odDmjnmdTcab`babE
+AaLabb`daab`bFacaa
+Baaaadab`d`Ncgbfae`dichbgahb`babnaaaDm``odDmjnmdTcab`babE
+AbLadahb`aaaaaaab`bFaeaa
+Baaabdaah`Bhbaaaacdab`aaaDdcbabaaadk`acabb`baenaadDm``odDmjnmdTcab`baeE
--
Debian repository for ClamAV
More information about the Pkg-clamav-commits
mailing list