diff options
Diffstat (limited to 'tests/analysis/scan/fuzzing.py')
-rw-r--r-- | tests/analysis/scan/fuzzing.py | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/tests/analysis/scan/fuzzing.py b/tests/analysis/scan/fuzzing.py new file mode 100644 index 0000000..1b9b25b --- /dev/null +++ b/tests/analysis/scan/fuzzing.py @@ -0,0 +1,289 @@ + +from common import RostTestClass +from pychrysalide.analysis.contents import MemoryContent +from pychrysalide.analysis.scan import ContentScanner +from pychrysalide.analysis.scan import ScanOptions +from pychrysalide.analysis.scan.patterns.backends import AcismBackend +from pychrysalide.analysis.scan.patterns.backends import BitapBackend + + +class TestRostFuzzingFixes(RostTestClass): + """TestCases to remember all the fixes for crashes identified by fuzzing.""" + + def testEmptyPatternListWithContent(self): + """Check no backend is run if there is no pattern to look for.""" + + content = MemoryContent(b'\n') + + rule = ''' +''' + + backends = [ + AcismBackend, # This one was segfaulting + BitapBackend, + ] + + for b in backends: + + options = ScanOptions() + options.backend_for_data = b + + scanner = ContentScanner(rule) + ctx = scanner.analyze(options, content) + + self.assertIsNotNone(ctx) + + + def testMandatoryCondition(self): + """Ensure a condition section exists in a rule.""" + + rule = ''' +rule test { + +} +''' + + with self.assertRaisesRegex(ValueError, 'Unable to create content scanner'): + + scanner = ContentScanner(rule) + + + def testNonExistingPattern(self): + """Avoid to count the matches of a non-existing pattern.""" + + rule = ''' +rule test { + + condition: + #badid + +} +''' + + with self.assertRaisesRegex(ValueError, 'Unable to create content scanner'): + + scanner = ContentScanner(rule) + + + def testNamespacesWithoutReductionCode(self): + """Clean the code for ROST namespaces.""" + + rule = ''' +rule test { + + condition: + console + +} +''' + + self.check_rule_failure(rule) + + + def testCallOnNonCallable(self): + """Reject calls on non callable expressions softly.""" + + rule = ''' +rule test { + + condition: + console.log().log() + +} +''' + + self.check_rule_failure(rule) + + + def testSelfReferencingRule(self): + """Reject any rule referencing itself as match condition.""" + + rule = ''' +rule test { + + condition: + test + +} +''' + + self.check_rule_failure(rule) + + + def testSelfReferencingRule(self): + """Expect only one argument for the not operator, even in debug mode.""" + + rule = ''' +rule test { + + condition: + not(0) + +} +''' + + self.check_rule_success(rule) + + + def testNoCommon(self): + """Handle the case where no common item is found from an empty set.""" + + rule = ''' +rule test { + + bytes: + $a = "a" + + condition: + maxcommon($a) == 0 + +} +''' + + self.check_rule_success(rule) + + + def testAAsAcharacter(self): + """Consider the 'a' character as a valid lowercase character.""" + + rule = ''' +rule test { + + bytes: + $a = "0000a0I0" nocase + + condition: + $a + +} +''' + + self.check_rule_failure(rule) + + + def testAAsAcharacter(self): + """Do not expect initialized trackers when there is no real defined search pattern.""" + + rule = ''' +rule test { + + bytes: + $a = {[0]} + + condition: + $a + +} +''' + + with self.assertRaisesRegex(ValueError, 'Unable to create content scanner'): + + scanner = ContentScanner(rule) + + + def testAllocations(self): + """Handle big alloctions for strings in conditions with regular expressions.""" + + rule = ''' +rule test { + + condition: + "%s" == "%s" + +} +''' % ("0" * (256 * 2 + 8), "0" * (256 * 2 + 8)) + + self.check_rule_success(rule) + + + def testFileFinalAccess(self): + """Ensure patterns found at the edges of scanned content do not crash the scanner.""" + + cnt = MemoryContent(bytes([ 0 for i in range(16) ])) + + rule = ''' +rule test { + + bytes: + $a = { 00 00 00 00 00 00 00 00 } + + condition: + $a + +} +''' + + self.check_rule_success(rule, cnt) + + + def testValidHexRangeMerge(self): + """Merge valid hexadecimal ranges.""" + + rule = ''' +rule test { + + bytes: + $a = { [0] ?? } + + condition: + $a + +} +''' + + with self.assertRaisesRegex(ValueError, 'Unable to create content scanner'): + + scanner = ContentScanner(rule) + + + rule = ''' +rule test { + + bytes: + $a = { [2] ?? } + + condition: + $a + +} +''' + + self.check_rule_failure(rule) + + + def testSmallBase64(self): + """Handle small base64 encodings which may produce few patterns.""" + + rule = ''' +rule test { + + bytes: + $a = "0" base64 + + condition: + $a + +} +''' + + self.check_rule_failure(rule) + + + def testCountIndex(self): + """Ban pattern count indexes from the grammer.""" + + rule = ''' +rule test { + + bytes: + $a = "1" + + condition: + #*[0] + +} +''' + + with self.assertRaisesRegex(ValueError, 'Unable to create content scanner'): + + scanner = ContentScanner(rule) |