def test_rule_with_custom_modules(self): cond = yaramod.conjunction([ yaramod.id("module_test.structure_test.function_test")(yaramod.regexp("abc", "")), yaramod.id("cuckoo.sync.mutex")(yaramod.regexp("abc", "")) ]).get() rule = yaramod.YaraRuleBuilder() \ .with_name('test') \ .with_condition(cond)\ .get() yara_file = yaramod.YaraFileBuilder(yaramod.Features.AllCurrent, "./tests/python/testing_modules") \ .with_module("cuckoo") \ .with_module("module_test") \ .with_rule(rule) \ .get(recheck=True) self.assertEqual(yara_file.text_formatted, '''import "cuckoo" import "module_test" rule test { condition: module_test.structure_test.function_test(/abc/) and cuckoo.sync.mutex(/abc/) } ''') self.assertEqual(yara_file.text, '''import "cuckoo" import "module_test" rule test { condition: module_test.structure_test.function_test(/abc/) and cuckoo.sync.mutex(/abc/) }''')
def test_rule_with_function_call_condition(self): cond = yaramod.id('pe').access('is_dll')().comment(message="SOME COMMENT", multiline=True) rule = self.new_rule \ .with_name('rule_with_function_call_condition') \ .with_condition(cond.get()) \ .get() yara_file = self.new_file \ .with_module('pe') \ .with_rule(rule) \ .get() self.assertEqual(yara_file.text_formatted, '''import "pe" rule rule_with_function_call_condition { condition: /* SOME COMMENT */ pe.is_dll() } ''') self.assertEqual(yara_file.text, '''import "pe" rule rule_with_function_call_condition { condition: pe.is_dll() }''')
def test_rule_with_dictionary_access_condition(self): cond = yaramod.id('pe').access('version_info')[yaramod.string_val('CompanyName')] rule = self.new_rule \ .with_name('rule_with_dictionary_access_condition') \ .with_condition(cond.get()) \ .get() yara_file = self.new_file \ .with_module('pe') \ .with_rule(rule) \ .get() self.assertEqual(yara_file.text_formatted, '''import "pe" rule rule_with_dictionary_access_condition { condition: pe.version_info["CompanyName"] } ''') self.assertEqual(yara_file.text, '''import "pe" rule rule_with_dictionary_access_condition { condition: pe.version_info["CompanyName"] }''')
def test_rule_with_array_access_condition(self): cond = yaramod.id('pe').access('sections')[yaramod.int_val(0)].access('name').comment(message="SOME COMMENT") rule = self.new_rule \ .with_name('rule_with_array_access_condition') \ .with_condition(cond.get()) \ .get() yara_file = self.new_file \ .with_module('pe') \ .with_rule(rule) \ .get() self.assertEqual(yara_file.text_formatted, '''import "pe" rule rule_with_array_access_condition { condition: // SOME COMMENT pe.sections[0].name } ''') self.assertEqual(yara_file.text, '''import "pe" rule rule_with_array_access_condition { condition: pe.sections[0].name }''')
def test_rule_with_structure_access_condition(self): cond = yaramod.id('pe').access('linker_version').access('major') rule = self.new_rule \ .with_name('rule_with_structure_access_condition') \ .with_condition(cond.get()) \ .get() yara_file = self.new_file \ .with_module('pe') \ .with_rule(rule) \ .get() self.assertEqual(yara_file.text_formatted, '''import "pe" rule rule_with_structure_access_condition { condition: pe.linker_version.major } ''') self.assertEqual(yara_file.text, '''import "pe" rule rule_with_structure_access_condition { condition: pe.linker_version.major }''')
def test_rule_with_variable_id_condition(self): cond = yaramod.id('time_struct').access('now')() rule = self.new_rule \ .with_name('rule_with_variable_id_condition') \ .with_struct_variable('time_struct', 'time') \ .with_condition(cond.get()) \ .get() yara_file = self.new_file \ .with_module('time') \ .with_rule(rule) \ .get() self.assertEqual(yara_file.text_formatted, '''import "time" rule rule_with_variable_id_condition { variables: time_struct = time condition: time_struct.now() } ''') self.assertEqual(yara_file.text, '''import "time" rule rule_with_variable_id_condition { variables: time_struct = time condition: time_struct.now() }''')
def test_rule_with_complex_condition(self): cond = yaramod.for_loop( yaramod.any(), 'i', yaramod.set( [yaramod.int_val(1), yaramod.int_val(2), yaramod.int_val(3)]), yaramod.match_at( '$1', yaramod.paren(yaramod.entrypoint() + yaramod.id('i')))) rule = self.new_rule \ .with_name('rule_with_complex_condition') \ .with_plain_string('$1', 'This is plaing string.') \ .with_condition(cond.get()) \ .get() yara_file = self.new_file \ .with_rule(rule) \ .get() self.assertEqual( yara_file.text, '''rule rule_with_complex_condition { strings: $1 = "This is plaing string." condition: for any i in (1, 2, 3) : ( $1 at (entrypoint + i) ) }''')
def test_rule_with_function_call_condition(self): cond = yaramod.id('pe').access('is_dll')() rule = self.new_rule \ .with_name('rule_with_function_call_condition') \ .with_condition(cond.get()) \ .get() yara_file = self.new_file \ .with_module('pe') \ .with_rule(rule) \ .get() self.assertEqual(yara_file.text_formatted, '''import "pe" rule rule_with_function_call_condition { condition: pe.is_dll() } ''') self.assertEqual(yara_file.text, '''import "pe" rule rule_with_function_call_condition { condition: pe.is_dll() }''')
def test_rule_with_for_loop_over_dictionary(self): cond = yaramod.for_loop( yaramod.any(), 'k', 'v', yaramod.id('pe').access('version_info'), yaramod.conjunction([ yaramod.id('k') == yaramod.string_val('CompanyName'), yaramod.id('v').contains(yaramod.string_val('Microsoft')) ]) ) rule = self.new_rule \ .with_name('rule_with_for_loop_over_dictionary') \ .with_plain_string('$1', 'This is plain string.') \ .with_condition(cond.get()) \ .get() yara_file = self.new_file \ .with_rule(rule) \ .get() self.assertEqual(yara_file.text_formatted, '''rule rule_with_for_loop_over_dictionary { strings: $1 = "This is plain string." condition: for any k, v in pe.version_info : ( k == "CompanyName" and v contains "Microsoft" ) } ''') self.assertEqual(yara_file.text, '''rule rule_with_for_loop_over_dictionary { strings: $1 = "This is plain string." condition: for any k, v in pe.version_info : ( k == "CompanyName" and v contains "Microsoft" ) }''')
def insert_rule(self, yara_file): rule_cond = yaramod.conjunction( [yaramod.id('first_file'), yaramod.id('second_file')]) another_rule = yaramod.YaraRuleBuilder() \ .with_modifier(yaramod.RuleModifier.Private) \ .with_name('ANOTHER_RULE') \ .with_condition(rule_cond.get()) \ .get() for rule in yara_file.rules: if not rule.is_private: context = yaramod.TokenStreamContext(rule.condition) output = yaramod.conjunction([ yaramod.id(another_rule.name), yaramod.paren(yaramod.YaraExpressionBuilder( rule.condition), linebreaks=True) ]).get() self.cleanup_tokenstreams(context, output) rule.condition = output yara_file.insert_rule(0, another_rule)
def test_rule_with_pe_int_constants_condition(self): constans = [ 'MACHINE_TARGET_HOST', 'MACHINE_R3000', 'MACHINE_R10000', 'MACHINE_ALPHA', 'MACHINE_SH3E', 'MACHINE_AXP64', 'MACHINE_ALPHA64', 'MACHINE_TRICORE', 'MACHINE_CEF', 'MACHINE_CEE', 'SUBSYSTEM_EFI_ROM_IMAGE', 'HIGH_ENTROPY_VA', 'APPCONTAINER', 'GUARD_CF', 'IMAGE_DIRECTORY_ENTRY_COPYRIGHT', 'IMAGE_NT_OPTIONAL_HDR32_MAGIC', 'IMAGE_NT_OPTIONAL_HDR64_MAGIC', 'IMAGE_ROM_OPTIONAL_HDR_MAGIC', 'SECTION_NO_PAD', 'SECTION_LNK_OTHER', 'SECTION_LNK_INFO', 'SECTION_LNK_REMOVE', 'SECTION_LNK_COMDAT', 'SECTION_NO_DEFER_SPEC_EXC', 'SECTION_MEM_FARDATA', 'SECTION_MEM_PURGEABLE', 'SECTION_MEM_PURGEABLE', 'SECTION_MEM_LOCKED', 'SECTION_MEM_PRELOAD', 'SECTION_ALIGN_1BYTES', 'SECTION_ALIGN_2BYTES', 'SECTION_ALIGN_4BYTES', 'SECTION_ALIGN_8BYTES', 'SECTION_ALIGN_16BYTES', 'SECTION_ALIGN_32BYTES', 'SECTION_ALIGN_64BYTES', 'SECTION_ALIGN_128BYTES', 'SECTION_ALIGN_256BYTES', 'SECTION_ALIGN_512BYTES', 'SECTION_ALIGN_1024BYTES', 'SECTION_ALIGN_2048BYTES', 'SECTION_ALIGN_4096BYTES', 'SECTION_ALIGN_8192BYTES', 'SECTION_ALIGN_MASK', 'SECTION_SCALE_INDEX', 'IMAGE_DEBUG_TYPE_UNKNOWN', 'IMAGE_DEBUG_TYPE_COFF', 'IMAGE_DEBUG_TYPE_CODEVIEW', 'IMAGE_DEBUG_TYPE_FPO', 'IMAGE_DEBUG_TYPE_MISC', 'IMAGE_DEBUG_TYPE_EXCEPTION', 'IMAGE_DEBUG_TYPE_FIXUP', 'IMAGE_DEBUG_TYPE_OMAP_FROM_SRC', 'IMAGE_DEBUG_TYPE_OMAP_TO_SRC', 'IMAGE_DEBUG_TYPE_BORLAND', 'IMAGE_DEBUG_TYPE_RESERVED10', 'IMAGE_DEBUG_TYPE_CLSID', 'IMAGE_DEBUG_TYPE_VC_FEATURE', 'IMAGE_DEBUG_TYPE_POGO', 'IMAGE_DEBUG_TYPE_ILTCG', 'IMAGE_DEBUG_TYPE_MPX', 'IMAGE_DEBUG_TYPE_REPRO', ] cond = yaramod.id('pe').access(constans[0]) for constant in constans[1:]: cond = cond | yaramod.id('pe').access(constant) rule = ( self.new_rule .with_name('rule_with_constant_condition') .with_condition(cond.get()) .get() ) yara_file = ( self.new_file .with_module("pe") .with_rule(rule) .get(True) ) self.assertEqual( yara_file.text_formatted, 'import "pe"\n' '\n' 'rule rule_with_constant_condition\n' '{\n' '\tcondition:\n' f'\t\t{" | ".join(f"pe.{constant}" for constant in constans)}\n' '}\n' )