diff options
Diffstat (limited to 'tools/yara2rost/grammar.y')
-rw-r--r-- | tools/yara2rost/grammar.y | 1332 |
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; + +} |