diff --git a/libclamav/bytecode.c b/libclamav/bytecode.c index de3bb0750..370bcefdd 100644 --- a/libclamav/bytecode.c +++ b/libclamav/bytecode.c @@ -1116,6 +1116,7 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc) case OP_ICMP_SLT: case OP_ICMP_SLE: case OP_COPY: + case OP_STORE: MAP(inst->u.binop[0]); MAP(inst->u.binop[1]); break; @@ -1175,6 +1176,9 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc) } break; } + case OP_LOAD: + MAP(inst->u.unaryop); + break; default: cli_dbgmsg("Unhandled opcode: %d\n", inst->opcode); return CL_EBYTECODE; diff --git a/libclamav/bytecode_vm.c b/libclamav/bytecode_vm.c index 672cec228..49cd56465 100644 --- a/libclamav/bytecode_vm.c +++ b/libclamav/bytecode_vm.c @@ -251,6 +251,10 @@ static always_inline struct stack_entry *pop_stack(struct stack *stack, CHECK_EQ((p)&7, 0);\ TRACE_W(x, p, 64);\ *(uint64_t*)&values[p] = x +#define WRITEP(x, p) CHECK_GT(func->numBytes, p+PSIZE-1);\ + CHECK_EQ((p)&(PSIZE-1), 0);\ + TRACE_W(x, p, PSIZE*8);\ + *(void**)&values[p] = x #define READ1(x, p) CHECK_GT(func->numBytes, p);\ x = (*(uint8_t*)&values[p])&1;\ @@ -270,6 +274,11 @@ static always_inline struct stack_entry *pop_stack(struct stack *stack, CHECK_EQ((p)&7, 0);\ x = *(uint64_t*)&values[p];\ TRACE_R(x) +#define PSIZE sizeof(void*) +#define READP(x, p) CHECK_GT(func->numBytes, p+PSIZE-1);\ + CHECK_EQ((p)&(PSIZE-1), 0);\ + x = *(void**)&values[p];\ + TRACE_R(x) #define READOLD8(x, p) CHECK_GT(func->numBytes, p);\ x = *(uint8_t*)&old_values[p];\ @@ -680,6 +689,82 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct break; } + case OP_LOAD*5: + case OP_LOAD*5+1: + { + uint8_t *ptr; + READP(ptr, inst->u.unaryop); + WRITE8(inst->dest, (*ptr)); + break; + } + case OP_LOAD*5+2: + { + const union unaligned_16 *ptr; + READP(ptr, inst->u.unaryop); + WRITE16(inst->dest, (ptr->una_u16)); + break; + } + case OP_LOAD*5+3: + { + const union unaligned_32 *ptr; + READP(ptr, inst->u.unaryop); + WRITE32(inst->dest, (ptr->una_u32)); + break; + } + case OP_LOAD*5+4: + { + const union unaligned_64 *ptr; + READP(ptr, inst->u.unaryop); + WRITE64(inst->dest, (ptr->una_u64)); + break; + } + + case OP_STORE*5: + { + uint8_t *ptr; + uint8_t v; + READP(ptr, BINOP(0)); + READ1(v, BINOP(1)); + *ptr = v; + break; + } + case OP_STORE*5+1: + { + uint8_t *ptr; + uint8_t v; + READP(ptr, BINOP(0)); + READ8(v, BINOP(1)); + *ptr = v; + break; + } + case OP_STORE*5+2: + { + union unaligned_16 *ptr; + uint16_t v; + READP(ptr, BINOP(0)); + READ16(v, BINOP(1)); + ptr->una_s16 = v; + break; + } + case OP_STORE*5+3: + { + union unaligned_32 *ptr; + uint32_t v; + READP(ptr, BINOP(0)); + READ32(v, BINOP(1)); + ptr->una_u32 = v; + break; + } + case OP_STORE*5+4: + { + union unaligned_64 *ptr; + uint64_t v; + READP(ptr, BINOP(0)); + READ64(v, BINOP(1)); + ptr->una_u64 = v; + break; + } + default: cli_errmsg("Opcode %u of type %u is not implemented yet!\n", inst->interp_op/5, inst->interp_op%5); diff --git a/libclamav/others.h b/libclamav/others.h index 592f138d3..1b3e91c5d 100644 --- a/libclamav/others.h +++ b/libclamav/others.h @@ -229,6 +229,20 @@ extern int have_rar; (((v) & 0xff00000000000000ULL) >> 56)) +union unaligned_64 { + uint64_t una_u64; + int64_t una_s64; +} __attribute__((packed)); + +union unaligned_32 { + uint32_t una_u32; + int32_t una_s32; +} __attribute__((packed)); + +union unaligned_16 { + uint16_t una_u16; + int16_t una_s16; +} __attribute__((packed)); #if WORDS_BIGENDIAN == 0 #ifndef HAVE_ATTRIB_PACKED @@ -241,14 +255,6 @@ extern int have_rar; #pragma pack 1 #endif -union unaligned_32 { - uint32_t una_u32; - int32_t una_s32; -} __attribute__((packed)); - -union unaligned_16 { - int16_t una_s16; -} __attribute__((packed)); #ifdef HAVE_PRAGMA_PACK #pragma pack()