[Forensics-changes] [yara] 294/407: Fix issue with undefined floating points values
Hilko Bengen
bengen at moszumanska.debian.org
Sat Jul 1 10:28:38 UTC 2017
This is an automated email from the git hooks/post-receive script.
bengen pushed a commit to annotated tag v3.3.0
in repository yara.
commit bb6bb84942869a26f61a74a3585c14e1cc19be9f
Author: Victor M. Alvarez <plusvic at gmail.com>
Date: Fri Jan 2 19:40:38 2015 +0100
Fix issue with undefined floating points values
---
configure.ac | 1 +
libyara/exec.c | 555 ++++++++++++++++++++++++-----------------
libyara/include/yara/modules.h | 43 +++-
libyara/object.c | 5 +-
4 files changed, 369 insertions(+), 235 deletions(-)
diff --git a/configure.ac b/configure.ac
index 0eec762..b427263 100644
--- a/configure.ac
+++ b/configure.ac
@@ -82,6 +82,7 @@ ACX_PTHREAD(
CC="$PTHREAD_CC"],
[AC_MSG_ERROR([pthread API support is required.])])
+AC_CHECK_LIB(m, isnan)
AC_CHECK_LIB(m, log2)
AC_CHECK_FUNCS([strlcpy strlcat memmem timegm])
diff --git a/libyara/exec.c b/libyara/exec.c
index f160b97..2a00ed2 100644
--- a/libyara/exec.c
+++ b/libyara/exec.c
@@ -19,6 +19,7 @@ limitations under the License.
#include <string.h>
#include <assert.h>
#include <time.h>
+#include <math.h>
#include <yara/exec.h>
#include <yara/limits.h>
@@ -42,45 +43,20 @@ union STACK_ITEM {
#define push(x) \
do { \
- if (sp < STACK_SIZE) stack[sp++].i = (x); \
+ if (sp < STACK_SIZE) stack[sp++] = (x); \
else return ERROR_EXEC_STACK_OVERFLOW; \
} while(0)
-#define push_dbl(x) \
- do { \
- if (sp < STACK_SIZE) stack[sp++].d = (x); \
- else return ERROR_EXEC_STACK_OVERFLOW; \
- } while(0)
-
-#define pop(x) x = stack[--sp].i
-#define pop_dbl(x) x = stack[--sp].d
-
-// The _rel() variants are used to push or pop at specific offsets from sp.
-// This is useful when you need have a stack with an integer that needs to be
-// converted to a double at stack[0] and a double at stack[1]. In this case
-// sp would be 2, so you can do:
-//
-// pop_rel(2, r1)
-// push_dbl_rel(2, r1)
-
-#define push_dbl_rel(offset, x) \
- do { \
- if (offset <= 0 || sp - offset < 0) return ERROR_EXEC_STACK_OVERFLOW; \
- else stack[sp - offset].d = (x); \
- } while(0)
+#define pop(x) x = stack[--sp]
-#define pop_rel(offset, x) \
- do { \
- if (offset < 0 || sp - offset < 0) return ERROR_EXEC_STACK_OVERFLOW; \
- else x = stack[sp - offset].i; \
- } while(0)
+#define is_undef(x) IS_UNDEFINED((x).i)
-
-#define break_if_undefined(x) \
- if (IS_UNDEFINED(x)) \
+#define break_if_undef(x) \
+ if (is_undef(x)) \
{ \
- push(UNDEFINED); \
+ r1.i = UNDEFINED; \
+ push(r1); \
break; \
}
@@ -148,17 +124,15 @@ int yr_execute_code(
int timeout,
time_t start_time)
{
- int64_t r1;
- int64_t r2;
- int64_t r3;
- double dr1;
- double dr2;
int64_t mem[MEM_SIZE];
int64_t args[MAX_FUNCTION_ARGS];
int32_t sp = 0;
uint8_t* ip = rules->code_start;
union STACK_ITEM stack[STACK_SIZE];
+ union STACK_ITEM r1;
+ union STACK_ITEM r2;
+ union STACK_ITEM r3;
YR_RULE* rule;
YR_STRING* string;
@@ -194,7 +168,7 @@ int yr_execute_code(
return ERROR_SUCCESS;
case OP_PUSH:
- r1 = *(uint64_t*)(ip + 1);
+ r1.i = *(uint64_t*)(ip + 1);
ip += sizeof(uint64_t);
push(r1);
break;
@@ -204,52 +178,58 @@ int yr_execute_code(
break;
case OP_CLEAR_M:
- r1 = *(uint64_t*)(ip + 1);
+ r1.i = *(uint64_t*)(ip + 1);
ip += sizeof(uint64_t);
- mem[r1] = 0;
+ mem[r1.i] = 0;
break;
case OP_ADD_M:
- r1 = *(uint64_t*)(ip + 1);
+ r1.i = *(uint64_t*)(ip + 1);
ip += sizeof(uint64_t);
pop(r2);
- if (!IS_UNDEFINED(r2))
- mem[r1] += r2;
+ if (!is_undef(r2))
+ mem[r1.i] += r2.i;
break;
case OP_INCR_M:
- r1 = *(uint64_t*)(ip + 1);
+ r1.i = *(uint64_t*)(ip + 1);
ip += sizeof(uint64_t);
- mem[r1]++;
+ mem[r1.i]++;
break;
case OP_PUSH_M:
- r1 = *(uint64_t*)(ip + 1);
+ r1.i = *(uint64_t*)(ip + 1);
ip += sizeof(uint64_t);
- push(mem[r1]);
+ r1.i = mem[r1.i];
+ push(r1);
break;
case OP_POP_M:
- r1 = *(uint64_t*)(ip + 1);
+ r1.i = *(uint64_t*)(ip + 1);
ip += sizeof(uint64_t);
- pop(mem[r1]);
+ pop(r2);
+ mem[r1.i] = r2.i;
break;
case OP_SWAPUNDEF:
- r1 = *(uint64_t*)(ip + 1);
+ r1.i = *(uint64_t*)(ip + 1);
ip += sizeof(uint64_t);
pop(r2);
- if (IS_UNDEFINED(r2))
- push(mem[r1]);
+ if (is_undef(r2))
+ {
+ r1.i = mem[r1.i];
+ push(r1);
+ }
else
+ {
push(r2);
+ }
break;
case OP_JNUNDEF:
pop(r1);
push(r1);
-
- if (!IS_UNDEFINED(r1))
+ if (!is_undef(r1))
{
ip = *(uint8_t**)(ip + 1);
// ip will be incremented at the end of the loop,
@@ -268,7 +248,7 @@ int yr_execute_code(
push(r1);
push(r2);
- if (r1 <= r2)
+ if (r1.i <= r2.i)
{
ip = *(uint8_t**)(ip + 1);
// ip will be incremented at the end of the loop,
@@ -284,76 +264,105 @@ int yr_execute_code(
case OP_AND:
pop(r2);
pop(r1);
- if (IS_UNDEFINED(r1) || IS_UNDEFINED(r2))
- push(0);
+
+ if (is_undef(r1) || is_undef(r2))
+ r1.i = 0;
else
- push(r1 && r2);
+ r1.i = r1.i && r2.i;
+
+ push(r1);
break;
case OP_OR:
pop(r2);
pop(r1);
- if (IS_UNDEFINED(r1))
+
+ if (is_undef(r1))
+ {
push(r2);
- else if (IS_UNDEFINED(r2))
+ }
+ else if (is_undef(r2))
+ {
push(r1);
+ }
else
- push(r1 || r2);
+ {
+ r1.i = r1.i || r2.i;
+ push(r1);
+ }
break;
case OP_NOT:
pop(r1);
- if (IS_UNDEFINED(r1))
- push(UNDEFINED);
+
+ if (is_undef(r1))
+ r1.i = UNDEFINED;
else
- push(!r1);
+ r1.i= !r1.i;
+
+ push(r1);
break;
case OP_MOD:
pop(r2);
pop(r1);
- push(OPERATION(%, r1, r2));
+ break_if_undef(r2);
+ break_if_undef(r1);
+ r1.i = r1.i % r2.i;
+ push(r1);
break;
case OP_SHR:
pop(r2);
pop(r1);
- push(OPERATION(>>, r1, r2));
+ break_if_undef(r2);
+ break_if_undef(r1);
+ r1.i = r1.i >> r2.i;
+ push(r1);
break;
case OP_SHL:
pop(r2);
pop(r1);
- push(OPERATION(<<, r1, r2));
+ break_if_undef(r2);
+ break_if_undef(r1);
+ r1.i = r1.i << r2.i;
+ push(r1);
break;
case OP_BITWISE_NOT:
pop(r1);
- push(IS_UNDEFINED(r1) ? UNDEFINED : ~r1);
+ break_if_undef(r1);
+ r1.i = ~r1.i;
+ push(r1);
break;
case OP_BITWISE_AND:
pop(r2);
pop(r1);
- push(OPERATION(&, r1, r2));
+ r1.i = r1.i & r2.i;
+ push(r1);
break;
case OP_BITWISE_OR:
pop(r2);
pop(r1);
- push(OPERATION(|, r1, r2));
+ r1.i = r1.i | r2.i;
+ push(r1);
break;
case OP_BITWISE_XOR:
pop(r2);
pop(r1);
- push(OPERATION(^, r1, r2));
+ r1.i = r1.i ^ r2.i;
+ push(r1);
break;
case OP_PUSH_RULE:
rule = *(YR_RULE**)(ip + 1);
ip += sizeof(uint64_t);
- push(rule->t_flags[tidx] & RULE_TFLAGS_MATCH ? 1 : 0);
+ r1.i = rule->t_flags[tidx] & RULE_TFLAGS_MATCH ? 1 : 0;
+ push(r1);
break;
case OP_MATCH_RULE:
@@ -361,7 +370,7 @@ int yr_execute_code(
rule = *(YR_RULE**)(ip + 1);
ip += sizeof(uint64_t);
- if (!IS_UNDEFINED(r1) && r1)
+ if (!is_undef(r1) && r1.i)
rule->t_flags[tidx] |= RULE_TFLAGS_MATCH;
#ifdef PROFILING_ENABLED
@@ -380,7 +389,8 @@ int yr_execute_code(
NULL);
assert(object != NULL);
- push(PTR_TO_UINT64(object));
+ r1.i = PTR_TO_UINT64(object);
+ push(r1);
break;
case OP_OBJ_FIELD:
@@ -388,79 +398,85 @@ int yr_execute_code(
ip += sizeof(uint64_t);
pop(r1);
- break_if_undefined(r1);
+ break_if_undef(r1);
- object = UINT64_TO_PTR(YR_OBJECT*, r1);
+ object = UINT64_TO_PTR(YR_OBJECT*, r1.i);
object = yr_object_lookup_field(object, identifier);
assert(object != NULL);
- push(PTR_TO_UINT64(object));
-
+ r1.i = PTR_TO_UINT64(object);
+ push(r1);
break;
case OP_OBJ_VALUE:
pop(r1);
- break_if_undefined(r1);
+ break_if_undef(r1);
- object = UINT64_TO_PTR(YR_OBJECT*, r1);
+ object = UINT64_TO_PTR(YR_OBJECT*, r1.i);
switch(object->type)
{
case OBJECT_TYPE_INTEGER:
- push(((YR_OBJECT_INTEGER*) object)->value);
+ r1.i = ((YR_OBJECT_INTEGER*) object)->value;
break;
case OBJECT_TYPE_DOUBLE:
- push_dbl(((YR_OBJECT_DOUBLE*) object)->value);
+ if (isnan(((YR_OBJECT_DOUBLE*) object)->value))
+ r1.i = UNDEFINED;
+ else
+ r1.d = ((YR_OBJECT_DOUBLE*) object)->value;
break;
case OBJECT_TYPE_STRING:
- if (((YR_OBJECT_STRING*) object)->value != NULL)
- push(PTR_TO_UINT64(((YR_OBJECT_STRING*) object)->value));
+ if (((YR_OBJECT_STRING*) object)->value == NULL)
+ r1.i = UNDEFINED;
else
- push(UNDEFINED);
+ r1.i = PTR_TO_UINT64(((YR_OBJECT_STRING*) object)->value);
break;
default:
assert(FALSE);
}
+ push(r1);
break;
case OP_INDEX_ARRAY:
pop(r1); // index
pop(r2); // array
- break_if_undefined(r1);
+ break_if_undef(r1);
- object = UINT64_TO_PTR(YR_OBJECT*, r2);
+ object = UINT64_TO_PTR(YR_OBJECT*, r2.i);
assert(object->type == OBJECT_TYPE_ARRAY);
- object = yr_object_array_get_item(object, 0, r1);
+ object = yr_object_array_get_item(object, 0, r1.i);
if (object != NULL)
- push(PTR_TO_UINT64(object));
+ r1.i = PTR_TO_UINT64(object);
else
- push(UNDEFINED);
+ r1.i = UNDEFINED;
+ push(r1);
break;
case OP_LOOKUP_DICT:
pop(r1); // key
pop(r2); // dictionary
- break_if_undefined(r1);
+ break_if_undef(r1);
- object = UINT64_TO_PTR(YR_OBJECT*, r2);
+ object = UINT64_TO_PTR(YR_OBJECT*, r2.i);
assert(object->type == OBJECT_TYPE_DICTIONARY);
object = yr_object_dict_get_item(
- object, 0, UINT64_TO_PTR(SIZED_STRING*, r1)->c_string);
+ object, 0, UINT64_TO_PTR(SIZED_STRING*, r1.i)->c_string);
if (object != NULL)
- push(PTR_TO_UINT64(object));
+ r1.i = PTR_TO_UINT64(object);
else
- push(UNDEFINED);
+ r1.i = UNDEFINED;
+ push(r1);
break;
case OP_CALL:
@@ -473,14 +489,15 @@ int yr_execute_code(
while (i > 0)
{
- pop(args[i - 1]);
+ pop(r1);
+ args[i - 1] = r1.i;
i--;
}
pop(r2);
- break_if_undefined(r2);
+ break_if_undef(r2);
- function = UINT64_TO_PTR(YR_OBJECT_FUNCTION*, r2);
+ function = UINT64_TO_PTR(YR_OBJECT_FUNCTION*, r2.i);
result = ERROR_INTERNAL_FATAL_ERROR;
for (i = 0; i < MAX_OVERLOADED_FUNCTIONS; i++)
@@ -502,50 +519,54 @@ int yr_execute_code(
assert(i < MAX_OVERLOADED_FUNCTIONS);
if (result == ERROR_SUCCESS)
- push(PTR_TO_UINT64(function->return_obj));
+ {
+ r1.i = PTR_TO_UINT64(function->return_obj);
+ push(r1);
+ }
else
+ {
return result;
+ }
break;
case OP_FOUND:
pop(r1);
- string = UINT64_TO_PTR(YR_STRING*, r1);
- push(string->matches[tidx].tail != NULL ? 1 : 0);
+ string = UINT64_TO_PTR(YR_STRING*, r1.i);
+ r1.i = string->matches[tidx].tail != NULL ? 1 : 0;
+ push(r1);
break;
case OP_FOUND_AT:
pop(r2);
pop(r1);
- if (IS_UNDEFINED(r1))
+ if (is_undef(r1))
{
- push(0);
+ r1.i = 0;
+ push(r1);
break;
}
- string = UINT64_TO_PTR(YR_STRING*, r2);
+ string = UINT64_TO_PTR(YR_STRING*, r2.i);
match = string->matches[tidx].head;
- found = 0;
+ r3.i = FALSE;
while (match != NULL)
{
- if (r1 == match->base + match->offset)
+ if (r1.i == match->base + match->offset)
{
- push(1);
- found = 1;
+ r3.i = TRUE;
break;
}
- if (r1 < match->base + match->offset)
+ if (r1.i < match->base + match->offset)
break;
match = match->next;
}
- if (!found)
- push(0);
-
+ push(r3);
break;
case OP_FOUND_IN:
@@ -553,64 +574,58 @@ int yr_execute_code(
pop(r2);
pop(r1);
- break_if_undefined(r1);
- break_if_undefined(r2);
+ break_if_undef(r1);
+ break_if_undef(r2);
- string = UINT64_TO_PTR(YR_STRING*, r3);
+ string = UINT64_TO_PTR(YR_STRING*, r3.i);
match = string->matches[tidx].head;
- found = FALSE;
+ r3.i = FALSE;
- while (match != NULL && !found)
+ while (match != NULL && !r3.i)
{
- if (match->base + match->offset >= r1 &&
- match->base + match->offset <= r2)
+ if (match->base + match->offset >= r1.i &&
+ match->base + match->offset <= r2.i)
{
- push(1);
- found = TRUE;
+ r3.i = TRUE;
}
- if (match->base + match->offset > r2)
+ if (match->base + match->offset > r2.i)
break;
match = match->next;
}
- if (!found)
- push(0);
-
+ push(r3);
break;
case OP_COUNT:
pop(r1);
- string = UINT64_TO_PTR(YR_STRING*, r1);
- push(string->matches[tidx].count);
+ string = UINT64_TO_PTR(YR_STRING*, r1.i);
+ r1.i = string->matches[tidx].count;
+ push(r1);
break;
case OP_OFFSET:
pop(r2);
pop(r1);
- break_if_undefined(r1);
- string = UINT64_TO_PTR(YR_STRING*, r2);
+ break_if_undef(r1);
+
+ string = UINT64_TO_PTR(YR_STRING*, r2.i);
match = string->matches[tidx].head;
i = 1;
- found = FALSE;
+ r3.i = UNDEFINED;
- while (match != NULL && !found)
+ while (match != NULL && r3.i == UNDEFINED)
{
- if (r1 == i)
- {
- push(match->base + match->offset);
- found = TRUE;
- }
+ if (r1.i == i)
+ r3.i = match->base + match->offset;
i++;
match = match->next;
}
- if (!found)
- push(UNDEFINED);
-
+ push(r3);
break;
case OP_OF:
@@ -618,9 +633,9 @@ int yr_execute_code(
count = 0;
pop(r1);
- while (!IS_UNDEFINED(r1))
+ while (!is_undef(r1))
{
- string = UINT64_TO_PTR(YR_STRING*, r1);
+ string = UINT64_TO_PTR(YR_STRING*, r1.i);
if (string->matches[tidx].tail != NULL)
found++;
count++;
@@ -629,101 +644,117 @@ int yr_execute_code(
pop(r2);
- if (IS_UNDEFINED(r2))
- push(found >= count ? 1 : 0);
+ if (is_undef(r2))
+ r1.i = found >= count ? 1 : 0;
else
- push(found >= r2 ? 1 : 0);
+ r1.i = found >= r2.i ? 1 : 0;
+ push(r1);
break;
case OP_FILESIZE:
- push(context->file_size);
+ r1.i = context->file_size;
+ push(r1);
break;
case OP_ENTRYPOINT:
- push(context->entry_point);
+ r1.i = context->entry_point;
+ push(r1);
break;
case OP_INT8:
pop(r1);
- push(read_int8_t_little_endian(context->mem_block, r1));
+ r1.i = read_int8_t_little_endian(context->mem_block, r1.i);
+ push(r1);
break;
case OP_INT16:
pop(r1);
- push(read_int16_t_little_endian(context->mem_block, r1));
+ r1.i = read_int16_t_little_endian(context->mem_block, r1.i);
+ push(r1);
break;
case OP_INT32:
pop(r1);
- push(read_int32_t_little_endian(context->mem_block, r1));
+ r1.i = read_int32_t_little_endian(context->mem_block, r1.i);
+ push(r1);
break;
case OP_UINT8:
pop(r1);
- push(read_uint8_t_little_endian(context->mem_block, r1));
+ r1.i = read_uint8_t_little_endian(context->mem_block, r1.i);
+ push(r1);
break;
case OP_UINT16:
pop(r1);
- push(read_uint16_t_little_endian(context->mem_block, r1));
+ r1.i = read_uint16_t_little_endian(context->mem_block, r1.i);
+ push(r1);
break;
case OP_UINT32:
pop(r1);
- push(read_uint32_t_little_endian(context->mem_block, r1));
+ r1.i = read_uint32_t_little_endian(context->mem_block, r1.i);
+ push(r1);
break;
case OP_INT8BE:
pop(r1);
- push(read_int8_t_big_endian(context->mem_block, r1));
+ r1.i = read_int8_t_big_endian(context->mem_block, r1.i);
+ push(r1);
break;
case OP_INT16BE:
pop(r1);
- push(read_int16_t_big_endian(context->mem_block, r1));
+ r1.i = read_int16_t_big_endian(context->mem_block, r1.i);
+ push(r1);
break;
case OP_INT32BE:
pop(r1);
- push(read_int32_t_big_endian(context->mem_block, r1));
+ r1.i = read_int32_t_big_endian(context->mem_block, r1.i);
+ push(r1);
break;
case OP_UINT8BE:
pop(r1);
- push(read_uint8_t_big_endian(context->mem_block, r1));
+ r1.i = read_uint8_t_big_endian(context->mem_block, r1.i);
+ push(r1);
break;
case OP_UINT16BE:
pop(r1);
- push(read_uint16_t_big_endian(context->mem_block, r1));
+ r1.i = read_uint16_t_big_endian(context->mem_block, r1.i);
+ push(r1);
break;
case OP_UINT32BE:
pop(r1);
- push(read_uint32_t_big_endian(context->mem_block, r1));
+ r1.i = read_uint32_t_big_endian(context->mem_block, r1.i);
+ push(r1);
break;
case OP_CONTAINS:
pop(r2);
pop(r1);
- break_if_undefined(r1);
- break_if_undefined(r2);
+ break_if_undef(r1);
+ break_if_undef(r2);
- sized_str_1 = UINT64_TO_PTR(SIZED_STRING*, r1);
- sized_str_2 = UINT64_TO_PTR(SIZED_STRING*, r2);
+ sized_str_1 = UINT64_TO_PTR(SIZED_STRING*, r1.i);
+ sized_str_2 = UINT64_TO_PTR(SIZED_STRING*, r2.i);
- push(memmem(sized_str_1->c_string, sized_str_1->length,
- sized_str_2->c_string, sized_str_2->length) != NULL);
+ r1.i = memmem(sized_str_1->c_string, sized_str_1->length,
+ sized_str_2->c_string, sized_str_2->length) != NULL;
+ push(r1);
break;
case OP_IMPORT:
- r1 = *(uint64_t*)(ip + 1);
+ r1.i = *(uint64_t*)(ip + 1);
ip += sizeof(uint64_t);
FAIL_ON_ERROR(yr_modules_load(
- UINT64_TO_PTR(char*, r1),
+ UINT64_TO_PTR(char*, r1.i),
context));
break;
@@ -732,163 +763,222 @@ int yr_execute_code(
pop(r2);
pop(r1);
- sized_str_1 = UINT64_TO_PTR(SIZED_STRING*, r1);
+ sized_str_1 = UINT64_TO_PTR(SIZED_STRING*, r1.i);
if (sized_str_1->length == 0)
{
- push(FALSE);
+ r1.i = FALSE;
+ push(r1);
break;
}
result = yr_re_exec(
- UINT64_TO_PTR(uint8_t*, r2),
+ UINT64_TO_PTR(uint8_t*, r2.i),
(uint8_t*) sized_str_1->c_string,
sized_str_1->length,
RE_FLAGS_SCAN,
NULL,
NULL);
- push(result >= 0);
+ r1.i = result >= 0;
+ push(r1);
break;
case OP_INT_TO_DBL:
- r1 = *(uint64_t*)(ip + 1);
+ r1.i = *(uint64_t*)(ip + 1);
ip += sizeof(uint64_t);
-
- pop_rel(r1, r2);
- break_if_undefined(r2);
- push_dbl_rel(r1, r2);
+ r2 = stack[sp - r1.i];
+ if (is_undef(r2))
+ stack[sp - r1.i].i = UNDEFINED;
+ else
+ stack[sp - r1.i].d = r2.i;
break;
case OP_STR_TO_BOOL:
pop(r1);
- break_if_undefined(r1);
- push(UINT64_TO_PTR(SIZED_STRING*, r1)->length > 0);
+ break_if_undef(r1);
+ r1.i = UINT64_TO_PTR(SIZED_STRING*, r1.i)->length > 0;
+ push(r1);
break;
case OP_INT_EQ:
pop(r2);
pop(r1);
- push(COMPARISON(==, r1, r2));
+ break_if_undef(r2);
+ break_if_undef(r1);
+ r1.i = r1.i == r2.i;
+ push(r1);
break;
case OP_INT_NEQ:
pop(r2);
pop(r1);
- push(COMPARISON(!=, r1, r2));
+ break_if_undef(r2);
+ break_if_undef(r1);
+ r1.i = r1.i != r2.i;
+ push(r1);
break;
case OP_INT_LT:
pop(r2);
pop(r1);
- push(COMPARISON(<, r1, r2));
+ break_if_undef(r2);
+ break_if_undef(r1);
+ r1.i = r1.i < r2.i;
+ push(r1);
break;
case OP_INT_GT:
pop(r2);
pop(r1);
- push(COMPARISON(>, r1, r2));
+ break_if_undef(r2);
+ break_if_undef(r1);
+ r1.i = r1.i > r2.i;
+ push(r1);
break;
case OP_INT_LE:
pop(r2);
pop(r1);
- push(COMPARISON(<=, r1, r2));
+ break_if_undef(r2);
+ break_if_undef(r1);
+ r1.i = r1.i <= r2.i;
+ push(r1);
break;
case OP_INT_GE:
pop(r2);
pop(r1);
- push(COMPARISON(>=, r1, r2));
+ break_if_undef(r2);
+ break_if_undef(r1);
+ r1.i = r1.i >= r2.i;
+ push(r1);
break;
case OP_INT_ADD:
pop(r2);
pop(r1);
- push(OPERATION(+, r1, r2));
+ break_if_undef(r2);
+ break_if_undef(r1);
+ r1.i = r1.i + r2.i;
+ push(r1);
break;
case OP_INT_SUB:
pop(r2);
pop(r1);
- push(OPERATION(-, r1, r2));
+ break_if_undef(r2);
+ break_if_undef(r1);
+ r1.i = r1.i - r2.i;
+ push(r1);
break;
case OP_INT_MUL:
pop(r2);
pop(r1);
- push(OPERATION(*, r1, r2));
+ break_if_undef(r2);
+ break_if_undef(r1);
+ r1.i = r1.i * r2.i;
+ push(r1);
break;
case OP_INT_DIV:
pop(r2);
pop(r1);
- push(OPERATION(/, r1, r2));
+ break_if_undef(r2);
+ break_if_undef(r1);
+ r1.i = r1.i / r2.i;
+ push(r1);
break;
- // Double comparisons do not use push_dbl because the result is just
- // an integer.
-
case OP_DBL_LT:
- pop_dbl(dr2);
- pop_dbl(dr1);
- push(COMPARISON(<, dr1, dr2));
+ pop(r2);
+ pop(r1);
+ break_if_undef(r2);
+ break_if_undef(r1);
+ r1.i = r1.d < r2.d;
+ push(r1);
break;
case OP_DBL_GT:
- pop_dbl(dr2);
- pop_dbl(dr1);
- push(COMPARISON(>, dr1, dr2));
+ pop(r2);
+ pop(r1);
+ break_if_undef(r2);
+ break_if_undef(r1);
+ r1.i = r1.d > r2.d;
+ push(r1);
break;
case OP_DBL_LE:
- pop_dbl(dr2);
- pop_dbl(dr1);
- push(COMPARISON(<=, dr1, dr2));
+ pop(r2);
+ pop(r1);
+ break_if_undef(r2);
+ break_if_undef(r1);
+ r1.i = r1.d <= r2.d;
+ push(r1);
break;
case OP_DBL_GE:
- pop_dbl(dr2);
- pop_dbl(dr1);
- push(COMPARISON(>=, dr1, dr2));
+ pop(r2);
+ pop(r1);
+ break_if_undef(r2);
+ break_if_undef(r1);
+ r1.i = r1.d >= r2.d;
+ push(r1);
break;
case OP_DBL_EQ:
- pop_dbl(dr2);
- pop_dbl(dr1);
- push(COMPARISON(==, dr1, dr2));
+ pop(r2);
+ pop(r1);
+ break_if_undef(r2);
+ break_if_undef(r1);
+ r1.i = r1.d == r2.d;
+ push(r1);
break;
case OP_DBL_NEQ:
- pop_dbl(dr2);
- pop_dbl(dr1);
- push(COMPARISON(!=, dr1, dr2));
+ pop(r2);
+ pop(r1);
+ break_if_undef(r2);
+ break_if_undef(r1);
+ r1.i = r1.d != r2.d;
+ push(r1);
break;
- // Double operations do use push_dbl because the result is a double.
-
case OP_DBL_ADD:
- pop_dbl(dr2);
- pop_dbl(dr1);
- push_dbl(OPERATION(+, dr1, dr2));
+ pop(r2);
+ pop(r1);
+ break_if_undef(r2);
+ break_if_undef(r1);
+ r1.d = r1.d + r2.d;
+ push(r1);
break;
case OP_DBL_SUB:
- pop_dbl(dr2);
- pop_dbl(dr1);
- push_dbl(OPERATION(-, dr1, dr2));
+ pop(r2);
+ pop(r1);
+ break_if_undef(r2);
+ break_if_undef(r1);
+ r1.d = r1.d - r2.d;
+ push(r1);
break;
case OP_DBL_MUL:
- pop_dbl(dr2);
- pop_dbl(dr1);
- push_dbl(OPERATION(*, dr1, dr2));
+ pop(r2);
+ pop(r1);
+ break_if_undef(r2);
+ break_if_undef(r1);
+ r1.d = r1.d * r2.d;
+ push(r1);
break;
case OP_DBL_DIV:
- pop_dbl(dr2);
- pop_dbl(dr1);
- push_dbl(OPERATION(/, dr1, dr2));
+ pop(r2);
+ pop(r1);
+ break_if_undef(r2);
+ break_if_undef(r1);
+ r1.d = r1.d / r2.d;
+ push(r1);
break;
case OP_STR_EQ:
@@ -901,36 +991,37 @@ int yr_execute_code(
pop(r2);
pop(r1);
- break_if_undefined(r1);
- break_if_undefined(r2);
+ break_if_undef(r1);
+ break_if_undef(r2);
- sized_str_1 = UINT64_TO_PTR(SIZED_STRING*, r1);
- sized_str_2 = UINT64_TO_PTR(SIZED_STRING*, r2);
+ sized_str_1 = UINT64_TO_PTR(SIZED_STRING*, r1.i);
+ sized_str_2 = UINT64_TO_PTR(SIZED_STRING*, r2.i);
int r = sized_string_cmp(sized_str_1, sized_str_2);
switch(*ip)
{
case OP_STR_EQ:
- push(r == 0);
+ r1.i = (r == 0);
break;
case OP_STR_NEQ:
- push(r != 0);
+ r1.i = (r != 0);
break;
case OP_STR_LT:
- push(r < 0);
+ r1.i = (r < 0);
break;
case OP_STR_LE:
- push(r <= 0);
+ r1.i = (r <= 0);
break;
case OP_STR_GT:
- push(r > 0);
+ r1.i = (r > 0);
break;
case OP_STR_GE:
- push(r >= 0);
+ r1.i = (r >= 0);
break;
}
+ push(r1);
break;
default:
diff --git a/libyara/include/yara/modules.h b/libyara/include/yara/modules.h
index 03fcfa1..067ea3f 100644
--- a/libyara/include/yara/modules.h
+++ b/libyara/include/yara/modules.h
@@ -20,6 +20,7 @@ limitations under the License.
#include <assert.h>
#include <stdio.h>
#include <string.h>
+#include <math.h>
#include <yara/utils.h>
#include <yara/limits.h>
@@ -160,6 +161,45 @@ limitations under the License.
}
+#define declare_double(name) { \
+ FAIL_ON_ERROR(yr_object_create( \
+ OBJECT_TYPE_DOUBLE, \
+ name, \
+ stack[stack_top], \
+ NULL)); \
+ }
+
+
+#define declare_double_array(name) { \
+ YR_OBJECT* array; \
+ FAIL_ON_ERROR(yr_object_create( \
+ OBJECT_TYPE_ARRAY, \
+ name, \
+ stack[stack_top], \
+ &array)); \
+ FAIL_ON_ERROR(yr_object_create( \
+ OBJECT_TYPE_DOUBLE, \
+ name, \
+ array, \
+ NULL)); \
+ }
+
+
+#define declare_double_dictionary(name) { \
+ YR_OBJECT* dict; \
+ FAIL_ON_ERROR(yr_object_create( \
+ OBJECT_TYPE_DICTIONARY, \
+ name, \
+ stack[stack_top], \
+ &dict)); \
+ FAIL_ON_ERROR(yr_object_create( \
+ OBJECT_TYPE_DOUBLE, \
+ name, \
+ dict, \
+ NULL)); \
+ }
+
+
#define declare_string(name) { \
FAIL_ON_ERROR(yr_object_create( \
OBJECT_TYPE_STRING, \
@@ -293,8 +333,9 @@ limitations under the License.
assertf( \
__function_obj->return_obj->type == OBJECT_TYPE_DOUBLE, \
"return type differs from function declaration"); \
+ double d = (double) (double_); \
yr_object_set_double( \
- (double_), \
+ (d != (double) UNDEFINED) ? d : NAN, \
__function_obj->return_obj, \
NULL); \
return ERROR_SUCCESS; \
diff --git a/libyara/object.c b/libyara/object.c
index e08688e..050afb3 100644
--- a/libyara/object.c
+++ b/libyara/object.c
@@ -20,6 +20,7 @@ limitations under the License.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <math.h>
#if _WIN32
#define PRIu64 "%I64d"
@@ -106,7 +107,7 @@ int yr_object_create(
((YR_OBJECT_INTEGER*) obj)->value = UNDEFINED;
break;
case OBJECT_TYPE_DOUBLE:
- ((YR_OBJECT_DOUBLE*) obj)->value = UNDEFINED;
+ ((YR_OBJECT_DOUBLE*) obj)->value = NAN;
break;
case OBJECT_TYPE_STRING:
((YR_OBJECT_STRING*) obj)->value = NULL;
@@ -860,7 +861,7 @@ double yr_object_get_double(
va_end(args);
if (double_obj == NULL)
- return UNDEFINED;
+ return NAN;
assertf(double_obj->type == OBJECT_TYPE_DOUBLE,
"type of \"%s\" is not double\n", field);
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/forensics/yara.git
More information about the forensics-changes
mailing list