Implement the OP_OF_FOUND_IN opcode. (#1554)

This is a combination of "OP_OF" and "OP_FOUND_IN" that allows you to express logic like "all of them in (0..100)". This came out of the discussion in #1483 and likely makes part of that pull request redundant.
This commit is contained in:
Wesley Shields
2021-08-31 19:34:16 +02:00
committed by GitHub
parent 0293d2ad90
commit 24a5ad1383
7 changed files with 1672 additions and 1350 deletions
+9
View File
@@ -1167,6 +1167,15 @@ The keywords ``any`` and ``all`` can be used as well.
1 of ($*) // same that "any of them"
Starting with YARA 4.2.0 it is possible to express a set of strings in an
integer range, like this:
.. code-block:: yara
all of ($a*) in (filesize-500..filesize)
any of ($a*, $b*) in (1000..2000)
Applying the same condition to many strings
-------------------------------------------
+42
View File
@@ -1341,6 +1341,48 @@ int yr_execute_code(YR_SCAN_CONTEXT* context)
push(r1);
break;
case OP_OF_FOUND_IN:
YR_DEBUG_FPRINTF(2, stderr, "- case OP_OF_RANGE: // %s()\n", __FUNCTION__);
count = 0;
pop(r2);
pop(r1);
ensure_defined(r1);
ensure_defined(r2);
pop(r3);
while (!is_undef(r3))
{
#if YR_PARANOID_EXEC
ensure_within_rules_arena(r3.p);
#endif
match = context->matches[r3.s->idx].head;
while (match != NULL)
{
if (match->base + match->offset >= r1.i &&
match->base + match->offset <= r2.i)
{
count++;
break;
}
if (match->base + match->offset > r1.i)
break;
match = match->next;
}
pop(r3);
}
pop(r1)
r1.i = count >= r1.i ? 1 : 0;
push(r1);
break;
case OP_FILESIZE:
r1.i = context->file_size;
YR_DEBUG_FPRINTF(
+1475 -1275
View File
File diff suppressed because it is too large Load Diff
+128 -75
View File
@@ -1,9 +1,8 @@
/* A Bison parser, made by GNU Bison 3.7.4. */
/* A Bison parser, made by GNU Bison 3.0.5. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
Inc.
Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -31,10 +30,6 @@
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
especially those whose name start with YY_ or yy_. They are
private implementation details that can be changed or removed. */
#ifndef YY_YARA_YY_GRAMMAR_H_INCLUDED
# define YY_YARA_YY_GRAMMAR_H_INCLUDED
/* Debug traces. */
@@ -45,83 +40,141 @@
extern int yara_yydebug;
#endif
/* Token kinds. */
/* Token type. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
enum yytokentype
{
YYEMPTY = -2,
_END_OF_FILE_ = 0, /* "end of file" */
YYerror = 256, /* error */
YYUNDEF = 257, /* "invalid token" */
_END_OF_INCLUDED_FILE_ = 258, /* "end of included file" */
_DOT_DOT_ = 259, /* ".." */
_RULE_ = 260, /* "<rule>" */
_PRIVATE_ = 261, /* "<private>" */
_GLOBAL_ = 262, /* "<global>" */
_META_ = 263, /* "<meta>" */
_STRINGS_ = 264, /* "<strings>" */
_CONDITION_ = 265, /* "<condition>" */
_IDENTIFIER_ = 266, /* "identifier" */
_STRING_IDENTIFIER_ = 267, /* "string identifier" */
_STRING_COUNT_ = 268, /* "string count" */
_STRING_OFFSET_ = 269, /* "string offset" */
_STRING_LENGTH_ = 270, /* "string length" */
_STRING_IDENTIFIER_WITH_WILDCARD_ = 271, /* "string identifier with wildcard" */
_NUMBER_ = 272, /* "integer number" */
_DOUBLE_ = 273, /* "floating point number" */
_INTEGER_FUNCTION_ = 274, /* "integer function" */
_TEXT_STRING_ = 275, /* "text string" */
_HEX_STRING_ = 276, /* "hex string" */
_REGEXP_ = 277, /* "regular expression" */
_ASCII_ = 278, /* "<ascii>" */
_WIDE_ = 279, /* "<wide>" */
_XOR_ = 280, /* "<xor>" */
_BASE64_ = 281, /* "<base64>" */
_BASE64_WIDE_ = 282, /* "<base64wide>" */
_NOCASE_ = 283, /* "<nocase>" */
_FULLWORD_ = 284, /* "<fullword>" */
_AT_ = 285, /* "<at>" */
_FILESIZE_ = 286, /* "<filesize>" */
_ENTRYPOINT_ = 287, /* "<entrypoint>" */
_ALL_ = 288, /* "<all>" */
_ANY_ = 289, /* "<any>" */
_IN_ = 290, /* "<in>" */
_OF_ = 291, /* "<of>" */
_FOR_ = 292, /* "<for>" */
_THEM_ = 293, /* "<them>" */
_MATCHES_ = 294, /* "<matches>" */
_CONTAINS_ = 295, /* "<contains>" */
_STARTSWITH_ = 296, /* "<startswith>" */
_ENDSWITH_ = 297, /* "<endswith>" */
_ICONTAINS_ = 298, /* "<icontains>" */
_ISTARTSWITH_ = 299, /* "<istartswith>" */
_IENDSWITH_ = 300, /* "<iendswith>" */
_IEQUALS_ = 301, /* "<iequals>" */
_IMPORT_ = 302, /* "<import>" */
_TRUE_ = 303, /* "<true>" */
_FALSE_ = 304, /* "<false>" */
_OR_ = 305, /* "<or>" */
_AND_ = 306, /* "<and>" */
_NOT_ = 307, /* "<not>" */
_EQ_ = 308, /* "==" */
_NEQ_ = 309, /* "!=" */
_LT_ = 310, /* "<" */
_LE_ = 311, /* "<=" */
_GT_ = 312, /* ">" */
_GE_ = 313, /* ">=" */
_SHIFT_LEFT_ = 314, /* "<<" */
_SHIFT_RIGHT_ = 315, /* ">>" */
UNARY_MINUS = 316 /* UNARY_MINUS */
_END_OF_FILE_ = 0,
_END_OF_INCLUDED_FILE_ = 258,
_DOT_DOT_ = 259,
_RULE_ = 260,
_PRIVATE_ = 261,
_GLOBAL_ = 262,
_META_ = 263,
_STRINGS_ = 264,
_CONDITION_ = 265,
_IDENTIFIER_ = 266,
_STRING_IDENTIFIER_ = 267,
_STRING_COUNT_ = 268,
_STRING_OFFSET_ = 269,
_STRING_LENGTH_ = 270,
_STRING_IDENTIFIER_WITH_WILDCARD_ = 271,
_NUMBER_ = 272,
_DOUBLE_ = 273,
_INTEGER_FUNCTION_ = 274,
_TEXT_STRING_ = 275,
_HEX_STRING_ = 276,
_REGEXP_ = 277,
_ASCII_ = 278,
_WIDE_ = 279,
_XOR_ = 280,
_BASE64_ = 281,
_BASE64_WIDE_ = 282,
_NOCASE_ = 283,
_FULLWORD_ = 284,
_AT_ = 285,
_FILESIZE_ = 286,
_ENTRYPOINT_ = 287,
_ALL_ = 288,
_ANY_ = 289,
_IN_ = 290,
_OF_ = 291,
_FOR_ = 292,
_THEM_ = 293,
_MATCHES_ = 294,
_CONTAINS_ = 295,
_STARTSWITH_ = 296,
_ENDSWITH_ = 297,
_ICONTAINS_ = 298,
_ISTARTSWITH_ = 299,
_IENDSWITH_ = 300,
_IEQUALS_ = 301,
_IMPORT_ = 302,
_TRUE_ = 303,
_FALSE_ = 304,
_OR_ = 305,
_AND_ = 306,
_NOT_ = 307,
_EQ_ = 308,
_NEQ_ = 309,
_LT_ = 310,
_LE_ = 311,
_GT_ = 312,
_GE_ = 313,
_SHIFT_LEFT_ = 314,
_SHIFT_RIGHT_ = 315,
UNARY_MINUS = 316
};
typedef enum yytokentype yytoken_kind_t;
#endif
/* Tokens. */
#define _END_OF_FILE_ 0
#define _END_OF_INCLUDED_FILE_ 258
#define _DOT_DOT_ 259
#define _RULE_ 260
#define _PRIVATE_ 261
#define _GLOBAL_ 262
#define _META_ 263
#define _STRINGS_ 264
#define _CONDITION_ 265
#define _IDENTIFIER_ 266
#define _STRING_IDENTIFIER_ 267
#define _STRING_COUNT_ 268
#define _STRING_OFFSET_ 269
#define _STRING_LENGTH_ 270
#define _STRING_IDENTIFIER_WITH_WILDCARD_ 271
#define _NUMBER_ 272
#define _DOUBLE_ 273
#define _INTEGER_FUNCTION_ 274
#define _TEXT_STRING_ 275
#define _HEX_STRING_ 276
#define _REGEXP_ 277
#define _ASCII_ 278
#define _WIDE_ 279
#define _XOR_ 280
#define _BASE64_ 281
#define _BASE64_WIDE_ 282
#define _NOCASE_ 283
#define _FULLWORD_ 284
#define _AT_ 285
#define _FILESIZE_ 286
#define _ENTRYPOINT_ 287
#define _ALL_ 288
#define _ANY_ 289
#define _IN_ 290
#define _OF_ 291
#define _FOR_ 292
#define _THEM_ 293
#define _MATCHES_ 294
#define _CONTAINS_ 295
#define _STARTSWITH_ 296
#define _ENDSWITH_ 297
#define _ICONTAINS_ 298
#define _ISTARTSWITH_ 299
#define _IENDSWITH_ 300
#define _IEQUALS_ 301
#define _IMPORT_ 302
#define _TRUE_ 303
#define _FALSE_ 304
#define _OR_ 305
#define _AND_ 306
#define _NOT_ 307
#define _EQ_ 308
#define _NEQ_ 309
#define _LT_ 310
#define _LE_ 311
#define _GT_ 312
#define _GE_ 313
#define _SHIFT_LEFT_ 314
#define _SHIFT_RIGHT_ 315
#define UNARY_MINUS 316
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
union YYSTYPE
{
#line 303 "grammar.y"
#line 303 "grammar.y" /* yacc.c:1916 */
YR_EXPRESSION expression;
SIZED_STRING* sized_string;
@@ -135,9 +188,9 @@ union YYSTYPE
YR_ARENA_REF meta;
YR_ARENA_REF string;
#line 139 "grammar.h"
#line 192 "grammar.h" /* yacc.c:1916 */
};
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
+6
View File
@@ -1780,6 +1780,12 @@ expression
{
yr_parser_emit(yyscanner, OP_OF, NULL);
$$.type = EXPRESSION_TYPE_BOOLEAN;
}
| for_expression _OF_ string_set _IN_ range
{
yr_parser_emit(yyscanner, OP_OF_FOUND_IN, NULL);
$$.type = EXPRESSION_TYPE_BOOLEAN;
}
| _NOT_ boolean_expression
+1
View File
@@ -112,6 +112,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define OP_ISTARTSWITH 68
#define OP_IENDSWITH 69
#define OP_IEQUALS 70
#define OP_OF_FOUND_IN 71
#define _OP_EQ 0
#define _OP_NEQ 1
+11
View File
@@ -608,6 +608,17 @@ static void test_strings()
}",
TEXT_1024_BYTES "abcdef");
assert_true_rule(
"rule test {\n\
strings:\n\
$a = \"foo\"\n\
$b = \"bar\"\n\
$c = \"baz\"\n\
condition:\n\
all of them in (0..10)\n\
}",
"foobarbaz" TEXT_1024_BYTES);
// xor by itself will match the plaintext version of the string too.
assert_true_rule_file(
"rule test {\n\