summaryrefslogtreecommitdiff
path: root/tools/yara2rost/grammar.y
diff options
context:
space:
mode:
Diffstat (limited to 'tools/yara2rost/grammar.y')
-rw-r--r--tools/yara2rost/grammar.y1332
1 files changed, 1332 insertions, 0 deletions
diff --git a/tools/yara2rost/grammar.y b/tools/yara2rost/grammar.y
new file mode 100644
index 0000000..0d756b1
--- /dev/null
+++ b/tools/yara2rost/grammar.y
@@ -0,0 +1,1332 @@
+
+%{
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+
+#include "decl.h"
+#include "tokens.h"
+
+
+
+/* Affiche un message d'erreur suite à l'analyse en échec. */
+static int yyerror(yyscan_t, const char *);
+
+/* Initialise une amorce de copie. */
+static void init_dump(sz_str_t *, const sz_cst_str_t *);
+
+#define init_dump_with_fixed(d, s) \
+ init_dump(d, (sz_cst_str_t []) { { .data = s, .len = sizeof(s) - 1 } })
+
+/* Complète une chaîne de caractères avec une autre. */
+static void add_to_dump(sz_str_t *, const sz_cst_str_t *);
+
+#define add_fixed_to_dump(d, s) \
+ add_to_dump(d, (sz_cst_str_t []) { { .data = s, .len = sizeof(s) - 1 } })
+
+#define add_dyn_to_dump(d, s) \
+ do \
+ { \
+ add_to_dump(d, (sz_cst_str_t *)s); \
+ free((s)->data); \
+ } \
+ while (0)
+
+/* Imprime une bribe de définition formant une règle ROST. */
+void dump_string(const char *, size_t);
+
+#define dump_fixed_string(s) \
+ dump_string(s, sizeof(s) - 1)
+
+
+%}
+
+
+%code requires {
+
+#include <stdbool.h>
+#include <sys/types.h>
+
+#include "enums.h"
+
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void *yyscan_t;
+
+
+typedef struct _sz_str_t
+{
+ char *data;
+ size_t len;
+
+} sz_str_t;
+
+typedef struct _sz_cst_str_t
+{
+ char *data;
+ size_t len;
+
+} sz_cst_str_t;
+
+}
+
+%union {
+
+ sz_str_t string; /* Chaîne de caractères #1 */
+ sz_cst_str_t cstring; /* Chaîne de caractères #2 */
+
+ RuleFlags rule_flags; /* Fanions pour règle */
+ StringExtraFlags string_flags; /* Fanions pour motif */
+
+}
+
+
+%expect 1
+
+%define api.pure full
+%define parse.error verbose
+
+%parse-param { yyscan_t yyscanner }
+%lex-param { yyscan_t yyscanner }
+
+
+%code provides {
+
+#define YY_DECL \
+ int yara2rost_lex(YYSTYPE *yylval_param, yyscan_t yyscanner)
+
+YY_DECL;
+
+}
+
+%token COLON ":"
+%token CURLY_BRACKET_O "{"
+%token CURLY_BRACKET_C "}"
+%token EQUAL "="
+%token PAREN_O "("
+%token PAREN_C ")"
+%token DOT_DOT ".."
+%token COMMA ","
+%token BRACKET_O "["
+%token BRACKET_C "]"
+%token PERCENT "%"
+%token DOT "."
+
+%token ADD_OP "+"
+%token SUB_OP "-"
+%token MUL_OP "*"
+%token DIV_OP "\\"
+%token EOR_OP "^"
+%token AND_OP "&"
+%token OR_OP "|"
+%token INV_OP "~"
+%token SHIFT_LEFT_OP "<<"
+%token SHIFT_RIGHT_OP ">>"
+
+%token LT "<"
+%token GT ">"
+%token LE "<="
+%token GE ">="
+%token EQ "=="
+%token NEQ "!="
+
+%token ALL "all"
+%token AND "and"
+%token ANY "any"
+%token ASCII "ascii"
+%token AT "at"
+%token BASE64 "base64"
+%token BASE64WIDE "base64wide"
+%token CONDITION "condition"
+%token CONTAINS "contains"
+%token DEFINED "defined"
+%token ENDSWITH "endswith"
+%token ENTRYPOINT "entrypoint"
+%token FILESIZE "filesize"
+%token FOR "for"
+%token FULLWORD "fullword"
+%token GLOBAL "global"
+%token ICONTAINS "icontains"
+%token IENDSWITH "iendswith"
+%token IEQUALS "iequals"
+%token IMPORT "import"
+%token IN "in"
+%token INCLUDE "include"
+%token ISTARTSWITH "istartswith"
+%token MATCHES "matches"
+%token META "meta"
+%token NOCASE "nocase"
+%token NONE "none"
+%token NOT "not"
+%token OF "of"
+%token OR "or"
+%token PRIVATE "private"
+%token RULE "rule"
+%token STARTSWITH "startswith"
+%token STRINGS "strings"
+%token THEM "them"
+%token WIDE "wide"
+%token XOR "xor"
+
+%token _FALSE "false"
+%token _TRUE "true"
+
+%token STRING_IDENTIFIER_WITH_WILDCARD
+%token STRING_IDENTIFIER
+%token STRING_COUNT
+%token STRING_OFFSET
+%token STRING_LENGTH
+%token INTEGER_FUNCTION
+%token IDENTIFIER
+%token NUMBER
+%token DOUBLE
+%token TEXT_STRING
+%token REGEXP
+%token HEX_STRING
+
+%type <cstring> STRING_IDENTIFIER_WITH_WILDCARD
+%type <cstring> STRING_IDENTIFIER
+%type <cstring> STRING_COUNT
+%type <cstring> STRING_OFFSET
+%type <cstring> STRING_LENGTH
+%type <cstring> INTEGER_FUNCTION
+%type <cstring> IDENTIFIER
+%type <cstring> NUMBER
+%type <cstring> DOUBLE
+%type <cstring> TEXT_STRING
+%type <cstring> REGEXP
+%type <cstring> HEX_STRING
+
+%type <rule_flags> rule_modifiers
+%type <rule_flags> rule_modifier
+
+%type <string_flags> string_modifiers
+%type <string_flags> string_modifier
+%type <string_flags> regexp_modifiers
+%type <string_flags> regexp_modifier
+%type <string_flags> hex_modifiers
+%type <string_flags> hex_modifier
+
+%type <string> boolean_expression
+%type <string> identifier
+%type <string> arguments
+%type <string> arguments_list
+%type <string> expression
+%type <string> for_iteration
+%type <string> for_variables
+%type <string> iterator
+%type <string> set
+%type <string> range
+%type <string> enumeration
+%type <string> string_iterator
+%type <string> string_set
+%type <string> string_enumeration
+%type <string> string_enumeration_item
+%type <string> rule_set
+%type <string> rule_enumeration
+%type <string> rule_enumeration_item
+%type <string> for_expression
+%type <string> for_quantifier
+%type <string> primary_expression
+%type <string> regexp
+
+%left OR
+%left AND
+%right NOT DEFINED
+%left EQ NEQ CONTAINS ICONTAINS STARTSWITH ENDSWITH ISTARTSWITH IENDSWITH IEQUALS MATCHES
+%left LT LE GT GE
+%left OR_OP
+%left EOR_OP
+%left AND_OP
+%left SHIFT_LEFT_OP SHIFT_RIGHT_OP
+%left ADD_OP SUB_OP
+%left MUL_OP DIV_OP PERCENT
+%right INV_OP UNARY_MINUS
+
+
+%%
+
+ rules : /* empty */
+ | rules include
+ | rules import
+ | rules rule
+ ;
+
+
+ include : "include" TEXT_STRING
+ {
+ dump_fixed_string("include ");
+ dump_string($2.data, $2.len);
+ dump_fixed_string("\n");
+ }
+ ;
+
+ import : "import" TEXT_STRING
+ {
+ dump_fixed_string("/* import ");
+ dump_string($2.data, $2.len);
+ dump_fixed_string(" */\n");
+ }
+ ;
+
+
+ rule : rule_modifiers "rule" IDENTIFIER
+ {
+ if ($1 != RULE_FLAGS_NONE)
+ {
+ if ($1 & RULE_FLAGS_PRIVATE)
+ {
+ dump_fixed_string("private");
+ dump_fixed_string(" ");
+ }
+
+ if ($1 & RULE_FLAGS_GLOBAL)
+ {
+ dump_fixed_string("global");
+ dump_fixed_string(" ");
+ }
+
+ }
+
+ dump_fixed_string("rule ");
+ dump_string($3.data, $3.len);
+
+ }
+ tags "{"
+ {
+ dump_fixed_string(" {\n");
+ }
+ meta strings condition "}"
+ {
+ dump_fixed_string("}\n");
+ }
+ ;
+
+
+ rule_modifiers : /* empty */
+ {
+ $$ = RULE_FLAGS_NONE;
+ }
+ | rule_modifiers rule_modifier
+ {
+ $$ = $1 | $2;
+ }
+ ;
+
+ rule_modifier : "private"
+ {
+ $$ = RULE_FLAGS_PRIVATE;
+ }
+ | "global"
+ {
+ $$ = RULE_FLAGS_GLOBAL;
+ }
+ ;
+
+
+ tags : /* empty */
+ | ":"
+ {
+ dump_fixed_string(" :");
+ }
+ tag_list
+ ;
+
+ tag_list : IDENTIFIER
+ {
+ dump_fixed_string(" ");
+ dump_string($1.data, $1.len);
+ }
+ | tag_list IDENTIFIER
+ {
+ dump_fixed_string(" ");
+ dump_string($2.data, $2.len);
+ }
+ ;
+
+
+/**
+ * Section "meta:"
+ */
+
+ meta : /* empty */
+ | "meta" ":"
+ {
+ dump_fixed_string("\n ");
+ dump_fixed_string("meta:\n");
+ }
+ meta_declarations
+ ;
+
+ meta_declarations : meta_declaration
+ {
+ dump_fixed_string("\n");
+ }
+ | meta_declarations meta_declaration
+ {
+ dump_fixed_string("\n");
+ }
+ ;
+
+ meta_declaration : IDENTIFIER "=" TEXT_STRING
+ {
+ dump_fixed_string(" ");
+ dump_string($1.data, $1.len);
+ dump_fixed_string(" = ");
+ dump_string($3.data, $3.len);
+ }
+ | IDENTIFIER "=" NUMBER
+ {
+ dump_fixed_string(" ");
+ dump_string($1.data, $1.len);
+ dump_fixed_string(" = ");
+ dump_string($3.data, $3.len);
+ }
+ | IDENTIFIER "=" "-" NUMBER
+ {
+ dump_fixed_string(" ");
+ dump_string($1.data, $1.len);
+ dump_fixed_string(" = -");
+ dump_string($4.data, $4.len);
+ }
+ | IDENTIFIER "=" "true"
+ {
+ dump_fixed_string(" ");
+ dump_string($1.data, $1.len);
+ dump_fixed_string(" = true");
+ }
+ | IDENTIFIER "=" "false"
+ {
+ dump_fixed_string(" ");
+ dump_string($1.data, $1.len);
+ dump_fixed_string(" = false");
+ }
+ ;
+
+
+/**
+ * Section "strings:"
+ */
+
+ strings : /* empty */
+ | "strings" ":"
+ {
+ dump_fixed_string("\n ");
+ dump_fixed_string("bytes:\n");
+ }
+ string_declarations
+ ;
+
+ string_declarations : string_declaration
+ {
+ dump_fixed_string("\n");
+ }
+ | string_declarations string_declaration
+ {
+ dump_fixed_string("\n");
+ }
+ ;
+
+ string_declaration : STRING_IDENTIFIER "="
+ {
+ dump_fixed_string(" ");
+ dump_string($1.data, $1.len);
+ dump_fixed_string(" = ");
+ }
+ TEXT_STRING
+ {
+ dump_string($4.data, $4.len);
+ }
+ string_modifiers
+ {
+ if ($6 & STRING_FLAGS_NO_CASE)
+ dump_fixed_string(" nocase");
+
+ if ($6 & STRING_FLAGS_FULL_WORD)
+ dump_fixed_string(" fullword");
+
+ if ($6 & STRING_FLAGS_PRIVATE)
+ dump_fixed_string(" private");
+
+ }
+ | STRING_IDENTIFIER "="
+ {
+ dump_fixed_string(" ");
+ dump_string($1.data, $1.len);
+ dump_fixed_string(" = ");
+ }
+ REGEXP
+ {
+ dump_fixed_string("/");
+ dump_string($4.data, $4.len);
+ }
+ regexp_modifiers
+ {
+ if ($6 & STRING_FLAGS_NO_CASE)
+ dump_fixed_string(" nocase");
+
+ if ($6 & STRING_FLAGS_FULL_WORD)
+ dump_fixed_string(" fullword");
+
+ if ($6 & STRING_FLAGS_PRIVATE)
+ dump_fixed_string(" private");
+
+ }
+ | STRING_IDENTIFIER "="
+ {
+ dump_fixed_string(" ");
+ dump_string($1.data, $1.len);
+ dump_fixed_string(" = ");
+ }
+ HEX_STRING
+ {
+ dump_string($4.data, $4.len);
+ }
+ hex_modifiers
+ {
+ if ($6 & STRING_FLAGS_NO_CASE)
+ dump_fixed_string(" nocase");
+
+ if ($6 & STRING_FLAGS_FULL_WORD)
+ dump_fixed_string(" fullword");
+
+ if ($6 & STRING_FLAGS_PRIVATE)
+ dump_fixed_string(" private");
+
+ }
+ ;
+
+
+ string_modifiers : /* empty */
+ {
+ $$ = STRING_FLAGS_NONE;
+ }
+ | string_modifiers string_modifier
+ {
+ $$ = $1 | $2;
+ }
+ ;
+
+ string_modifier : "wide"
+ {
+ dump_fixed_string(" wide");
+ $$ = STRING_FLAGS_NONE;
+ }
+ | "ascii"
+ {
+ dump_fixed_string(" plain");
+ $$ = STRING_FLAGS_NONE;
+ }
+ | "nocase"
+ {
+ $$ = STRING_FLAGS_NO_CASE;
+ }
+ | "fullword"
+ {
+ $$ = STRING_FLAGS_FULL_WORD;
+ }
+ | "private"
+ {
+ $$ = STRING_FLAGS_PRIVATE;
+ }
+ | "xor"
+ {
+ dump_fixed_string(" xor");
+ $$ = STRING_FLAGS_NONE;
+ }
+ | "xor" "(" NUMBER ")"
+ {
+ dump_fixed_string(" xor(");
+ dump_string($3.data, $3.len);
+ dump_fixed_string(")");
+ $$ = STRING_FLAGS_NONE;
+ }
+ | "xor" "(" NUMBER "-" NUMBER ")"
+ {
+ dump_fixed_string(" xor(");
+ dump_string($3.data, $3.len);
+ dump_fixed_string("-");
+ dump_string($5.data, $5.len);
+ dump_fixed_string(")");
+ $$ = STRING_FLAGS_NONE;
+ }
+ | "base64"
+ {
+ dump_fixed_string(" base64");
+ $$ = STRING_FLAGS_NONE;
+ }
+ | "base64" "(" TEXT_STRING ")"
+ {
+ dump_fixed_string(" base64(");
+ dump_string($3.data, $3.len);
+ dump_fixed_string(")");
+ $$ = STRING_FLAGS_NONE;
+ }
+ | "base64wide"
+ {
+ dump_fixed_string(" (base64 | wide)");
+ $$ = STRING_FLAGS_NONE;
+ }
+ | "base64wide" "(" TEXT_STRING ")"
+ {
+ dump_fixed_string(" (base64(");
+ dump_string($3.data, $3.len);
+ dump_fixed_string(") | wide)");
+ $$ = STRING_FLAGS_NONE;
+ }
+ ;
+
+ regexp_modifiers : /* empty */
+ {
+ $$ = STRING_FLAGS_NONE;
+ }
+ | regexp_modifiers regexp_modifier
+ {
+ $$ = $1 | $2;
+ }
+ ;
+
+ regexp_modifier : "wide"
+ {
+ dump_fixed_string(" wide");
+ $$ = STRING_FLAGS_NONE;
+ }
+ | "ascii"
+ {
+ dump_fixed_string(" plain");
+ $$ = STRING_FLAGS_NONE;
+ }
+ | "nocase"
+ {
+ $$ = STRING_FLAGS_NO_CASE;
+ }
+ | "fullword"
+ {
+ $$ = STRING_FLAGS_FULL_WORD;
+ }
+ | "private"
+ {
+ $$ = STRING_FLAGS_PRIVATE;
+ }
+ ;
+
+ hex_modifiers : /* empty */
+ {
+ $$ = STRING_FLAGS_NONE;
+ }
+ | hex_modifiers hex_modifier
+ {
+ $$ = $1 | $2;
+ }
+ ;
+
+ hex_modifier : "private"
+ {
+ $$ = STRING_FLAGS_PRIVATE;
+ }
+ ;
+
+
+/**
+ * Section "condition:"
+ */
+
+ condition : "condition" ":" boolean_expression
+ {
+ dump_fixed_string("\n ");
+ dump_fixed_string("condition:\n");
+ dump_fixed_string(" ");
+ dump_string($3.data, $3.len);
+ free($3.data);
+ dump_fixed_string("\n\n");
+ }
+ ;
+
+ boolean_expression : expression { $$ = $1; }
+ ;
+
+ identifier : IDENTIFIER
+ {
+ init_dump(&$$, &$1);
+ }
+ | identifier "." IDENTIFIER
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, ".");
+ add_to_dump(&$$, &$3);
+ }
+ | identifier "[" primary_expression "]"
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, "[");
+ add_dyn_to_dump(&$$, &$3);
+ add_fixed_to_dump(&$$, "]");
+ }
+ | identifier "(" arguments ")"
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, "(");
+ if ($3.len > 0)
+ add_dyn_to_dump(&$$, &$3);
+ add_fixed_to_dump(&$$, ")");
+ }
+ ;
+
+
+ arguments : { $$.len = 0; /* empty */ }
+ | arguments_list { $$ = $1; }
+ ;
+
+
+ arguments_list : expression
+ {
+ $$ = $1;
+ }
+ | arguments_list "," expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, ", ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ ;
+
+
+ expression : "true"
+ {
+ init_dump_with_fixed(&$$, "true");
+ }
+ | "false"
+ {
+ init_dump_with_fixed(&$$, "false");
+ }
+ | primary_expression "matches" regexp
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " matches ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | primary_expression "contains" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " contains ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | primary_expression "icontains" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " icontains ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | primary_expression "startswith" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " startswith ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | primary_expression "istartswith" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " istartswith ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | primary_expression "endswith" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " endswith ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | primary_expression "iendswith" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " iendswith ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | primary_expression "iequals" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " iequals ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | STRING_IDENTIFIER
+ {
+ init_dump(&$$, &$1);
+ }
+ | STRING_IDENTIFIER "at" primary_expression
+ {
+ init_dump(&$$, &$1);
+ add_fixed_to_dump(&$$, " at ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | STRING_IDENTIFIER "in" range
+ {
+ init_dump(&$$, &$1);
+ add_fixed_to_dump(&$$, " in ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | "for" for_expression for_iteration ":" "(" boolean_expression ")"
+ {
+ init_dump_with_fixed(&$$, "for ");
+ add_dyn_to_dump(&$$, &$2);
+ add_dyn_to_dump(&$$, &$3);
+ add_fixed_to_dump(&$$, " : (");
+ add_dyn_to_dump(&$$, &$6);
+ add_fixed_to_dump(&$$, ")");
+ }
+ | for_expression "of" string_set
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " of ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | for_expression "of" rule_set
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " of ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+
+ | primary_expression "%" "of" string_set
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, "% of ");
+ add_dyn_to_dump(&$$, &$4);
+ }
+ | primary_expression "%" "of" rule_set
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, "% of ");
+ add_dyn_to_dump(&$$, &$4);
+ }
+
+ | for_expression "of" string_set "in" range
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " of ");
+ add_dyn_to_dump(&$$, &$3);
+ add_fixed_to_dump(&$$, " in ");
+ add_dyn_to_dump(&$$, &$5);
+ }
+ | for_expression "of" string_set "at" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " of ");
+ add_dyn_to_dump(&$$, &$3);
+ add_fixed_to_dump(&$$, " at ");
+ add_dyn_to_dump(&$$, &$5);
+ }
+ | "not" boolean_expression
+ {
+ init_dump_with_fixed(&$$, "not ");
+ add_dyn_to_dump(&$$, &$2);
+ }
+ | "defined" boolean_expression
+ {
+ init_dump_with_fixed(&$$, "defined ");
+ add_dyn_to_dump(&$$, &$2);
+ }
+ | boolean_expression "and" boolean_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " and ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | boolean_expression "or" boolean_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " or ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | primary_expression "<" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " < ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | primary_expression ">" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " > ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | primary_expression "<=" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " <= ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | primary_expression ">=" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " >= ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | primary_expression "==" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " == ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | primary_expression "!=" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " != ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | primary_expression
+ {
+ $$ = $1;
+ }
+ | "(" expression ")"
+ {
+ init_dump_with_fixed(&$$, "(");
+ add_dyn_to_dump(&$$, &$2);
+ add_fixed_to_dump(&$$, ")");
+ }
+ ;
+
+
+ for_iteration : for_variables "in" iterator
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " in ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | "of" string_iterator
+ {
+ init_dump_with_fixed(&$$, "of ");
+ add_dyn_to_dump(&$$, &$2);
+ }
+ ;
+
+ for_variables : IDENTIFIER
+ {
+ init_dump(&$$, &$1);
+ }
+ | for_variables "," IDENTIFIER
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, ", ");
+ add_to_dump(&$$, &$3);
+ }
+ ;
+
+
+ iterator : identifier { $$ = $1; }
+ | set { $$ = $1; }
+ ;
+
+
+ set : "(" enumeration ")"
+ {
+ init_dump_with_fixed(&$$, "(");
+ add_dyn_to_dump(&$$, &$2);
+ add_fixed_to_dump(&$$, ")");
+ }
+ | range { $$ = $1; }
+ ;
+
+
+ range : "(" primary_expression ".." primary_expression ")"
+ {
+ init_dump_with_fixed(&$$, "(");
+ add_dyn_to_dump(&$$, &$2);
+ add_fixed_to_dump(&$$, " .. ");
+ add_dyn_to_dump(&$$, &$4);
+ add_fixed_to_dump(&$$, ")");
+ }
+ ;
+
+
+ enumeration : primary_expression { $$ = $1; }
+ | enumeration "," primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, ", ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ ;
+
+
+ string_iterator : string_set { $$ = $1; }
+ ;
+
+ string_set : "(" string_enumeration ")"
+ {
+ init_dump_with_fixed(&$$, "(");
+ add_dyn_to_dump(&$$, &$2);
+ add_fixed_to_dump(&$$, ")");
+ }
+ | "them"
+ {
+ init_dump_with_fixed(&$$, "them");
+ }
+ ;
+
+ string_enumeration : string_enumeration_item
+ {
+ $$ = $1;
+ }
+ | string_enumeration "," string_enumeration_item
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, ", ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ ;
+
+string_enumeration_item : STRING_IDENTIFIER
+ {
+ init_dump(&$$, &$1);
+ }
+ | STRING_IDENTIFIER_WITH_WILDCARD
+ {
+ init_dump(&$$, &$1);
+ }
+ ;
+
+
+ rule_set : "(" rule_enumeration ")"
+ {
+ init_dump_with_fixed(&$$, "(");
+ add_dyn_to_dump(&$$, &$2);
+ add_fixed_to_dump(&$$, ")");
+ }
+ ;
+
+ rule_enumeration : rule_enumeration_item
+ {
+ $$ = $1;
+ }
+ | rule_enumeration "," rule_enumeration_item
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, ", ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ ;
+
+ rule_enumeration_item : IDENTIFIER
+ {
+ init_dump(&$$, &$1);
+ }
+ | IDENTIFIER "*"
+ {
+ init_dump(&$$, &$1);
+ add_fixed_to_dump(&$$, "*");
+ }
+ ;
+
+
+ for_expression : primary_expression { $$ = $1; }
+ | for_quantifier { $$ = $1; }
+ ;
+
+ for_quantifier : "all"
+ {
+ init_dump_with_fixed(&$$, "all");
+ }
+ | "any"
+ {
+ init_dump_with_fixed(&$$, "any");
+ }
+ | "none"
+ {
+ init_dump_with_fixed(&$$, "none");
+ }
+ ;
+
+
+ primary_expression : "(" primary_expression ")"
+ {
+ init_dump_with_fixed(&$$, "(");
+ add_dyn_to_dump(&$$, &$2);
+ add_fixed_to_dump(&$$, ")");
+ }
+ | "filesize"
+ {
+ init_dump_with_fixed(&$$, "datasize");
+ }
+ | "entrypoint"
+ {
+ init_dump_with_fixed(&$$, "/* entrypoint */ 0");
+ }
+ | INTEGER_FUNCTION "(" primary_expression ")"
+ {
+ init_dump(&$$, &$1);
+ add_fixed_to_dump(&$$, "(");
+ add_dyn_to_dump(&$$, &$3);
+ add_fixed_to_dump(&$$, ")");
+ }
+ | NUMBER
+ {
+ init_dump(&$$, &$1);
+ }
+ | DOUBLE
+ {
+ init_dump(&$$, &$1);
+ }
+ | TEXT_STRING
+ {
+ init_dump(&$$, &$1);
+ }
+ | STRING_COUNT "in" range
+ {
+ init_dump(&$$, &$1);
+ add_fixed_to_dump(&$$, " in ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | STRING_COUNT
+ {
+ init_dump(&$$, &$1);
+ }
+ | STRING_OFFSET "[" primary_expression "]"
+ {
+ init_dump(&$$, &$1);
+ add_fixed_to_dump(&$$, "[");
+ add_dyn_to_dump(&$$, &$3);
+ add_fixed_to_dump(&$$, "]");
+ }
+ | STRING_OFFSET
+ {
+ init_dump(&$$, &$1);
+ }
+ | STRING_LENGTH "[" primary_expression "]"
+ {
+ init_dump(&$$, &$1);
+ add_fixed_to_dump(&$$, "[");
+ add_dyn_to_dump(&$$, &$3);
+ add_fixed_to_dump(&$$, "]");
+ }
+ | STRING_LENGTH
+ {
+ init_dump(&$$, &$1);
+ }
+ | identifier
+ {
+ $$ = $1;
+ }
+ | "-" primary_expression %prec UNARY_MINUS
+ {
+ init_dump_with_fixed(&$$, "-");
+ add_dyn_to_dump(&$$, &$2);
+ }
+ | primary_expression "+" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " + ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | primary_expression "-" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " - ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | primary_expression "*" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " * ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | primary_expression "\\" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " \\ ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | primary_expression "%" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " % ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | primary_expression "^" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " ^ ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | primary_expression "&" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " & ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | primary_expression "|" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " | ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | "~" primary_expression
+ {
+ init_dump_with_fixed(&$$, "~");
+ add_dyn_to_dump(&$$, &$2);
+ }
+ | primary_expression "<<" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " << ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | primary_expression ">>" primary_expression
+ {
+ $$ = $1;
+ add_fixed_to_dump(&$$, " >> ");
+ add_dyn_to_dump(&$$, &$3);
+ }
+ | regexp
+ ;
+
+
+ regexp : REGEXP
+ {
+ init_dump_with_fixed(&$$, "/");
+ add_to_dump(&$$, &$1);
+ }
+ ;
+
+
+%%
+
+
+/******************************************************************************
+* *
+* Paramètres : yyscanner = décodeur impliqué dans le processus. *
+* msg = message d'erreur. *
+* *
+* Description : Affiche un message d'erreur suite à l'analyse en échec. *
+* *
+* Retour : 0 *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int yyerror(yyscan_t yyscanner, const char *msg)
+{
+ printf("YYERROR line %d: %s\n", yyget_lineno(yyscanner), msg);
+
+ return 0;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : dst = chaîne de caractères à créer. *
+* src = chaîne de caractères à ajouter. *
+* *
+* Description : Initialise une amorce de copie. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void init_dump(sz_str_t *dst, const sz_cst_str_t *src)
+{
+ dst->data = malloc((src->len + 1) * sizeof(char));
+ dst->len = src->len;
+
+ memcpy(dst->data, src->data, src->len);
+
+ dst->data[dst->len] = '\0';
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : dst = chaîne de caractères à créer. *
+* src = chaîne de caractères à ajouter. *
+* *
+* Description : Complète une chaîne de caractères avec une autre. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void add_to_dump(sz_str_t *dst, const sz_cst_str_t *src)
+{
+ dst->data = realloc(dst->data, (dst->len + src->len + 1) * sizeof(char));
+
+ memcpy(&dst->data[dst->len], src->data, src->len);
+
+ dst->len += src->len;
+
+ dst->data[dst->len] = '\0';
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : string = texte à copier sur la sortie standard. *
+* length = longueur de ce texte. *
+* *
+* Description : Imprime une bribe de définition formant une règle ROST. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void dump_string(const char *string, size_t length)
+{
+ ssize_t ret; /* Bilan de l'appel */
+
+ ret = write(STDOUT_FILENO, string, length);
+
+ if (ret != length)
+ perror("write");
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : text = définitions des règles à charger. *
+* length = longueur de ces définitions. *
+* *
+* Description : Parcourt des définitions de règles pour traduction. *
+* *
+* Retour : Bilan à retourner. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool process_rules_definitions(const char *text, size_t length)
+{
+ bool result; /* Bilan à renvoyer */
+ yyscan_t lexstate; /* Gestion d'analyse lexicale */
+ YY_BUFFER_STATE state; /* Contexte d'analyse */
+ int status; /* Bilan d'une analyse */
+
+ result = false;
+
+ yara2rost_lex_init(&lexstate);
+
+ state = yara2rost__scan_bytes(text, length, lexstate);
+
+ status = yyparse(lexstate);
+
+ result = (status == EXIT_SUCCESS);
+
+ yy_delete_buffer(state, lexstate);
+
+ yara2rost_lex_destroy(lexstate);
+
+ return result;
+
+}