Support for bytecode lines >8k.

Size is specified on first line (which must be <8k).
0.96
Török Edvin 16 years ago
parent 4a3c659b54
commit 482e97dbb2
  1. 72
      libclamav/bytecode.c
  2. 3
      libclamav/c++/bytecode2llvm.cpp
  3. 2
      libclamav/clambc.h
  4. 2
      unit_tests/input/apicalls.cbc
  5. 2
      unit_tests/input/apicalls2.cbc
  6. 2
      unit_tests/input/arith.cbc
  7. 2
      unit_tests/input/div0.cbc
  8. 2
      unit_tests/input/lsig.cbc
  9. 2
      unit_tests/input/retmagic.cbc

@ -403,12 +403,13 @@ static inline char *readString(const unsigned char *p, unsigned *off, unsigned l
return str;
}
static int parseHeader(struct cli_bc *bc, unsigned char *buffer)
static int parseHeader(struct cli_bc *bc, unsigned char *buffer, unsigned *linelength)
{
uint64_t magic1;
unsigned magic2;
char ok = 1;
unsigned offset, len, flevel;
char *pos;
if (strncmp((const char*)buffer, BC_HEADER, sizeof(BC_HEADER)-1)) {
cli_errmsg("Missing file magic in bytecode");
return CL_EMALFDB;
@ -420,7 +421,7 @@ static int parseHeader(struct cli_bc *bc, unsigned char *buffer)
cli_errmsg("Unable to parse functionality level in bytecode header\n");
return CL_EMALFDB;
}
if (flevel > BC_FUNC_LEVEL) {
if (flevel != BC_FUNC_LEVEL) {
cli_dbgmsg("Skipping bytecode with functionality level: %u\n", flevel);
return CL_BREAK;
}
@ -451,9 +452,14 @@ static int parseHeader(struct cli_bc *bc, unsigned char *buffer)
cli_errmsg("Magic numbers don't match: %lx%lx, %u\n", m0, m1, magic2);
return CL_EMALFDB;
}
if (offset != len) {
cli_errmsg("Trailing garbage in bytecode header: %d extra bytes\n",
len-offset);
if (buffer[offset] != ':') {
cli_errmsg("Expected : but found: %c\n", buffer[offset]);
return CL_EMALFDB;
}
offset++;
*linelength = strtol(buffer+offset, &pos, 10);
if (*pos != '\n') {
cli_errmsg("Invalid number: %s\n", buffer+offset);
return CL_EMALFDB;
}
@ -1169,8 +1175,7 @@ static int parseBB(struct cli_bc *bc, unsigned func, unsigned bb, unsigned char
}
enum parse_state {
PARSE_BC_HEADER=0,
PARSE_BC_TYPES,
PARSE_BC_TYPES=0,
PARSE_BC_APIS,
PARSE_BC_GLOBALS,
PARSE_BC_LSIG,
@ -1182,38 +1187,49 @@ enum parse_state {
int cli_bytecode_load(struct cli_bc *bc, FILE *f, struct cli_dbio *dbio)
{
unsigned row = 0, current_func = 0, bb=0;
char buffer[FILEBUFF];
enum parse_state state = PARSE_BC_HEADER;
char *buffer;
unsigned linelength=0;
char firstbuf[FILEBUFF];
enum parse_state state;
int rc;
if (!f && !dbio) {
cli_errmsg("Unable to load bytecode (null file)\n");
return CL_ENULLARG;
}
while (cli_dbgets(buffer, FILEBUFF, f, dbio)) {
int rc;
if (!cli_dbgets(firstbuf, FILEBUFF, f, dbio)) {
cli_errmsg("Unable to load bytecode (empty file)\n");
return CL_EMALFDB;
}
rc = parseHeader(bc, (unsigned char*)firstbuf, &linelength);
if (rc == CL_BREAK) {
bc->state = bc_skip;
return CL_SUCCESS;
}
if (rc != CL_SUCCESS) {
cli_errmsg("Error at bytecode line %u\n", row);
return rc;
}
buffer = cli_malloc(linelength);
if (!buffer) {
cli_errmsg("Out of memory allocating line of length %u\n", linelength);
return CL_EMEM;
}
state = PARSE_BC_LSIG;
while (cli_dbgets(buffer, linelength, f, dbio)) {
cli_chomp(buffer);
row++;
switch (state) {
case PARSE_BC_HEADER:
rc = parseHeader(bc, (unsigned char*)buffer);
if (rc == CL_BREAK) /* skip */ {
bc->state = bc_skip;
return CL_SUCCESS;
}
if (rc != CL_SUCCESS) {
cli_errmsg("Error at bytecode line %u\n", row);
return rc;
}
state = PARSE_BC_LSIG;
break;
case PARSE_BC_LSIG:
rc = parseLSig(bc, (unsigned char*)buffer);
if (rc == CL_BREAK) /* skip */ {
bc->state = bc_skip;
free(buffer);
return CL_SUCCESS;
}
if (rc != CL_SUCCESS) {
cli_errmsg("Error at bytecode line %u\n", row);
free(buffer);
return rc;
}
state = PARSE_BC_TYPES;
@ -1222,6 +1238,7 @@ int cli_bytecode_load(struct cli_bc *bc, FILE *f, struct cli_dbio *dbio)
rc = parseTypes(bc, (unsigned char*)buffer);
if (rc != CL_SUCCESS) {
cli_errmsg("Error at bytecode line %u\n", row);
free(buffer);
return rc;
}
state = PARSE_BC_APIS;
@ -1230,10 +1247,12 @@ int cli_bytecode_load(struct cli_bc *bc, FILE *f, struct cli_dbio *dbio)
rc = parseApis(bc, (unsigned char*)buffer);
if (rc == CL_BREAK) /* skip */ {
bc->state = bc_skip;
free(buffer);
return CL_SUCCESS;
}
if (rc != CL_SUCCESS) {
cli_errmsg("Error at bytecode line %u\n", row);
free(buffer);
return rc;
}
state = PARSE_BC_GLOBALS;
@ -1242,10 +1261,12 @@ int cli_bytecode_load(struct cli_bc *bc, FILE *f, struct cli_dbio *dbio)
rc = parseGlobals(bc, (unsigned char*)buffer);
if (rc == CL_BREAK) /* skip */ {
bc->state = bc_skip;
free(buffer);
return CL_SUCCESS;
}
if (rc != CL_SUCCESS) {
cli_errmsg("Error at bytecode line %u\n", row);
free(buffer);
return rc;
}
state = PARSE_MD_OPT_HEADER;
@ -1255,6 +1276,7 @@ int cli_bytecode_load(struct cli_bc *bc, FILE *f, struct cli_dbio *dbio)
rc = parseMD(bc, (unsigned char*)buffer);
if (rc != CL_SUCCESS) {
cli_errmsg("Error at bytecode line %u\n", row);
free(buffer);
return rc;
}
break;
@ -1264,6 +1286,7 @@ int cli_bytecode_load(struct cli_bc *bc, FILE *f, struct cli_dbio *dbio)
rc = parseFunctionHeader(bc, current_func, (unsigned char*)buffer);
if (rc != CL_SUCCESS) {
cli_errmsg("Error at bytecode line %u\n", row);
free(buffer);
return rc;
}
bb = 0;
@ -1273,12 +1296,14 @@ int cli_bytecode_load(struct cli_bc *bc, FILE *f, struct cli_dbio *dbio)
rc = parseBB(bc, current_func, bb++, (unsigned char*)buffer);
if (rc != CL_SUCCESS) {
cli_errmsg("Error at bytecode line %u\n", row);
free(buffer);
return rc;
}
if (bb >= bc->funcs[current_func].numBB) {
if (bc->funcs[current_func].insn_idx != bc->funcs[current_func].numInsts) {
cli_errmsg("Parsed different number of instructions than declared: %u != %u\n",
bc->funcs[current_func].insn_idx, bc->funcs[current_func].numInsts);
free(buffer);
return CL_EMALFDB;
}
cli_dbgmsg("Parsed %u BBs, %u instructions\n",
@ -1289,6 +1314,7 @@ int cli_bytecode_load(struct cli_bc *bc, FILE *f, struct cli_dbio *dbio)
break;
}
}
free(buffer);
cli_dbgmsg("Parsed %d functions\n", current_func);
if (current_func != bc->num_func) {
cli_errmsg("Loaded less functions than declared: %u vs. %u\n",

@ -1187,7 +1187,10 @@ int bytecode_init(void)
#ifdef CL_DEBUG
llvm::JITEmitDebugInfo = true;
#else
llvm::JITEmitDebugInfo = false;
#endif
llvm::DwarfExceptionHandling = false;
llvm_start_multithreaded();
// If we have a native target, initialize it to ensure it is linked in and

@ -28,7 +28,7 @@ struct bytecode_metadata {
char *targetExclude;
};
#define BC_FUNC_LEVEL 1
#define BC_FUNC_LEVEL 2
#define BC_HEADER "ClamBC"
enum bc_opcode {

@ -1,4 +1,4 @@
ClamBCaa`|``````|`agafp`clamcoincidencejb
ClamBCab`|``````|`agafp`clamcoincidencejb:82
Tedaaa`aacb`bb`bb`b
Eabaaabbfd|afdgefcgdgac``

@ -1,4 +1,4 @@
ClamBCaa`|``````|`akafp`clamcoincidencejb
ClamBCab`|``````|`akafp`clamcoincidencejb:82
Tedcaabjdebjdaaa`aacb`bbjdb`baacb`bb`bb`bebed
Eababaabhd|afdgefcgdg`c``abbid|afdgefcgdgac``

@ -1,4 +1,4 @@
ClamBCaa`|``````|`afbbep`clamcoincidencejb
ClamBCab`|``````|`afbbep`clamcoincidencejb:418
Tedaaa`
E``

@ -1,4 +1,4 @@
ClamBCaa`|``````|`afabp`clamcoincidencejb
ClamBCab`|``````|`afabp`clamcoincidencejb:23
Tedaaa`
E``

@ -1,4 +1,4 @@
ClamBCaa`|``c``a```|`bjaabp`clamcoincidencejb
ClamBCab`|``c``a```|`bjaabp`clamcoincidencejb:326
Trojan.Foo.{A,B};Target:1;(((0|1|2)=42,2)|(3=10));EP+0:aabb;ffff;aaccee;f00d;dead
Tedebieebheebgeebfeebeeebdeebbeebaeebadebcdaaa`aacb`bbadb`bdb`db`bcajbadbcebadbcebadbcebadbcebadbcecaab`bdagahdaeahdajahdabbaddabahdakah
Eafaaafb`e|amcgefdgfgifbgegcgnfafmfef``

@ -1,4 +1,4 @@
ClamBCaa`|``````|`afaap`clamcoincidencejb
ClamBCab`|``````|`afaap`clamcoincidencejb:20
Tedaaa`
E``

Loading…
Cancel
Save