diff --git a/capa/capabilities/dynamic.py b/capa/capabilities/dynamic.py index 95aa795d..cb553e30 100644 --- a/capa/capabilities/dynamic.py +++ b/capa/capabilities/dynamic.py @@ -35,6 +35,10 @@ class CallCapabilities: matches: MatchResults +# The number of calls that make up a sequence. +SEQUENCE_SIZE = 5 + + def find_call_capabilities( ruleset: RuleSet, extractor: DynamicFeatureExtractor, ph: ProcessHandle, th: ThreadHandle, ch: CallHandle ) -> CallCapabilities: @@ -64,6 +68,7 @@ def find_call_capabilities( class ThreadCapabilities: features: FeatureSet thread_matches: MatchResults + sequence_matches: MatchResults call_matches: MatchResults @@ -81,6 +86,11 @@ def find_thread_capabilities( # might be found at different calls, that's ok. call_matches: MatchResults = collections.defaultdict(list) + # matches found at the sequence scope. + sequence_matches: MatchResults = collections.defaultdict(list) + + sequence: collections.deque[FeatureSet] = collections.deque(maxlen=SEQUENCE_SIZE) + for ch in extractor.get_calls(ph, th): call_capabilities = find_call_capabilities(ruleset, extractor, ph, th, ch) for feature, vas in call_capabilities.features.items(): @@ -89,6 +99,16 @@ def find_thread_capabilities( for rule_name, res in call_capabilities.matches.items(): call_matches[rule_name].extend(res) + sequence.append(call_capabilities.features) + sequence_features: FeatureSet = collections.defaultdict(set) + for call in sequence: + for feature, vas in call.items(): + sequence_features[feature].update(vas) + + _, smatches = ruleset.match(Scope.SEQUENCE, sequence_features, ch.address) + for rule_name, res in smatches.items(): + sequence_matches[rule_name].extend(res) + for feature, va in itertools.chain(extractor.extract_thread_features(ph, th), extractor.extract_global_features()): features[feature].add(va) @@ -100,7 +120,7 @@ def find_thread_capabilities( for va, _ in res: capa.engine.index_rule_matches(features, rule, [va]) - return ThreadCapabilities(features, matches, call_matches) + return ThreadCapabilities(features, matches, sequence_matches, call_matches) @dataclass @@ -125,6 +145,10 @@ def find_process_capabilities( # might be found at different threads, that's ok. thread_matches: MatchResults = collections.defaultdict(list) + # matches found at the sequence scope. + # might be found at different sequences, that's ok. + sequence_matches: MatchResults = collections.defaultdict(list) + # matches found at the call scope. # might be found at different calls, that's ok. call_matches: MatchResults = collections.defaultdict(list) @@ -137,6 +161,9 @@ def find_process_capabilities( for rule_name, res in thread_capabilities.thread_matches.items(): thread_matches[rule_name].extend(res) + for rule_name, res in thread_capabilities.sequence_matches.items(): + sequence_matches[rule_name].extend(res) + for rule_name, res in thread_capabilities.call_matches.items(): call_matches[rule_name].extend(res) @@ -152,6 +179,7 @@ def find_dynamic_capabilities( ) -> Capabilities: all_process_matches: MatchResults = collections.defaultdict(list) all_thread_matches: MatchResults = collections.defaultdict(list) + all_sequence_matches: MatchResults = collections.defaultdict(list) all_call_matches: MatchResults = collections.defaultdict(list) feature_counts = rdoc.DynamicFeatureCounts(file=0, processes=()) @@ -177,6 +205,8 @@ def find_dynamic_capabilities( all_process_matches[rule_name].extend(res) for rule_name, res in process_capabilities.thread_matches.items(): all_thread_matches[rule_name].extend(res) + for rule_name, res in process_capabilities.sequence_matches.items(): + all_sequence_matches[rule_name].extend(res) for rule_name, res in process_capabilities.call_matches.items(): all_call_matches[rule_name].extend(res) @@ -186,7 +216,7 @@ def find_dynamic_capabilities( # mapping from feature (matched rule) to set of addresses at which it matched. process_and_lower_features: FeatureSet = collections.defaultdict(set) for rule_name, results in itertools.chain( - all_process_matches.items(), all_thread_matches.items(), all_call_matches.items() + all_process_matches.items(), all_thread_matches.items(), all_sequence_matches.items(), all_call_matches.items() ): locations = {p[0] for p in results} rule = ruleset[rule_name] @@ -200,6 +230,8 @@ def find_dynamic_capabilities( # each rule exists in exactly one scope, # so there won't be any overlap among these following MatchResults, # and we can merge the dictionaries naively. + all_call_matches.items(), + all_sequence_matches.items(), all_thread_matches.items(), all_process_matches.items(), all_file_capabilities.matches.items(), diff --git a/capa/features/extractors/base_extractor.py b/capa/features/extractors/base_extractor.py index ba9b905b..35c9b665 100644 --- a/capa/features/extractors/base_extractor.py +++ b/capa/features/extractors/base_extractor.py @@ -504,4 +504,16 @@ def ProcessFilter(extractor: DynamicFeatureExtractor, processes: set) -> Dynamic return new_extractor +def ThreadFilter(extractor: DynamicFeatureExtractor, threads: set) -> DynamicFeatureExtractor: + original_get_threads = extractor.get_threads + + def filtered_get_threads(self, ph: ProcessHandle): + yield from (t for t in original_get_threads(ph) if t.address in threads) + + new_extractor = copy(extractor) + new_extractor.get_threads = MethodType(filtered_get_threads, extractor) # type: ignore + + return new_extractor + + FeatureExtractor: TypeAlias = Union[StaticFeatureExtractor, DynamicFeatureExtractor] diff --git a/capa/render/proto/__init__.py b/capa/render/proto/__init__.py index e72add4d..2541c944 100644 --- a/capa/render/proto/__init__.py +++ b/capa/render/proto/__init__.py @@ -163,6 +163,8 @@ def scope_to_pb2(scope: capa.rules.Scope) -> capa_pb2.Scope.ValueType: return capa_pb2.Scope.SCOPE_PROCESS elif scope == capa.rules.Scope.THREAD: return capa_pb2.Scope.SCOPE_THREAD + elif scope == capa.rules.Scope.SEQUENCE: + return capa_pb2.Scope.SCOPE_SEQUENCE elif scope == capa.rules.Scope.CALL: return capa_pb2.Scope.SCOPE_CALL else: @@ -655,6 +657,8 @@ def scope_from_pb2(scope: capa_pb2.Scope.ValueType) -> capa.rules.Scope: return capa.rules.Scope.PROCESS elif scope == capa_pb2.Scope.SCOPE_THREAD: return capa.rules.Scope.THREAD + elif scope == capa_pb2.Scope.SCOPE_SEQUENCE: + return capa.rules.Scope.SEQUENCE elif scope == capa_pb2.Scope.SCOPE_CALL: return capa.rules.Scope.CALL else: diff --git a/capa/render/proto/capa.proto b/capa/render/proto/capa.proto index 2c0964c7..e824c42e 100644 --- a/capa/render/proto/capa.proto +++ b/capa/render/proto/capa.proto @@ -378,6 +378,7 @@ enum Scope { SCOPE_PROCESS = 5; SCOPE_THREAD = 6; SCOPE_CALL = 7; + SCOPE_SEQUENCE = 8; } message Scopes { diff --git a/capa/render/proto/capa_pb2.py b/capa/render/proto/capa_pb2.py index 8b55fed4..35d01793 100644 --- a/capa/render/proto/capa_pb2.py +++ b/capa/render/proto/capa_pb2.py @@ -2,10 +2,10 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: capa/render/proto/capa.proto """Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -13,159 +13,159 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1c\x63\x61pa/render/proto/capa.proto\x12\rmandiant.capa\"Q\n\nAPIFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0b\n\x03\x61pi\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\xb3\x02\n\x07\x41\x64\x64ress\x12(\n\x04type\x18\x01 \x01(\x0e\x32\x1a.mandiant.capa.AddressType\x12#\n\x01v\x18\x02 \x01(\x0b\x32\x16.mandiant.capa.IntegerH\x00\x12\x33\n\x0ctoken_offset\x18\x03 \x01(\x0b\x32\x1b.mandiant.capa.Token_OffsetH\x00\x12+\n\x08ppid_pid\x18\x04 \x01(\x0b\x32\x17.mandiant.capa.Ppid_PidH\x00\x12\x33\n\x0cppid_pid_tid\x18\x05 \x01(\x0b\x32\x1b.mandiant.capa.Ppid_Pid_TidH\x00\x12\x39\n\x0fppid_pid_tid_id\x18\x06 \x01(\x0b\x32\x1e.mandiant.capa.Ppid_Pid_Tid_IdH\x00\x42\x07\n\x05value\"\x9c\x02\n\x08\x41nalysis\x12\x0e\n\x06\x66ormat\x18\x01 \x01(\t\x12\x0c\n\x04\x61rch\x18\x02 \x01(\t\x12\n\n\x02os\x18\x03 \x01(\t\x12\x11\n\textractor\x18\x04 \x01(\t\x12\r\n\x05rules\x18\x05 \x03(\t\x12,\n\x0c\x62\x61se_address\x18\x06 \x01(\x0b\x32\x16.mandiant.capa.Address\x12%\n\x06layout\x18\x07 \x01(\x0b\x32\x15.mandiant.capa.Layout\x12\x34\n\x0e\x66\x65\x61ture_counts\x18\x08 \x01(\x0b\x32\x1c.mandiant.capa.FeatureCounts\x12\x39\n\x11library_functions\x18\t \x03(\x0b\x32\x1e.mandiant.capa.LibraryFunction\"S\n\x0b\x41rchFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0c\n\x04\x61rch\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"`\n\nAttackSpec\x12\r\n\x05parts\x18\x01 \x03(\t\x12\x0e\n\x06tactic\x18\x02 \x01(\t\x12\x11\n\ttechnique\x18\x03 \x01(\t\x12\x14\n\x0csubtechnique\x18\x04 \x01(\t\x12\n\n\x02id\x18\x05 \x01(\t\"K\n\x11\x42\x61sicBlockFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\";\n\x10\x42\x61sicBlockLayout\x12\'\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Address\"U\n\x0c\x42ytesFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\r\n\x05\x62ytes\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"g\n\x15\x43haracteristicFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x16\n\x0e\x63haracteristic\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"V\n\x0c\x43lassFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0e\n\x06\x63lass_\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"K\n\x11\x43ompoundStatement\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\xc8\x01\n\x0f\x44ynamicAnalysis\x12\x0e\n\x06\x66ormat\x18\x01 \x01(\t\x12\x0c\n\x04\x61rch\x18\x02 \x01(\t\x12\n\n\x02os\x18\x03 \x01(\t\x12\x11\n\textractor\x18\x04 \x01(\t\x12\r\n\x05rules\x18\x05 \x03(\t\x12,\n\x06layout\x18\x06 \x01(\x0b\x32\x1c.mandiant.capa.DynamicLayout\x12;\n\x0e\x66\x65\x61ture_counts\x18\x07 \x01(\x0b\x32#.mandiant.capa.DynamicFeatureCounts\"[\n\x14\x44ynamicFeatureCounts\x12\x0c\n\x04\x66ile\x18\x01 \x01(\x04\x12\x35\n\tprocesses\x18\x02 \x03(\x0b\x32\".mandiant.capa.ProcessFeatureCount\"@\n\rDynamicLayout\x12/\n\tprocesses\x18\x01 \x03(\x0b\x32\x1c.mandiant.capa.ProcessLayout\"W\n\rExportFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0e\n\x06\x65xport\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"U\n\rFeatureCounts\x12\x0c\n\x04\x66ile\x18\x01 \x01(\x04\x12\x36\n\tfunctions\x18\x02 \x03(\x0b\x32#.mandiant.capa.FunctionFeatureCount\"\xb9\t\n\x0b\x46\x65\x61tureNode\x12\x0c\n\x04type\x18\x01 \x01(\t\x12&\n\x02os\x18\x02 \x01(\x0b\x32\x18.mandiant.capa.OSFeatureH\x00\x12*\n\x04\x61rch\x18\x03 \x01(\x0b\x32\x1a.mandiant.capa.ArchFeatureH\x00\x12.\n\x06\x66ormat\x18\x04 \x01(\x0b\x32\x1c.mandiant.capa.FormatFeatureH\x00\x12,\n\x05match\x18\x05 \x01(\x0b\x32\x1b.mandiant.capa.MatchFeatureH\x00\x12>\n\x0e\x63haracteristic\x18\x06 \x01(\x0b\x32$.mandiant.capa.CharacteristicFeatureH\x00\x12.\n\x06\x65xport\x18\x07 \x01(\x0b\x32\x1c.mandiant.capa.ExportFeatureH\x00\x12/\n\x07import_\x18\x08 \x01(\x0b\x32\x1c.mandiant.capa.ImportFeatureH\x00\x12\x30\n\x07section\x18\t \x01(\x0b\x32\x1d.mandiant.capa.SectionFeatureH\x00\x12;\n\rfunction_name\x18\n \x01(\x0b\x32\".mandiant.capa.FunctionNameFeatureH\x00\x12\x34\n\tsubstring\x18\x0b \x01(\x0b\x32\x1f.mandiant.capa.SubstringFeatureH\x00\x12,\n\x05regex\x18\x0c \x01(\x0b\x32\x1b.mandiant.capa.RegexFeatureH\x00\x12.\n\x06string\x18\r \x01(\x0b\x32\x1c.mandiant.capa.StringFeatureH\x00\x12-\n\x06\x63lass_\x18\x0e \x01(\x0b\x32\x1b.mandiant.capa.ClassFeatureH\x00\x12\x34\n\tnamespace\x18\x0f \x01(\x0b\x32\x1f.mandiant.capa.NamespaceFeatureH\x00\x12(\n\x03\x61pi\x18\x10 \x01(\x0b\x32\x19.mandiant.capa.APIFeatureH\x00\x12\x33\n\tproperty_\x18\x11 \x01(\x0b\x32\x1e.mandiant.capa.PropertyFeatureH\x00\x12.\n\x06number\x18\x12 \x01(\x0b\x32\x1c.mandiant.capa.NumberFeatureH\x00\x12,\n\x05\x62ytes\x18\x13 \x01(\x0b\x32\x1b.mandiant.capa.BytesFeatureH\x00\x12.\n\x06offset\x18\x14 \x01(\x0b\x32\x1c.mandiant.capa.OffsetFeatureH\x00\x12\x32\n\x08mnemonic\x18\x15 \x01(\x0b\x32\x1e.mandiant.capa.MnemonicFeatureH\x00\x12=\n\x0eoperand_number\x18\x16 \x01(\x0b\x32#.mandiant.capa.OperandNumberFeatureH\x00\x12=\n\x0eoperand_offset\x18\x17 \x01(\x0b\x32#.mandiant.capa.OperandOffsetFeatureH\x00\x12\x37\n\x0b\x62\x61sic_block\x18\x18 \x01(\x0b\x32 .mandiant.capa.BasicBlockFeatureH\x00\x42\t\n\x07\x66\x65\x61ture\"W\n\rFormatFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0e\n\x06\x66ormat\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"N\n\x14\x46unctionFeatureCount\x12\'\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Address\x12\r\n\x05\x63ount\x18\x02 \x01(\x04\"x\n\x0e\x46unctionLayout\x12\'\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Address\x12=\n\x14matched_basic_blocks\x18\x02 \x03(\x0b\x32\x1f.mandiant.capa.BasicBlockLayout\"d\n\x13\x46unctionNameFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x15\n\rfunction_name\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"X\n\rImportFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0f\n\x07import_\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\":\n\x06Layout\x12\x30\n\tfunctions\x18\x01 \x03(\x0b\x32\x1d.mandiant.capa.FunctionLayout\"H\n\x0fLibraryFunction\x12\'\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Address\x12\x0c\n\x04name\x18\x02 \x01(\t\"Y\n\x07MBCSpec\x12\r\n\x05parts\x18\x01 \x03(\t\x12\x11\n\tobjective\x18\x02 \x01(\t\x12\x10\n\x08\x62\x65havior\x18\x03 \x01(\t\x12\x0e\n\x06method\x18\x04 \x01(\t\x12\n\n\x02id\x18\x05 \x01(\t\"\x9a\x01\n\x0cMaecMetadata\x12\x1b\n\x13\x61nalysis_conclusion\x18\x01 \x01(\t\x12\x1e\n\x16\x61nalysis_conclusion_ov\x18\x02 \x01(\t\x12\x16\n\x0emalware_family\x18\x03 \x01(\t\x12\x18\n\x10malware_category\x18\x04 \x01(\t\x12\x1b\n\x13malware_category_ov\x18\x05 \x01(\t\"\xd6\x02\n\x05Match\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x31\n\tstatement\x18\x02 \x01(\x0b\x32\x1c.mandiant.capa.StatementNodeH\x00\x12-\n\x07\x66\x65\x61ture\x18\x03 \x01(\x0b\x32\x1a.mandiant.capa.FeatureNodeH\x00\x12&\n\x08\x63hildren\x18\x05 \x03(\x0b\x32\x14.mandiant.capa.Match\x12)\n\tlocations\x18\x06 \x03(\x0b\x32\x16.mandiant.capa.Address\x12\x34\n\x08\x63\x61ptures\x18\x07 \x03(\x0b\x32\".mandiant.capa.Match.CapturesEntry\x1aI\n\rCapturesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\'\n\x05value\x18\x02 \x01(\x0b\x32\x18.mandiant.capa.Addresses:\x02\x38\x01\x42\x06\n\x04node\"U\n\x0cMatchFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\r\n\x05match\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\xbc\x02\n\x08Metadata\x12\x11\n\ttimestamp\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\t\x12\x0c\n\x04\x61rgv\x18\x03 \x03(\t\x12%\n\x06sample\x18\x04 \x01(\x0b\x32\x15.mandiant.capa.Sample\x12-\n\x08\x61nalysis\x18\x05 \x01(\x0b\x32\x17.mandiant.capa.AnalysisB\x02\x18\x01\x12%\n\x06\x66lavor\x18\x06 \x01(\x0e\x32\x15.mandiant.capa.Flavor\x12\x38\n\x0fstatic_analysis\x18\x07 \x01(\x0b\x32\x1d.mandiant.capa.StaticAnalysisH\x00\x12:\n\x10\x64ynamic_analysis\x18\x08 \x01(\x0b\x32\x1e.mandiant.capa.DynamicAnalysisH\x00\x42\x0b\n\tanalysis2\"[\n\x0fMnemonicFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x10\n\x08mnemonic\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"]\n\x10NamespaceFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x11\n\tnamespace\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"n\n\rNumberFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12%\n\x06number\x18\x02 \x01(\x0b\x32\x15.mandiant.capa.Number\x12\x18\n\x0b\x64\x65scription\x18\x05 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"O\n\tOSFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\n\n\x02os\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"o\n\rOffsetFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12&\n\x06offset\x18\x02 \x01(\x0b\x32\x16.mandiant.capa.Integer\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\x8d\x01\n\x14OperandNumberFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\r\n\x05index\x18\x02 \x01(\r\x12.\n\x0eoperand_number\x18\x03 \x01(\x0b\x32\x16.mandiant.capa.Integer\x12\x18\n\x0b\x64\x65scription\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\x8d\x01\n\x14OperandOffsetFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\r\n\x05index\x18\x02 \x01(\r\x12.\n\x0eoperand_offset\x18\x03 \x01(\x0b\x32\x16.mandiant.capa.Integer\x12\x18\n\x0b\x64\x65scription\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"M\n\x13ProcessFeatureCount\x12\'\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Address\x12\r\n\x05\x63ount\x18\x02 \x01(\x04\"|\n\rProcessLayout\x12\'\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Address\x12\x34\n\x0fmatched_threads\x18\x02 \x03(\x0b\x32\x1b.mandiant.capa.ThreadLayout\x12\x0c\n\x04name\x18\x03 \x01(\t\"|\n\x0fPropertyFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x11\n\tproperty_\x18\x02 \x01(\t\x12\x13\n\x06\x61\x63\x63\x65ss\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x04 \x01(\tH\x01\x88\x01\x01\x42\t\n\x07_accessB\x0e\n\x0c_description\"\x8d\x01\n\x0eRangeStatement\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0b\n\x03min\x18\x02 \x01(\x04\x12\x0b\n\x03max\x18\x03 \x01(\x04\x12)\n\x05\x63hild\x18\x04 \x01(\x0b\x32\x1a.mandiant.capa.FeatureNode\x12\x18\n\x0b\x64\x65scription\x18\x05 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"U\n\x0cRegexFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\r\n\x05regex\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\xba\x01\n\x0eResultDocument\x12%\n\x04meta\x18\x01 \x01(\x0b\x32\x17.mandiant.capa.Metadata\x12\x37\n\x05rules\x18\x02 \x03(\x0b\x32(.mandiant.capa.ResultDocument.RulesEntry\x1aH\n\nRulesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12)\n\x05value\x18\x02 \x01(\x0b\x32\x1a.mandiant.capa.RuleMatches:\x02\x38\x01\"|\n\x0bRuleMatches\x12)\n\x04meta\x18\x01 \x01(\x0b\x32\x1b.mandiant.capa.RuleMetadata\x12\x0e\n\x06source\x18\x02 \x01(\t\x12\x32\n\x07matches\x18\x03 \x03(\x0b\x32!.mandiant.capa.Pair_Address_Match\"\xed\x02\n\x0cRuleMetadata\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\tnamespace\x18\x02 \x01(\t\x12\x0f\n\x07\x61uthors\x18\x03 \x03(\t\x12\'\n\x05scope\x18\x04 \x01(\x0e\x32\x14.mandiant.capa.ScopeB\x02\x18\x01\x12)\n\x06\x61ttack\x18\x05 \x03(\x0b\x32\x19.mandiant.capa.AttackSpec\x12#\n\x03mbc\x18\x06 \x03(\x0b\x32\x16.mandiant.capa.MBCSpec\x12\x12\n\nreferences\x18\x07 \x03(\t\x12\x10\n\x08\x65xamples\x18\x08 \x03(\t\x12\x13\n\x0b\x64\x65scription\x18\t \x01(\t\x12\x0b\n\x03lib\x18\n \x01(\x08\x12)\n\x04maec\x18\x0b \x01(\x0b\x32\x1b.mandiant.capa.MaecMetadata\x12\x18\n\x10is_subscope_rule\x18\x0c \x01(\x08\x12%\n\x06scopes\x18\r \x01(\x0b\x32\x15.mandiant.capa.Scopes\"A\n\x06Sample\x12\x0b\n\x03md5\x18\x01 \x01(\t\x12\x0c\n\x04sha1\x18\x02 \x01(\t\x12\x0e\n\x06sha256\x18\x03 \x01(\t\x12\x0c\n\x04path\x18\x04 \x01(\t\"v\n\x06Scopes\x12)\n\x06static\x18\x01 \x01(\x0e\x32\x14.mandiant.capa.ScopeH\x00\x88\x01\x01\x12*\n\x07\x64ynamic\x18\x02 \x01(\x0e\x32\x14.mandiant.capa.ScopeH\x01\x88\x01\x01\x42\t\n\x07_staticB\n\n\x08_dynamic\"Y\n\x0eSectionFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0f\n\x07section\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"V\n\rSomeStatement\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\r\n\x05\x63ount\x18\x02 \x01(\r\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\xf4\x01\n\rStatementNode\x12\x0c\n\x04type\x18\x01 \x01(\t\x12.\n\x05range\x18\x02 \x01(\x0b\x32\x1d.mandiant.capa.RangeStatementH\x00\x12,\n\x04some\x18\x03 \x01(\x0b\x32\x1c.mandiant.capa.SomeStatementH\x00\x12\x34\n\x08subscope\x18\x04 \x01(\x0b\x32 .mandiant.capa.SubscopeStatementH\x00\x12\x34\n\x08\x63ompound\x18\x05 \x01(\x0b\x32 .mandiant.capa.CompoundStatementH\x00\x42\x0b\n\tstatement\"\xae\x02\n\x0eStaticAnalysis\x12\x0e\n\x06\x66ormat\x18\x01 \x01(\t\x12\x0c\n\x04\x61rch\x18\x02 \x01(\t\x12\n\n\x02os\x18\x03 \x01(\t\x12\x11\n\textractor\x18\x04 \x01(\t\x12\r\n\x05rules\x18\x05 \x03(\t\x12,\n\x0c\x62\x61se_address\x18\x06 \x01(\x0b\x32\x16.mandiant.capa.Address\x12+\n\x06layout\x18\x07 \x01(\x0b\x32\x1b.mandiant.capa.StaticLayout\x12:\n\x0e\x66\x65\x61ture_counts\x18\x08 \x01(\x0b\x32\".mandiant.capa.StaticFeatureCounts\x12\x39\n\x11library_functions\x18\t \x03(\x0b\x32\x1e.mandiant.capa.LibraryFunction\"[\n\x13StaticFeatureCounts\x12\x0c\n\x04\x66ile\x18\x01 \x01(\x04\x12\x36\n\tfunctions\x18\x02 \x03(\x0b\x32#.mandiant.capa.FunctionFeatureCount\"@\n\x0cStaticLayout\x12\x30\n\tfunctions\x18\x01 \x03(\x0b\x32\x1d.mandiant.capa.FunctionLayout\"W\n\rStringFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0e\n\x06string\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"p\n\x11SubscopeStatement\x12\x0c\n\x04type\x18\x01 \x01(\t\x12#\n\x05scope\x18\x02 \x01(\x0e\x32\x14.mandiant.capa.Scope\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"]\n\x10SubstringFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x11\n\tsubstring\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"C\n\nCallLayout\x12\'\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Address\x12\x0c\n\x04name\x18\x02 \x01(\t\"i\n\x0cThreadLayout\x12\'\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Address\x12\x30\n\rmatched_calls\x18\x02 \x03(\x0b\x32\x19.mandiant.capa.CallLayout\"4\n\tAddresses\x12\'\n\x07\x61\x64\x64ress\x18\x01 \x03(\x0b\x32\x16.mandiant.capa.Address\"b\n\x12Pair_Address_Match\x12\'\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Address\x12#\n\x05match\x18\x02 \x01(\x0b\x32\x14.mandiant.capa.Match\"E\n\x0cToken_Offset\x12%\n\x05token\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Integer\x12\x0e\n\x06offset\x18\x02 \x01(\x04\"U\n\x08Ppid_Pid\x12$\n\x04ppid\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Integer\x12#\n\x03pid\x18\x02 \x01(\x0b\x32\x16.mandiant.capa.Integer\"~\n\x0cPpid_Pid_Tid\x12$\n\x04ppid\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Integer\x12#\n\x03pid\x18\x02 \x01(\x0b\x32\x16.mandiant.capa.Integer\x12#\n\x03tid\x18\x03 \x01(\x0b\x32\x16.mandiant.capa.Integer\"\xa5\x01\n\x0fPpid_Pid_Tid_Id\x12$\n\x04ppid\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Integer\x12#\n\x03pid\x18\x02 \x01(\x0b\x32\x16.mandiant.capa.Integer\x12#\n\x03tid\x18\x03 \x01(\x0b\x32\x16.mandiant.capa.Integer\x12\"\n\x02id\x18\x04 \x01(\x0b\x32\x16.mandiant.capa.Integer\",\n\x07Integer\x12\x0b\n\x01u\x18\x01 \x01(\x04H\x00\x12\x0b\n\x01i\x18\x02 \x01(\x12H\x00\x42\x07\n\x05value\"8\n\x06Number\x12\x0b\n\x01u\x18\x01 \x01(\x04H\x00\x12\x0b\n\x01i\x18\x02 \x01(\x12H\x00\x12\x0b\n\x01\x66\x18\x03 \x01(\x01H\x00\x42\x07\n\x05value*\x92\x02\n\x0b\x41\x64\x64ressType\x12\x1b\n\x17\x41\x44\x44RESSTYPE_UNSPECIFIED\x10\x00\x12\x18\n\x14\x41\x44\x44RESSTYPE_ABSOLUTE\x10\x01\x12\x18\n\x14\x41\x44\x44RESSTYPE_RELATIVE\x10\x02\x12\x14\n\x10\x41\x44\x44RESSTYPE_FILE\x10\x03\x12\x18\n\x14\x41\x44\x44RESSTYPE_DN_TOKEN\x10\x04\x12\x1f\n\x1b\x41\x44\x44RESSTYPE_DN_TOKEN_OFFSET\x10\x05\x12\x1a\n\x16\x41\x44\x44RESSTYPE_NO_ADDRESS\x10\x06\x12\x17\n\x13\x41\x44\x44RESSTYPE_PROCESS\x10\x07\x12\x16\n\x12\x41\x44\x44RESSTYPE_THREAD\x10\x08\x12\x14\n\x10\x41\x44\x44RESSTYPE_CALL\x10\t*G\n\x06\x46lavor\x12\x16\n\x12\x46LAVOR_UNSPECIFIED\x10\x00\x12\x11\n\rFLAVOR_STATIC\x10\x01\x12\x12\n\x0e\x46LAVOR_DYNAMIC\x10\x02*\xa5\x01\n\x05Scope\x12\x15\n\x11SCOPE_UNSPECIFIED\x10\x00\x12\x0e\n\nSCOPE_FILE\x10\x01\x12\x12\n\x0eSCOPE_FUNCTION\x10\x02\x12\x15\n\x11SCOPE_BASIC_BLOCK\x10\x03\x12\x15\n\x11SCOPE_INSTRUCTION\x10\x04\x12\x11\n\rSCOPE_PROCESS\x10\x05\x12\x10\n\x0cSCOPE_THREAD\x10\x06\x12\x0e\n\nSCOPE_CALL\x10\x07\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1c\x63\x61pa/render/proto/capa.proto\x12\rmandiant.capa\"Q\n\nAPIFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0b\n\x03\x61pi\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\xb3\x02\n\x07\x41\x64\x64ress\x12(\n\x04type\x18\x01 \x01(\x0e\x32\x1a.mandiant.capa.AddressType\x12#\n\x01v\x18\x02 \x01(\x0b\x32\x16.mandiant.capa.IntegerH\x00\x12\x33\n\x0ctoken_offset\x18\x03 \x01(\x0b\x32\x1b.mandiant.capa.Token_OffsetH\x00\x12+\n\x08ppid_pid\x18\x04 \x01(\x0b\x32\x17.mandiant.capa.Ppid_PidH\x00\x12\x33\n\x0cppid_pid_tid\x18\x05 \x01(\x0b\x32\x1b.mandiant.capa.Ppid_Pid_TidH\x00\x12\x39\n\x0fppid_pid_tid_id\x18\x06 \x01(\x0b\x32\x1e.mandiant.capa.Ppid_Pid_Tid_IdH\x00\x42\x07\n\x05value\"\x9c\x02\n\x08\x41nalysis\x12\x0e\n\x06\x66ormat\x18\x01 \x01(\t\x12\x0c\n\x04\x61rch\x18\x02 \x01(\t\x12\n\n\x02os\x18\x03 \x01(\t\x12\x11\n\textractor\x18\x04 \x01(\t\x12\r\n\x05rules\x18\x05 \x03(\t\x12,\n\x0c\x62\x61se_address\x18\x06 \x01(\x0b\x32\x16.mandiant.capa.Address\x12%\n\x06layout\x18\x07 \x01(\x0b\x32\x15.mandiant.capa.Layout\x12\x34\n\x0e\x66\x65\x61ture_counts\x18\x08 \x01(\x0b\x32\x1c.mandiant.capa.FeatureCounts\x12\x39\n\x11library_functions\x18\t \x03(\x0b\x32\x1e.mandiant.capa.LibraryFunction\"S\n\x0b\x41rchFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0c\n\x04\x61rch\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"`\n\nAttackSpec\x12\r\n\x05parts\x18\x01 \x03(\t\x12\x0e\n\x06tactic\x18\x02 \x01(\t\x12\x11\n\ttechnique\x18\x03 \x01(\t\x12\x14\n\x0csubtechnique\x18\x04 \x01(\t\x12\n\n\x02id\x18\x05 \x01(\t\"K\n\x11\x42\x61sicBlockFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\";\n\x10\x42\x61sicBlockLayout\x12\'\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Address\"U\n\x0c\x42ytesFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\r\n\x05\x62ytes\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"g\n\x15\x43haracteristicFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x16\n\x0e\x63haracteristic\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"V\n\x0c\x43lassFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0e\n\x06\x63lass_\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"K\n\x11\x43ompoundStatement\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\xc8\x01\n\x0f\x44ynamicAnalysis\x12\x0e\n\x06\x66ormat\x18\x01 \x01(\t\x12\x0c\n\x04\x61rch\x18\x02 \x01(\t\x12\n\n\x02os\x18\x03 \x01(\t\x12\x11\n\textractor\x18\x04 \x01(\t\x12\r\n\x05rules\x18\x05 \x03(\t\x12,\n\x06layout\x18\x06 \x01(\x0b\x32\x1c.mandiant.capa.DynamicLayout\x12;\n\x0e\x66\x65\x61ture_counts\x18\x07 \x01(\x0b\x32#.mandiant.capa.DynamicFeatureCounts\"[\n\x14\x44ynamicFeatureCounts\x12\x0c\n\x04\x66ile\x18\x01 \x01(\x04\x12\x35\n\tprocesses\x18\x02 \x03(\x0b\x32\".mandiant.capa.ProcessFeatureCount\"@\n\rDynamicLayout\x12/\n\tprocesses\x18\x01 \x03(\x0b\x32\x1c.mandiant.capa.ProcessLayout\"W\n\rExportFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0e\n\x06\x65xport\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"U\n\rFeatureCounts\x12\x0c\n\x04\x66ile\x18\x01 \x01(\x04\x12\x36\n\tfunctions\x18\x02 \x03(\x0b\x32#.mandiant.capa.FunctionFeatureCount\"\xb9\t\n\x0b\x46\x65\x61tureNode\x12\x0c\n\x04type\x18\x01 \x01(\t\x12&\n\x02os\x18\x02 \x01(\x0b\x32\x18.mandiant.capa.OSFeatureH\x00\x12*\n\x04\x61rch\x18\x03 \x01(\x0b\x32\x1a.mandiant.capa.ArchFeatureH\x00\x12.\n\x06\x66ormat\x18\x04 \x01(\x0b\x32\x1c.mandiant.capa.FormatFeatureH\x00\x12,\n\x05match\x18\x05 \x01(\x0b\x32\x1b.mandiant.capa.MatchFeatureH\x00\x12>\n\x0e\x63haracteristic\x18\x06 \x01(\x0b\x32$.mandiant.capa.CharacteristicFeatureH\x00\x12.\n\x06\x65xport\x18\x07 \x01(\x0b\x32\x1c.mandiant.capa.ExportFeatureH\x00\x12/\n\x07import_\x18\x08 \x01(\x0b\x32\x1c.mandiant.capa.ImportFeatureH\x00\x12\x30\n\x07section\x18\t \x01(\x0b\x32\x1d.mandiant.capa.SectionFeatureH\x00\x12;\n\rfunction_name\x18\n \x01(\x0b\x32\".mandiant.capa.FunctionNameFeatureH\x00\x12\x34\n\tsubstring\x18\x0b \x01(\x0b\x32\x1f.mandiant.capa.SubstringFeatureH\x00\x12,\n\x05regex\x18\x0c \x01(\x0b\x32\x1b.mandiant.capa.RegexFeatureH\x00\x12.\n\x06string\x18\r \x01(\x0b\x32\x1c.mandiant.capa.StringFeatureH\x00\x12-\n\x06\x63lass_\x18\x0e \x01(\x0b\x32\x1b.mandiant.capa.ClassFeatureH\x00\x12\x34\n\tnamespace\x18\x0f \x01(\x0b\x32\x1f.mandiant.capa.NamespaceFeatureH\x00\x12(\n\x03\x61pi\x18\x10 \x01(\x0b\x32\x19.mandiant.capa.APIFeatureH\x00\x12\x33\n\tproperty_\x18\x11 \x01(\x0b\x32\x1e.mandiant.capa.PropertyFeatureH\x00\x12.\n\x06number\x18\x12 \x01(\x0b\x32\x1c.mandiant.capa.NumberFeatureH\x00\x12,\n\x05\x62ytes\x18\x13 \x01(\x0b\x32\x1b.mandiant.capa.BytesFeatureH\x00\x12.\n\x06offset\x18\x14 \x01(\x0b\x32\x1c.mandiant.capa.OffsetFeatureH\x00\x12\x32\n\x08mnemonic\x18\x15 \x01(\x0b\x32\x1e.mandiant.capa.MnemonicFeatureH\x00\x12=\n\x0eoperand_number\x18\x16 \x01(\x0b\x32#.mandiant.capa.OperandNumberFeatureH\x00\x12=\n\x0eoperand_offset\x18\x17 \x01(\x0b\x32#.mandiant.capa.OperandOffsetFeatureH\x00\x12\x37\n\x0b\x62\x61sic_block\x18\x18 \x01(\x0b\x32 .mandiant.capa.BasicBlockFeatureH\x00\x42\t\n\x07\x66\x65\x61ture\"W\n\rFormatFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0e\n\x06\x66ormat\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"N\n\x14\x46unctionFeatureCount\x12\'\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Address\x12\r\n\x05\x63ount\x18\x02 \x01(\x04\"x\n\x0e\x46unctionLayout\x12\'\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Address\x12=\n\x14matched_basic_blocks\x18\x02 \x03(\x0b\x32\x1f.mandiant.capa.BasicBlockLayout\"d\n\x13\x46unctionNameFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x15\n\rfunction_name\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"X\n\rImportFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0f\n\x07import_\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\":\n\x06Layout\x12\x30\n\tfunctions\x18\x01 \x03(\x0b\x32\x1d.mandiant.capa.FunctionLayout\"H\n\x0fLibraryFunction\x12\'\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Address\x12\x0c\n\x04name\x18\x02 \x01(\t\"Y\n\x07MBCSpec\x12\r\n\x05parts\x18\x01 \x03(\t\x12\x11\n\tobjective\x18\x02 \x01(\t\x12\x10\n\x08\x62\x65havior\x18\x03 \x01(\t\x12\x0e\n\x06method\x18\x04 \x01(\t\x12\n\n\x02id\x18\x05 \x01(\t\"\x9a\x01\n\x0cMaecMetadata\x12\x1b\n\x13\x61nalysis_conclusion\x18\x01 \x01(\t\x12\x1e\n\x16\x61nalysis_conclusion_ov\x18\x02 \x01(\t\x12\x16\n\x0emalware_family\x18\x03 \x01(\t\x12\x18\n\x10malware_category\x18\x04 \x01(\t\x12\x1b\n\x13malware_category_ov\x18\x05 \x01(\t\"\xd6\x02\n\x05Match\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x31\n\tstatement\x18\x02 \x01(\x0b\x32\x1c.mandiant.capa.StatementNodeH\x00\x12-\n\x07\x66\x65\x61ture\x18\x03 \x01(\x0b\x32\x1a.mandiant.capa.FeatureNodeH\x00\x12&\n\x08\x63hildren\x18\x05 \x03(\x0b\x32\x14.mandiant.capa.Match\x12)\n\tlocations\x18\x06 \x03(\x0b\x32\x16.mandiant.capa.Address\x12\x34\n\x08\x63\x61ptures\x18\x07 \x03(\x0b\x32\".mandiant.capa.Match.CapturesEntry\x1aI\n\rCapturesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\'\n\x05value\x18\x02 \x01(\x0b\x32\x18.mandiant.capa.Addresses:\x02\x38\x01\x42\x06\n\x04node\"U\n\x0cMatchFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\r\n\x05match\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\xbc\x02\n\x08Metadata\x12\x11\n\ttimestamp\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\t\x12\x0c\n\x04\x61rgv\x18\x03 \x03(\t\x12%\n\x06sample\x18\x04 \x01(\x0b\x32\x15.mandiant.capa.Sample\x12-\n\x08\x61nalysis\x18\x05 \x01(\x0b\x32\x17.mandiant.capa.AnalysisB\x02\x18\x01\x12%\n\x06\x66lavor\x18\x06 \x01(\x0e\x32\x15.mandiant.capa.Flavor\x12\x38\n\x0fstatic_analysis\x18\x07 \x01(\x0b\x32\x1d.mandiant.capa.StaticAnalysisH\x00\x12:\n\x10\x64ynamic_analysis\x18\x08 \x01(\x0b\x32\x1e.mandiant.capa.DynamicAnalysisH\x00\x42\x0b\n\tanalysis2\"[\n\x0fMnemonicFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x10\n\x08mnemonic\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"]\n\x10NamespaceFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x11\n\tnamespace\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"n\n\rNumberFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12%\n\x06number\x18\x02 \x01(\x0b\x32\x15.mandiant.capa.Number\x12\x18\n\x0b\x64\x65scription\x18\x05 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"O\n\tOSFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\n\n\x02os\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"o\n\rOffsetFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12&\n\x06offset\x18\x02 \x01(\x0b\x32\x16.mandiant.capa.Integer\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\x8d\x01\n\x14OperandNumberFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\r\n\x05index\x18\x02 \x01(\r\x12.\n\x0eoperand_number\x18\x03 \x01(\x0b\x32\x16.mandiant.capa.Integer\x12\x18\n\x0b\x64\x65scription\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\x8d\x01\n\x14OperandOffsetFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\r\n\x05index\x18\x02 \x01(\r\x12.\n\x0eoperand_offset\x18\x03 \x01(\x0b\x32\x16.mandiant.capa.Integer\x12\x18\n\x0b\x64\x65scription\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"M\n\x13ProcessFeatureCount\x12\'\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Address\x12\r\n\x05\x63ount\x18\x02 \x01(\x04\"|\n\rProcessLayout\x12\'\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Address\x12\x34\n\x0fmatched_threads\x18\x02 \x03(\x0b\x32\x1b.mandiant.capa.ThreadLayout\x12\x0c\n\x04name\x18\x03 \x01(\t\"|\n\x0fPropertyFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x11\n\tproperty_\x18\x02 \x01(\t\x12\x13\n\x06\x61\x63\x63\x65ss\x18\x03 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0b\x64\x65scription\x18\x04 \x01(\tH\x01\x88\x01\x01\x42\t\n\x07_accessB\x0e\n\x0c_description\"\x8d\x01\n\x0eRangeStatement\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0b\n\x03min\x18\x02 \x01(\x04\x12\x0b\n\x03max\x18\x03 \x01(\x04\x12)\n\x05\x63hild\x18\x04 \x01(\x0b\x32\x1a.mandiant.capa.FeatureNode\x12\x18\n\x0b\x64\x65scription\x18\x05 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"U\n\x0cRegexFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\r\n\x05regex\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\xba\x01\n\x0eResultDocument\x12%\n\x04meta\x18\x01 \x01(\x0b\x32\x17.mandiant.capa.Metadata\x12\x37\n\x05rules\x18\x02 \x03(\x0b\x32(.mandiant.capa.ResultDocument.RulesEntry\x1aH\n\nRulesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12)\n\x05value\x18\x02 \x01(\x0b\x32\x1a.mandiant.capa.RuleMatches:\x02\x38\x01\"|\n\x0bRuleMatches\x12)\n\x04meta\x18\x01 \x01(\x0b\x32\x1b.mandiant.capa.RuleMetadata\x12\x0e\n\x06source\x18\x02 \x01(\t\x12\x32\n\x07matches\x18\x03 \x03(\x0b\x32!.mandiant.capa.Pair_Address_Match\"\xed\x02\n\x0cRuleMetadata\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\tnamespace\x18\x02 \x01(\t\x12\x0f\n\x07\x61uthors\x18\x03 \x03(\t\x12\'\n\x05scope\x18\x04 \x01(\x0e\x32\x14.mandiant.capa.ScopeB\x02\x18\x01\x12)\n\x06\x61ttack\x18\x05 \x03(\x0b\x32\x19.mandiant.capa.AttackSpec\x12#\n\x03mbc\x18\x06 \x03(\x0b\x32\x16.mandiant.capa.MBCSpec\x12\x12\n\nreferences\x18\x07 \x03(\t\x12\x10\n\x08\x65xamples\x18\x08 \x03(\t\x12\x13\n\x0b\x64\x65scription\x18\t \x01(\t\x12\x0b\n\x03lib\x18\n \x01(\x08\x12)\n\x04maec\x18\x0b \x01(\x0b\x32\x1b.mandiant.capa.MaecMetadata\x12\x18\n\x10is_subscope_rule\x18\x0c \x01(\x08\x12%\n\x06scopes\x18\r \x01(\x0b\x32\x15.mandiant.capa.Scopes\"A\n\x06Sample\x12\x0b\n\x03md5\x18\x01 \x01(\t\x12\x0c\n\x04sha1\x18\x02 \x01(\t\x12\x0e\n\x06sha256\x18\x03 \x01(\t\x12\x0c\n\x04path\x18\x04 \x01(\t\"v\n\x06Scopes\x12)\n\x06static\x18\x01 \x01(\x0e\x32\x14.mandiant.capa.ScopeH\x00\x88\x01\x01\x12*\n\x07\x64ynamic\x18\x02 \x01(\x0e\x32\x14.mandiant.capa.ScopeH\x01\x88\x01\x01\x42\t\n\x07_staticB\n\n\x08_dynamic\"Y\n\x0eSectionFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0f\n\x07section\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"V\n\rSomeStatement\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\r\n\x05\x63ount\x18\x02 \x01(\r\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\xf4\x01\n\rStatementNode\x12\x0c\n\x04type\x18\x01 \x01(\t\x12.\n\x05range\x18\x02 \x01(\x0b\x32\x1d.mandiant.capa.RangeStatementH\x00\x12,\n\x04some\x18\x03 \x01(\x0b\x32\x1c.mandiant.capa.SomeStatementH\x00\x12\x34\n\x08subscope\x18\x04 \x01(\x0b\x32 .mandiant.capa.SubscopeStatementH\x00\x12\x34\n\x08\x63ompound\x18\x05 \x01(\x0b\x32 .mandiant.capa.CompoundStatementH\x00\x42\x0b\n\tstatement\"\xae\x02\n\x0eStaticAnalysis\x12\x0e\n\x06\x66ormat\x18\x01 \x01(\t\x12\x0c\n\x04\x61rch\x18\x02 \x01(\t\x12\n\n\x02os\x18\x03 \x01(\t\x12\x11\n\textractor\x18\x04 \x01(\t\x12\r\n\x05rules\x18\x05 \x03(\t\x12,\n\x0c\x62\x61se_address\x18\x06 \x01(\x0b\x32\x16.mandiant.capa.Address\x12+\n\x06layout\x18\x07 \x01(\x0b\x32\x1b.mandiant.capa.StaticLayout\x12:\n\x0e\x66\x65\x61ture_counts\x18\x08 \x01(\x0b\x32\".mandiant.capa.StaticFeatureCounts\x12\x39\n\x11library_functions\x18\t \x03(\x0b\x32\x1e.mandiant.capa.LibraryFunction\"[\n\x13StaticFeatureCounts\x12\x0c\n\x04\x66ile\x18\x01 \x01(\x04\x12\x36\n\tfunctions\x18\x02 \x03(\x0b\x32#.mandiant.capa.FunctionFeatureCount\"@\n\x0cStaticLayout\x12\x30\n\tfunctions\x18\x01 \x03(\x0b\x32\x1d.mandiant.capa.FunctionLayout\"W\n\rStringFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0e\n\x06string\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"p\n\x11SubscopeStatement\x12\x0c\n\x04type\x18\x01 \x01(\t\x12#\n\x05scope\x18\x02 \x01(\x0e\x32\x14.mandiant.capa.Scope\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"]\n\x10SubstringFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x11\n\tsubstring\x18\x02 \x01(\t\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"C\n\nCallLayout\x12\'\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Address\x12\x0c\n\x04name\x18\x02 \x01(\t\"i\n\x0cThreadLayout\x12\'\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Address\x12\x30\n\rmatched_calls\x18\x02 \x03(\x0b\x32\x19.mandiant.capa.CallLayout\"4\n\tAddresses\x12\'\n\x07\x61\x64\x64ress\x18\x01 \x03(\x0b\x32\x16.mandiant.capa.Address\"b\n\x12Pair_Address_Match\x12\'\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Address\x12#\n\x05match\x18\x02 \x01(\x0b\x32\x14.mandiant.capa.Match\"E\n\x0cToken_Offset\x12%\n\x05token\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Integer\x12\x0e\n\x06offset\x18\x02 \x01(\x04\"U\n\x08Ppid_Pid\x12$\n\x04ppid\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Integer\x12#\n\x03pid\x18\x02 \x01(\x0b\x32\x16.mandiant.capa.Integer\"~\n\x0cPpid_Pid_Tid\x12$\n\x04ppid\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Integer\x12#\n\x03pid\x18\x02 \x01(\x0b\x32\x16.mandiant.capa.Integer\x12#\n\x03tid\x18\x03 \x01(\x0b\x32\x16.mandiant.capa.Integer\"\xa5\x01\n\x0fPpid_Pid_Tid_Id\x12$\n\x04ppid\x18\x01 \x01(\x0b\x32\x16.mandiant.capa.Integer\x12#\n\x03pid\x18\x02 \x01(\x0b\x32\x16.mandiant.capa.Integer\x12#\n\x03tid\x18\x03 \x01(\x0b\x32\x16.mandiant.capa.Integer\x12\"\n\x02id\x18\x04 \x01(\x0b\x32\x16.mandiant.capa.Integer\",\n\x07Integer\x12\x0b\n\x01u\x18\x01 \x01(\x04H\x00\x12\x0b\n\x01i\x18\x02 \x01(\x12H\x00\x42\x07\n\x05value\"8\n\x06Number\x12\x0b\n\x01u\x18\x01 \x01(\x04H\x00\x12\x0b\n\x01i\x18\x02 \x01(\x12H\x00\x12\x0b\n\x01\x66\x18\x03 \x01(\x01H\x00\x42\x07\n\x05value*\x92\x02\n\x0b\x41\x64\x64ressType\x12\x1b\n\x17\x41\x44\x44RESSTYPE_UNSPECIFIED\x10\x00\x12\x18\n\x14\x41\x44\x44RESSTYPE_ABSOLUTE\x10\x01\x12\x18\n\x14\x41\x44\x44RESSTYPE_RELATIVE\x10\x02\x12\x14\n\x10\x41\x44\x44RESSTYPE_FILE\x10\x03\x12\x18\n\x14\x41\x44\x44RESSTYPE_DN_TOKEN\x10\x04\x12\x1f\n\x1b\x41\x44\x44RESSTYPE_DN_TOKEN_OFFSET\x10\x05\x12\x1a\n\x16\x41\x44\x44RESSTYPE_NO_ADDRESS\x10\x06\x12\x17\n\x13\x41\x44\x44RESSTYPE_PROCESS\x10\x07\x12\x16\n\x12\x41\x44\x44RESSTYPE_THREAD\x10\x08\x12\x14\n\x10\x41\x44\x44RESSTYPE_CALL\x10\t*G\n\x06\x46lavor\x12\x16\n\x12\x46LAVOR_UNSPECIFIED\x10\x00\x12\x11\n\rFLAVOR_STATIC\x10\x01\x12\x12\n\x0e\x46LAVOR_DYNAMIC\x10\x02*\xb9\x01\n\x05Scope\x12\x15\n\x11SCOPE_UNSPECIFIED\x10\x00\x12\x0e\n\nSCOPE_FILE\x10\x01\x12\x12\n\x0eSCOPE_FUNCTION\x10\x02\x12\x15\n\x11SCOPE_BASIC_BLOCK\x10\x03\x12\x15\n\x11SCOPE_INSTRUCTION\x10\x04\x12\x11\n\rSCOPE_PROCESS\x10\x05\x12\x10\n\x0cSCOPE_THREAD\x10\x06\x12\x0e\n\nSCOPE_CALL\x10\x07\x12\x12\n\x0eSCOPE_SEQUENCE\x10\x08\x62\x06proto3') -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'capa.render.proto.capa_pb2', globals()) +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'capa.render.proto.capa_pb2', _globals) if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - _MATCH_CAPTURESENTRY._options = None - _MATCH_CAPTURESENTRY._serialized_options = b'8\001' - _METADATA.fields_by_name['analysis']._options = None - _METADATA.fields_by_name['analysis']._serialized_options = b'\030\001' - _RESULTDOCUMENT_RULESENTRY._options = None - _RESULTDOCUMENT_RULESENTRY._serialized_options = b'8\001' - _RULEMETADATA.fields_by_name['scope']._options = None - _RULEMETADATA.fields_by_name['scope']._serialized_options = b'\030\001' - _ADDRESSTYPE._serialized_start=9062 - _ADDRESSTYPE._serialized_end=9336 - _FLAVOR._serialized_start=9338 - _FLAVOR._serialized_end=9409 - _SCOPE._serialized_start=9412 - _SCOPE._serialized_end=9577 - _APIFEATURE._serialized_start=47 - _APIFEATURE._serialized_end=128 - _ADDRESS._serialized_start=131 - _ADDRESS._serialized_end=438 - _ANALYSIS._serialized_start=441 - _ANALYSIS._serialized_end=725 - _ARCHFEATURE._serialized_start=727 - _ARCHFEATURE._serialized_end=810 - _ATTACKSPEC._serialized_start=812 - _ATTACKSPEC._serialized_end=908 - _BASICBLOCKFEATURE._serialized_start=910 - _BASICBLOCKFEATURE._serialized_end=985 - _BASICBLOCKLAYOUT._serialized_start=987 - _BASICBLOCKLAYOUT._serialized_end=1046 - _BYTESFEATURE._serialized_start=1048 - _BYTESFEATURE._serialized_end=1133 - _CHARACTERISTICFEATURE._serialized_start=1135 - _CHARACTERISTICFEATURE._serialized_end=1238 - _CLASSFEATURE._serialized_start=1240 - _CLASSFEATURE._serialized_end=1326 - _COMPOUNDSTATEMENT._serialized_start=1328 - _COMPOUNDSTATEMENT._serialized_end=1403 - _DYNAMICANALYSIS._serialized_start=1406 - _DYNAMICANALYSIS._serialized_end=1606 - _DYNAMICFEATURECOUNTS._serialized_start=1608 - _DYNAMICFEATURECOUNTS._serialized_end=1699 - _DYNAMICLAYOUT._serialized_start=1701 - _DYNAMICLAYOUT._serialized_end=1765 - _EXPORTFEATURE._serialized_start=1767 - _EXPORTFEATURE._serialized_end=1854 - _FEATURECOUNTS._serialized_start=1856 - _FEATURECOUNTS._serialized_end=1941 - _FEATURENODE._serialized_start=1944 - _FEATURENODE._serialized_end=3153 - _FORMATFEATURE._serialized_start=3155 - _FORMATFEATURE._serialized_end=3242 - _FUNCTIONFEATURECOUNT._serialized_start=3244 - _FUNCTIONFEATURECOUNT._serialized_end=3322 - _FUNCTIONLAYOUT._serialized_start=3324 - _FUNCTIONLAYOUT._serialized_end=3444 - _FUNCTIONNAMEFEATURE._serialized_start=3446 - _FUNCTIONNAMEFEATURE._serialized_end=3546 - _IMPORTFEATURE._serialized_start=3548 - _IMPORTFEATURE._serialized_end=3636 - _LAYOUT._serialized_start=3638 - _LAYOUT._serialized_end=3696 - _LIBRARYFUNCTION._serialized_start=3698 - _LIBRARYFUNCTION._serialized_end=3770 - _MBCSPEC._serialized_start=3772 - _MBCSPEC._serialized_end=3861 - _MAECMETADATA._serialized_start=3864 - _MAECMETADATA._serialized_end=4018 - _MATCH._serialized_start=4021 - _MATCH._serialized_end=4363 - _MATCH_CAPTURESENTRY._serialized_start=4282 - _MATCH_CAPTURESENTRY._serialized_end=4355 - _MATCHFEATURE._serialized_start=4365 - _MATCHFEATURE._serialized_end=4450 - _METADATA._serialized_start=4453 - _METADATA._serialized_end=4769 - _MNEMONICFEATURE._serialized_start=4771 - _MNEMONICFEATURE._serialized_end=4862 - _NAMESPACEFEATURE._serialized_start=4864 - _NAMESPACEFEATURE._serialized_end=4957 - _NUMBERFEATURE._serialized_start=4959 - _NUMBERFEATURE._serialized_end=5069 - _OSFEATURE._serialized_start=5071 - _OSFEATURE._serialized_end=5150 - _OFFSETFEATURE._serialized_start=5152 - _OFFSETFEATURE._serialized_end=5263 - _OPERANDNUMBERFEATURE._serialized_start=5266 - _OPERANDNUMBERFEATURE._serialized_end=5407 - _OPERANDOFFSETFEATURE._serialized_start=5410 - _OPERANDOFFSETFEATURE._serialized_end=5551 - _PROCESSFEATURECOUNT._serialized_start=5553 - _PROCESSFEATURECOUNT._serialized_end=5630 - _PROCESSLAYOUT._serialized_start=5632 - _PROCESSLAYOUT._serialized_end=5756 - _PROPERTYFEATURE._serialized_start=5758 - _PROPERTYFEATURE._serialized_end=5882 - _RANGESTATEMENT._serialized_start=5885 - _RANGESTATEMENT._serialized_end=6026 - _REGEXFEATURE._serialized_start=6028 - _REGEXFEATURE._serialized_end=6113 - _RESULTDOCUMENT._serialized_start=6116 - _RESULTDOCUMENT._serialized_end=6302 - _RESULTDOCUMENT_RULESENTRY._serialized_start=6230 - _RESULTDOCUMENT_RULESENTRY._serialized_end=6302 - _RULEMATCHES._serialized_start=6304 - _RULEMATCHES._serialized_end=6428 - _RULEMETADATA._serialized_start=6431 - _RULEMETADATA._serialized_end=6796 - _SAMPLE._serialized_start=6798 - _SAMPLE._serialized_end=6863 - _SCOPES._serialized_start=6865 - _SCOPES._serialized_end=6983 - _SECTIONFEATURE._serialized_start=6985 - _SECTIONFEATURE._serialized_end=7074 - _SOMESTATEMENT._serialized_start=7076 - _SOMESTATEMENT._serialized_end=7162 - _STATEMENTNODE._serialized_start=7165 - _STATEMENTNODE._serialized_end=7409 - _STATICANALYSIS._serialized_start=7412 - _STATICANALYSIS._serialized_end=7714 - _STATICFEATURECOUNTS._serialized_start=7716 - _STATICFEATURECOUNTS._serialized_end=7807 - _STATICLAYOUT._serialized_start=7809 - _STATICLAYOUT._serialized_end=7873 - _STRINGFEATURE._serialized_start=7875 - _STRINGFEATURE._serialized_end=7962 - _SUBSCOPESTATEMENT._serialized_start=7964 - _SUBSCOPESTATEMENT._serialized_end=8076 - _SUBSTRINGFEATURE._serialized_start=8078 - _SUBSTRINGFEATURE._serialized_end=8171 - _CALLLAYOUT._serialized_start=8173 - _CALLLAYOUT._serialized_end=8240 - _THREADLAYOUT._serialized_start=8242 - _THREADLAYOUT._serialized_end=8347 - _ADDRESSES._serialized_start=8349 - _ADDRESSES._serialized_end=8401 - _PAIR_ADDRESS_MATCH._serialized_start=8403 - _PAIR_ADDRESS_MATCH._serialized_end=8501 - _TOKEN_OFFSET._serialized_start=8503 - _TOKEN_OFFSET._serialized_end=8572 - _PPID_PID._serialized_start=8574 - _PPID_PID._serialized_end=8659 - _PPID_PID_TID._serialized_start=8661 - _PPID_PID_TID._serialized_end=8787 - _PPID_PID_TID_ID._serialized_start=8790 - _PPID_PID_TID_ID._serialized_end=8955 - _INTEGER._serialized_start=8957 - _INTEGER._serialized_end=9001 - _NUMBER._serialized_start=9003 - _NUMBER._serialized_end=9059 + _globals['_MATCH_CAPTURESENTRY']._options = None + _globals['_MATCH_CAPTURESENTRY']._serialized_options = b'8\001' + _globals['_METADATA'].fields_by_name['analysis']._options = None + _globals['_METADATA'].fields_by_name['analysis']._serialized_options = b'\030\001' + _globals['_RESULTDOCUMENT_RULESENTRY']._options = None + _globals['_RESULTDOCUMENT_RULESENTRY']._serialized_options = b'8\001' + _globals['_RULEMETADATA'].fields_by_name['scope']._options = None + _globals['_RULEMETADATA'].fields_by_name['scope']._serialized_options = b'\030\001' + _globals['_ADDRESSTYPE']._serialized_start=9062 + _globals['_ADDRESSTYPE']._serialized_end=9336 + _globals['_FLAVOR']._serialized_start=9338 + _globals['_FLAVOR']._serialized_end=9409 + _globals['_SCOPE']._serialized_start=9412 + _globals['_SCOPE']._serialized_end=9597 + _globals['_APIFEATURE']._serialized_start=47 + _globals['_APIFEATURE']._serialized_end=128 + _globals['_ADDRESS']._serialized_start=131 + _globals['_ADDRESS']._serialized_end=438 + _globals['_ANALYSIS']._serialized_start=441 + _globals['_ANALYSIS']._serialized_end=725 + _globals['_ARCHFEATURE']._serialized_start=727 + _globals['_ARCHFEATURE']._serialized_end=810 + _globals['_ATTACKSPEC']._serialized_start=812 + _globals['_ATTACKSPEC']._serialized_end=908 + _globals['_BASICBLOCKFEATURE']._serialized_start=910 + _globals['_BASICBLOCKFEATURE']._serialized_end=985 + _globals['_BASICBLOCKLAYOUT']._serialized_start=987 + _globals['_BASICBLOCKLAYOUT']._serialized_end=1046 + _globals['_BYTESFEATURE']._serialized_start=1048 + _globals['_BYTESFEATURE']._serialized_end=1133 + _globals['_CHARACTERISTICFEATURE']._serialized_start=1135 + _globals['_CHARACTERISTICFEATURE']._serialized_end=1238 + _globals['_CLASSFEATURE']._serialized_start=1240 + _globals['_CLASSFEATURE']._serialized_end=1326 + _globals['_COMPOUNDSTATEMENT']._serialized_start=1328 + _globals['_COMPOUNDSTATEMENT']._serialized_end=1403 + _globals['_DYNAMICANALYSIS']._serialized_start=1406 + _globals['_DYNAMICANALYSIS']._serialized_end=1606 + _globals['_DYNAMICFEATURECOUNTS']._serialized_start=1608 + _globals['_DYNAMICFEATURECOUNTS']._serialized_end=1699 + _globals['_DYNAMICLAYOUT']._serialized_start=1701 + _globals['_DYNAMICLAYOUT']._serialized_end=1765 + _globals['_EXPORTFEATURE']._serialized_start=1767 + _globals['_EXPORTFEATURE']._serialized_end=1854 + _globals['_FEATURECOUNTS']._serialized_start=1856 + _globals['_FEATURECOUNTS']._serialized_end=1941 + _globals['_FEATURENODE']._serialized_start=1944 + _globals['_FEATURENODE']._serialized_end=3153 + _globals['_FORMATFEATURE']._serialized_start=3155 + _globals['_FORMATFEATURE']._serialized_end=3242 + _globals['_FUNCTIONFEATURECOUNT']._serialized_start=3244 + _globals['_FUNCTIONFEATURECOUNT']._serialized_end=3322 + _globals['_FUNCTIONLAYOUT']._serialized_start=3324 + _globals['_FUNCTIONLAYOUT']._serialized_end=3444 + _globals['_FUNCTIONNAMEFEATURE']._serialized_start=3446 + _globals['_FUNCTIONNAMEFEATURE']._serialized_end=3546 + _globals['_IMPORTFEATURE']._serialized_start=3548 + _globals['_IMPORTFEATURE']._serialized_end=3636 + _globals['_LAYOUT']._serialized_start=3638 + _globals['_LAYOUT']._serialized_end=3696 + _globals['_LIBRARYFUNCTION']._serialized_start=3698 + _globals['_LIBRARYFUNCTION']._serialized_end=3770 + _globals['_MBCSPEC']._serialized_start=3772 + _globals['_MBCSPEC']._serialized_end=3861 + _globals['_MAECMETADATA']._serialized_start=3864 + _globals['_MAECMETADATA']._serialized_end=4018 + _globals['_MATCH']._serialized_start=4021 + _globals['_MATCH']._serialized_end=4363 + _globals['_MATCH_CAPTURESENTRY']._serialized_start=4282 + _globals['_MATCH_CAPTURESENTRY']._serialized_end=4355 + _globals['_MATCHFEATURE']._serialized_start=4365 + _globals['_MATCHFEATURE']._serialized_end=4450 + _globals['_METADATA']._serialized_start=4453 + _globals['_METADATA']._serialized_end=4769 + _globals['_MNEMONICFEATURE']._serialized_start=4771 + _globals['_MNEMONICFEATURE']._serialized_end=4862 + _globals['_NAMESPACEFEATURE']._serialized_start=4864 + _globals['_NAMESPACEFEATURE']._serialized_end=4957 + _globals['_NUMBERFEATURE']._serialized_start=4959 + _globals['_NUMBERFEATURE']._serialized_end=5069 + _globals['_OSFEATURE']._serialized_start=5071 + _globals['_OSFEATURE']._serialized_end=5150 + _globals['_OFFSETFEATURE']._serialized_start=5152 + _globals['_OFFSETFEATURE']._serialized_end=5263 + _globals['_OPERANDNUMBERFEATURE']._serialized_start=5266 + _globals['_OPERANDNUMBERFEATURE']._serialized_end=5407 + _globals['_OPERANDOFFSETFEATURE']._serialized_start=5410 + _globals['_OPERANDOFFSETFEATURE']._serialized_end=5551 + _globals['_PROCESSFEATURECOUNT']._serialized_start=5553 + _globals['_PROCESSFEATURECOUNT']._serialized_end=5630 + _globals['_PROCESSLAYOUT']._serialized_start=5632 + _globals['_PROCESSLAYOUT']._serialized_end=5756 + _globals['_PROPERTYFEATURE']._serialized_start=5758 + _globals['_PROPERTYFEATURE']._serialized_end=5882 + _globals['_RANGESTATEMENT']._serialized_start=5885 + _globals['_RANGESTATEMENT']._serialized_end=6026 + _globals['_REGEXFEATURE']._serialized_start=6028 + _globals['_REGEXFEATURE']._serialized_end=6113 + _globals['_RESULTDOCUMENT']._serialized_start=6116 + _globals['_RESULTDOCUMENT']._serialized_end=6302 + _globals['_RESULTDOCUMENT_RULESENTRY']._serialized_start=6230 + _globals['_RESULTDOCUMENT_RULESENTRY']._serialized_end=6302 + _globals['_RULEMATCHES']._serialized_start=6304 + _globals['_RULEMATCHES']._serialized_end=6428 + _globals['_RULEMETADATA']._serialized_start=6431 + _globals['_RULEMETADATA']._serialized_end=6796 + _globals['_SAMPLE']._serialized_start=6798 + _globals['_SAMPLE']._serialized_end=6863 + _globals['_SCOPES']._serialized_start=6865 + _globals['_SCOPES']._serialized_end=6983 + _globals['_SECTIONFEATURE']._serialized_start=6985 + _globals['_SECTIONFEATURE']._serialized_end=7074 + _globals['_SOMESTATEMENT']._serialized_start=7076 + _globals['_SOMESTATEMENT']._serialized_end=7162 + _globals['_STATEMENTNODE']._serialized_start=7165 + _globals['_STATEMENTNODE']._serialized_end=7409 + _globals['_STATICANALYSIS']._serialized_start=7412 + _globals['_STATICANALYSIS']._serialized_end=7714 + _globals['_STATICFEATURECOUNTS']._serialized_start=7716 + _globals['_STATICFEATURECOUNTS']._serialized_end=7807 + _globals['_STATICLAYOUT']._serialized_start=7809 + _globals['_STATICLAYOUT']._serialized_end=7873 + _globals['_STRINGFEATURE']._serialized_start=7875 + _globals['_STRINGFEATURE']._serialized_end=7962 + _globals['_SUBSCOPESTATEMENT']._serialized_start=7964 + _globals['_SUBSCOPESTATEMENT']._serialized_end=8076 + _globals['_SUBSTRINGFEATURE']._serialized_start=8078 + _globals['_SUBSTRINGFEATURE']._serialized_end=8171 + _globals['_CALLLAYOUT']._serialized_start=8173 + _globals['_CALLLAYOUT']._serialized_end=8240 + _globals['_THREADLAYOUT']._serialized_start=8242 + _globals['_THREADLAYOUT']._serialized_end=8347 + _globals['_ADDRESSES']._serialized_start=8349 + _globals['_ADDRESSES']._serialized_end=8401 + _globals['_PAIR_ADDRESS_MATCH']._serialized_start=8403 + _globals['_PAIR_ADDRESS_MATCH']._serialized_end=8501 + _globals['_TOKEN_OFFSET']._serialized_start=8503 + _globals['_TOKEN_OFFSET']._serialized_end=8572 + _globals['_PPID_PID']._serialized_start=8574 + _globals['_PPID_PID']._serialized_end=8659 + _globals['_PPID_PID_TID']._serialized_start=8661 + _globals['_PPID_PID_TID']._serialized_end=8787 + _globals['_PPID_PID_TID_ID']._serialized_start=8790 + _globals['_PPID_PID_TID_ID']._serialized_end=8955 + _globals['_INTEGER']._serialized_start=8957 + _globals['_INTEGER']._serialized_end=9001 + _globals['_NUMBER']._serialized_start=9003 + _globals['_NUMBER']._serialized_end=9059 # @@protoc_insertion_point(module_scope) diff --git a/capa/render/proto/capa_pb2.pyi b/capa/render/proto/capa_pb2.pyi index ecb330bc..c881561a 100644 --- a/capa/render/proto/capa_pb2.pyi +++ b/capa/render/proto/capa_pb2.pyi @@ -2,6 +2,7 @@ @generated by mypy-protobuf. Do not edit manually! isort:skip_file """ + import builtins import collections.abc import google.protobuf.descriptor @@ -80,6 +81,7 @@ class _ScopeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumType SCOPE_PROCESS: _Scope.ValueType # 5 SCOPE_THREAD: _Scope.ValueType # 6 SCOPE_CALL: _Scope.ValueType # 7 + SCOPE_SEQUENCE: _Scope.ValueType # 8 class Scope(_Scope, metaclass=_ScopeEnumTypeWrapper): ... @@ -91,9 +93,10 @@ SCOPE_INSTRUCTION: Scope.ValueType # 4 SCOPE_PROCESS: Scope.ValueType # 5 SCOPE_THREAD: Scope.ValueType # 6 SCOPE_CALL: Scope.ValueType # 7 +SCOPE_SEQUENCE: Scope.ValueType # 8 global___Scope = Scope -@typing_extensions.final +@typing.final class APIFeature(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -110,13 +113,13 @@ class APIFeature(google.protobuf.message.Message): api: builtins.str = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "api", b"api", "description", b"description", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "api", b"api", "description", b"description", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___APIFeature = APIFeature -@typing_extensions.final +@typing.final class Address(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -147,13 +150,13 @@ class Address(google.protobuf.message.Message): ppid_pid_tid: global___Ppid_Pid_Tid | None = ..., ppid_pid_tid_id: global___Ppid_Pid_Tid_Id | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["ppid_pid", b"ppid_pid", "ppid_pid_tid", b"ppid_pid_tid", "ppid_pid_tid_id", b"ppid_pid_tid_id", "token_offset", b"token_offset", "v", b"v", "value", b"value"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["ppid_pid", b"ppid_pid", "ppid_pid_tid", b"ppid_pid_tid", "ppid_pid_tid_id", b"ppid_pid_tid_id", "token_offset", b"token_offset", "type", b"type", "v", b"v", "value", b"value"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["value", b"value"]) -> typing_extensions.Literal["v", "token_offset", "ppid_pid", "ppid_pid_tid", "ppid_pid_tid_id"] | None: ... + def HasField(self, field_name: typing.Literal["ppid_pid", b"ppid_pid", "ppid_pid_tid", b"ppid_pid_tid", "ppid_pid_tid_id", b"ppid_pid_tid_id", "token_offset", b"token_offset", "v", b"v", "value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["ppid_pid", b"ppid_pid", "ppid_pid_tid", b"ppid_pid_tid", "ppid_pid_tid_id", b"ppid_pid_tid_id", "token_offset", b"token_offset", "type", b"type", "v", b"v", "value", b"value"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["value", b"value"]) -> typing.Literal["v", "token_offset", "ppid_pid", "ppid_pid_tid", "ppid_pid_tid_id"] | None: ... global___Address = Address -@typing_extensions.final +@typing.final class Analysis(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -193,12 +196,12 @@ class Analysis(google.protobuf.message.Message): feature_counts: global___FeatureCounts | None = ..., library_functions: collections.abc.Iterable[global___LibraryFunction] | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["base_address", b"base_address", "feature_counts", b"feature_counts", "layout", b"layout"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["arch", b"arch", "base_address", b"base_address", "extractor", b"extractor", "feature_counts", b"feature_counts", "format", b"format", "layout", b"layout", "library_functions", b"library_functions", "os", b"os", "rules", b"rules"]) -> None: ... + def HasField(self, field_name: typing.Literal["base_address", b"base_address", "feature_counts", b"feature_counts", "layout", b"layout"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["arch", b"arch", "base_address", b"base_address", "extractor", b"extractor", "feature_counts", b"feature_counts", "format", b"format", "layout", b"layout", "library_functions", b"library_functions", "os", b"os", "rules", b"rules"]) -> None: ... global___Analysis = Analysis -@typing_extensions.final +@typing.final class ArchFeature(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -215,13 +218,13 @@ class ArchFeature(google.protobuf.message.Message): arch: builtins.str = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "arch", b"arch", "description", b"description", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "arch", b"arch", "description", b"description", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___ArchFeature = ArchFeature -@typing_extensions.final +@typing.final class AttackSpec(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -230,12 +233,12 @@ class AttackSpec(google.protobuf.message.Message): TECHNIQUE_FIELD_NUMBER: builtins.int SUBTECHNIQUE_FIELD_NUMBER: builtins.int ID_FIELD_NUMBER: builtins.int - @property - def parts(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: ... tactic: builtins.str technique: builtins.str subtechnique: builtins.str id: builtins.str + @property + def parts(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: ... def __init__( self, *, @@ -245,11 +248,11 @@ class AttackSpec(google.protobuf.message.Message): subtechnique: builtins.str = ..., id: builtins.str = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["id", b"id", "parts", b"parts", "subtechnique", b"subtechnique", "tactic", b"tactic", "technique", b"technique"]) -> None: ... + def ClearField(self, field_name: typing.Literal["id", b"id", "parts", b"parts", "subtechnique", b"subtechnique", "tactic", b"tactic", "technique", b"technique"]) -> None: ... global___AttackSpec = AttackSpec -@typing_extensions.final +@typing.final class BasicBlockFeature(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -263,13 +266,13 @@ class BasicBlockFeature(google.protobuf.message.Message): type: builtins.str = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "description", b"description", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___BasicBlockFeature = BasicBlockFeature -@typing_extensions.final +@typing.final class BasicBlockLayout(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -281,12 +284,12 @@ class BasicBlockLayout(google.protobuf.message.Message): *, address: global___Address | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["address", b"address"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["address", b"address"]) -> None: ... + def HasField(self, field_name: typing.Literal["address", b"address"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["address", b"address"]) -> None: ... global___BasicBlockLayout = BasicBlockLayout -@typing_extensions.final +@typing.final class BytesFeature(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -303,13 +306,13 @@ class BytesFeature(google.protobuf.message.Message): bytes: builtins.str = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "bytes", b"bytes", "description", b"description", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "bytes", b"bytes", "description", b"description", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___BytesFeature = BytesFeature -@typing_extensions.final +@typing.final class CharacteristicFeature(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -326,13 +329,13 @@ class CharacteristicFeature(google.protobuf.message.Message): characteristic: builtins.str = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "characteristic", b"characteristic", "description", b"description", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "characteristic", b"characteristic", "description", b"description", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___CharacteristicFeature = CharacteristicFeature -@typing_extensions.final +@typing.final class ClassFeature(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -350,13 +353,13 @@ class ClassFeature(google.protobuf.message.Message): class_: builtins.str = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "class_", b"class_", "description", b"description", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "class_", b"class_", "description", b"description", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___ClassFeature = ClassFeature -@typing_extensions.final +@typing.final class CompoundStatement(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -370,13 +373,13 @@ class CompoundStatement(google.protobuf.message.Message): type: builtins.str = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "description", b"description", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___CompoundStatement = CompoundStatement -@typing_extensions.final +@typing.final class DynamicAnalysis(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -408,12 +411,12 @@ class DynamicAnalysis(google.protobuf.message.Message): layout: global___DynamicLayout | None = ..., feature_counts: global___DynamicFeatureCounts | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["feature_counts", b"feature_counts", "layout", b"layout"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["arch", b"arch", "extractor", b"extractor", "feature_counts", b"feature_counts", "format", b"format", "layout", b"layout", "os", b"os", "rules", b"rules"]) -> None: ... + def HasField(self, field_name: typing.Literal["feature_counts", b"feature_counts", "layout", b"layout"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["arch", b"arch", "extractor", b"extractor", "feature_counts", b"feature_counts", "format", b"format", "layout", b"layout", "os", b"os", "rules", b"rules"]) -> None: ... global___DynamicAnalysis = DynamicAnalysis -@typing_extensions.final +@typing.final class DynamicFeatureCounts(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -428,11 +431,11 @@ class DynamicFeatureCounts(google.protobuf.message.Message): file: builtins.int = ..., processes: collections.abc.Iterable[global___ProcessFeatureCount] | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["file", b"file", "processes", b"processes"]) -> None: ... + def ClearField(self, field_name: typing.Literal["file", b"file", "processes", b"processes"]) -> None: ... global___DynamicFeatureCounts = DynamicFeatureCounts -@typing_extensions.final +@typing.final class DynamicLayout(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -444,11 +447,11 @@ class DynamicLayout(google.protobuf.message.Message): *, processes: collections.abc.Iterable[global___ProcessLayout] | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["processes", b"processes"]) -> None: ... + def ClearField(self, field_name: typing.Literal["processes", b"processes"]) -> None: ... global___DynamicLayout = DynamicLayout -@typing_extensions.final +@typing.final class ExportFeature(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -465,13 +468,13 @@ class ExportFeature(google.protobuf.message.Message): export: builtins.str = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description", "export", b"export", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "description", b"description", "export", b"export", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___ExportFeature = ExportFeature -@typing_extensions.final +@typing.final class FeatureCounts(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -486,11 +489,11 @@ class FeatureCounts(google.protobuf.message.Message): file: builtins.int = ..., functions: collections.abc.Iterable[global___FunctionFeatureCount] | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["file", b"file", "functions", b"functions"]) -> None: ... + def ClearField(self, field_name: typing.Literal["file", b"file", "functions", b"functions"]) -> None: ... global___FeatureCounts = FeatureCounts -@typing_extensions.final +@typing.final class FeatureNode(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -534,6 +537,7 @@ class FeatureNode(google.protobuf.message.Message): @property def import_(self) -> global___ImportFeature: """import is Python keyword""" + @property def section(self) -> global___SectionFeature: ... @property @@ -553,6 +557,7 @@ class FeatureNode(google.protobuf.message.Message): @property def property_(self) -> global___PropertyFeature: """property is a Python top-level decorator name""" + @property def number(self) -> global___NumberFeature: ... @property @@ -595,13 +600,13 @@ class FeatureNode(google.protobuf.message.Message): operand_offset: global___OperandOffsetFeature | None = ..., basic_block: global___BasicBlockFeature | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["api", b"api", "arch", b"arch", "basic_block", b"basic_block", "bytes", b"bytes", "characteristic", b"characteristic", "class_", b"class_", "export", b"export", "feature", b"feature", "format", b"format", "function_name", b"function_name", "import_", b"import_", "match", b"match", "mnemonic", b"mnemonic", "namespace", b"namespace", "number", b"number", "offset", b"offset", "operand_number", b"operand_number", "operand_offset", b"operand_offset", "os", b"os", "property_", b"property_", "regex", b"regex", "section", b"section", "string", b"string", "substring", b"substring"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["api", b"api", "arch", b"arch", "basic_block", b"basic_block", "bytes", b"bytes", "characteristic", b"characteristic", "class_", b"class_", "export", b"export", "feature", b"feature", "format", b"format", "function_name", b"function_name", "import_", b"import_", "match", b"match", "mnemonic", b"mnemonic", "namespace", b"namespace", "number", b"number", "offset", b"offset", "operand_number", b"operand_number", "operand_offset", b"operand_offset", "os", b"os", "property_", b"property_", "regex", b"regex", "section", b"section", "string", b"string", "substring", b"substring", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["feature", b"feature"]) -> typing_extensions.Literal["os", "arch", "format", "match", "characteristic", "export", "import_", "section", "function_name", "substring", "regex", "string", "class_", "namespace", "api", "property_", "number", "bytes", "offset", "mnemonic", "operand_number", "operand_offset", "basic_block"] | None: ... + def HasField(self, field_name: typing.Literal["api", b"api", "arch", b"arch", "basic_block", b"basic_block", "bytes", b"bytes", "characteristic", b"characteristic", "class_", b"class_", "export", b"export", "feature", b"feature", "format", b"format", "function_name", b"function_name", "import_", b"import_", "match", b"match", "mnemonic", b"mnemonic", "namespace", b"namespace", "number", b"number", "offset", b"offset", "operand_number", b"operand_number", "operand_offset", b"operand_offset", "os", b"os", "property_", b"property_", "regex", b"regex", "section", b"section", "string", b"string", "substring", b"substring"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["api", b"api", "arch", b"arch", "basic_block", b"basic_block", "bytes", b"bytes", "characteristic", b"characteristic", "class_", b"class_", "export", b"export", "feature", b"feature", "format", b"format", "function_name", b"function_name", "import_", b"import_", "match", b"match", "mnemonic", b"mnemonic", "namespace", b"namespace", "number", b"number", "offset", b"offset", "operand_number", b"operand_number", "operand_offset", b"operand_offset", "os", b"os", "property_", b"property_", "regex", b"regex", "section", b"section", "string", b"string", "substring", b"substring", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["feature", b"feature"]) -> typing.Literal["os", "arch", "format", "match", "characteristic", "export", "import_", "section", "function_name", "substring", "regex", "string", "class_", "namespace", "api", "property_", "number", "bytes", "offset", "mnemonic", "operand_number", "operand_offset", "basic_block"] | None: ... global___FeatureNode = FeatureNode -@typing_extensions.final +@typing.final class FormatFeature(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -618,33 +623,33 @@ class FormatFeature(google.protobuf.message.Message): format: builtins.str = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description", "format", b"format", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "description", b"description", "format", b"format", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___FormatFeature = FormatFeature -@typing_extensions.final +@typing.final class FunctionFeatureCount(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor ADDRESS_FIELD_NUMBER: builtins.int COUNT_FIELD_NUMBER: builtins.int + count: builtins.int @property def address(self) -> global___Address: ... - count: builtins.int def __init__( self, *, address: global___Address | None = ..., count: builtins.int = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["address", b"address"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["address", b"address", "count", b"count"]) -> None: ... + def HasField(self, field_name: typing.Literal["address", b"address"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["address", b"address", "count", b"count"]) -> None: ... global___FunctionFeatureCount = FunctionFeatureCount -@typing_extensions.final +@typing.final class FunctionLayout(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -660,12 +665,12 @@ class FunctionLayout(google.protobuf.message.Message): address: global___Address | None = ..., matched_basic_blocks: collections.abc.Iterable[global___BasicBlockLayout] | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["address", b"address"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["address", b"address", "matched_basic_blocks", b"matched_basic_blocks"]) -> None: ... + def HasField(self, field_name: typing.Literal["address", b"address"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["address", b"address", "matched_basic_blocks", b"matched_basic_blocks"]) -> None: ... global___FunctionLayout = FunctionLayout -@typing_extensions.final +@typing.final class FunctionNameFeature(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -682,13 +687,13 @@ class FunctionNameFeature(google.protobuf.message.Message): function_name: builtins.str = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description", "function_name", b"function_name", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "description", b"description", "function_name", b"function_name", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___FunctionNameFeature = FunctionNameFeature -@typing_extensions.final +@typing.final class ImportFeature(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -705,13 +710,13 @@ class ImportFeature(google.protobuf.message.Message): import_: builtins.str = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description", "import_", b"import_", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "description", b"description", "import_", b"import_", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___ImportFeature = ImportFeature -@typing_extensions.final +@typing.final class Layout(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -723,31 +728,31 @@ class Layout(google.protobuf.message.Message): *, functions: collections.abc.Iterable[global___FunctionLayout] | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["functions", b"functions"]) -> None: ... + def ClearField(self, field_name: typing.Literal["functions", b"functions"]) -> None: ... global___Layout = Layout -@typing_extensions.final +@typing.final class LibraryFunction(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor ADDRESS_FIELD_NUMBER: builtins.int NAME_FIELD_NUMBER: builtins.int + name: builtins.str @property def address(self) -> global___Address: ... - name: builtins.str def __init__( self, *, address: global___Address | None = ..., name: builtins.str = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["address", b"address"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["address", b"address", "name", b"name"]) -> None: ... + def HasField(self, field_name: typing.Literal["address", b"address"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["address", b"address", "name", b"name"]) -> None: ... global___LibraryFunction = LibraryFunction -@typing_extensions.final +@typing.final class MBCSpec(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -756,12 +761,12 @@ class MBCSpec(google.protobuf.message.Message): BEHAVIOR_FIELD_NUMBER: builtins.int METHOD_FIELD_NUMBER: builtins.int ID_FIELD_NUMBER: builtins.int - @property - def parts(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: ... objective: builtins.str behavior: builtins.str method: builtins.str id: builtins.str + @property + def parts(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: ... def __init__( self, *, @@ -771,11 +776,11 @@ class MBCSpec(google.protobuf.message.Message): method: builtins.str = ..., id: builtins.str = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["behavior", b"behavior", "id", b"id", "method", b"method", "objective", b"objective", "parts", b"parts"]) -> None: ... + def ClearField(self, field_name: typing.Literal["behavior", b"behavior", "id", b"id", "method", b"method", "objective", b"objective", "parts", b"parts"]) -> None: ... global___MBCSpec = MBCSpec -@typing_extensions.final +@typing.final class MaecMetadata(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -798,15 +803,15 @@ class MaecMetadata(google.protobuf.message.Message): malware_category: builtins.str = ..., malware_category_ov: builtins.str = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["analysis_conclusion", b"analysis_conclusion", "analysis_conclusion_ov", b"analysis_conclusion_ov", "malware_category", b"malware_category", "malware_category_ov", b"malware_category_ov", "malware_family", b"malware_family"]) -> None: ... + def ClearField(self, field_name: typing.Literal["analysis_conclusion", b"analysis_conclusion", "analysis_conclusion_ov", b"analysis_conclusion_ov", "malware_category", b"malware_category", "malware_category_ov", b"malware_category_ov", "malware_family", b"malware_family"]) -> None: ... global___MaecMetadata = MaecMetadata -@typing_extensions.final +@typing.final class Match(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor - @typing_extensions.final + @typing.final class CapturesEntry(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -821,8 +826,8 @@ class Match(google.protobuf.message.Message): key: builtins.str = ..., value: global___Addresses | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["value", b"value"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "value", b"value"]) -> None: ... + def HasField(self, field_name: typing.Literal["value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["key", b"key", "value", b"value"]) -> None: ... SUCCESS_FIELD_NUMBER: builtins.int STATEMENT_FIELD_NUMBER: builtins.int @@ -851,13 +856,13 @@ class Match(google.protobuf.message.Message): locations: collections.abc.Iterable[global___Address] | None = ..., captures: collections.abc.Mapping[builtins.str, global___Addresses] | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["feature", b"feature", "node", b"node", "statement", b"statement"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["captures", b"captures", "children", b"children", "feature", b"feature", "locations", b"locations", "node", b"node", "statement", b"statement", "success", b"success"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["node", b"node"]) -> typing_extensions.Literal["statement", "feature"] | None: ... + def HasField(self, field_name: typing.Literal["feature", b"feature", "node", b"node", "statement", b"statement"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["captures", b"captures", "children", b"children", "feature", b"feature", "locations", b"locations", "node", b"node", "statement", b"statement", "success", b"success"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["node", b"node"]) -> typing.Literal["statement", "feature"] | None: ... global___Match = Match -@typing_extensions.final +@typing.final class MatchFeature(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -874,13 +879,13 @@ class MatchFeature(google.protobuf.message.Message): match: builtins.str = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description", "match", b"match", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "description", b"description", "match", b"match", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___MatchFeature = MatchFeature -@typing_extensions.final +@typing.final class Metadata(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -895,6 +900,7 @@ class Metadata(google.protobuf.message.Message): timestamp: builtins.str """iso8601 format, like: 2019-01-01T00:00:00Z""" version: builtins.str + flavor: global___Flavor.ValueType @property def argv(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: ... @property @@ -904,10 +910,11 @@ class Metadata(google.protobuf.message.Message): """deprecated in v7.0. use analysis2 instead. """ - flavor: global___Flavor.ValueType + @property def static_analysis(self) -> global___StaticAnalysis: """use analysis2 instead of analysis (deprecated in v7.0).""" + @property def dynamic_analysis(self) -> global___DynamicAnalysis: ... def __init__( @@ -922,13 +929,13 @@ class Metadata(google.protobuf.message.Message): static_analysis: global___StaticAnalysis | None = ..., dynamic_analysis: global___DynamicAnalysis | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["analysis", b"analysis", "analysis2", b"analysis2", "dynamic_analysis", b"dynamic_analysis", "sample", b"sample", "static_analysis", b"static_analysis"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["analysis", b"analysis", "analysis2", b"analysis2", "argv", b"argv", "dynamic_analysis", b"dynamic_analysis", "flavor", b"flavor", "sample", b"sample", "static_analysis", b"static_analysis", "timestamp", b"timestamp", "version", b"version"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["analysis2", b"analysis2"]) -> typing_extensions.Literal["static_analysis", "dynamic_analysis"] | None: ... + def HasField(self, field_name: typing.Literal["analysis", b"analysis", "analysis2", b"analysis2", "dynamic_analysis", b"dynamic_analysis", "sample", b"sample", "static_analysis", b"static_analysis"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["analysis", b"analysis", "analysis2", b"analysis2", "argv", b"argv", "dynamic_analysis", b"dynamic_analysis", "flavor", b"flavor", "sample", b"sample", "static_analysis", b"static_analysis", "timestamp", b"timestamp", "version", b"version"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["analysis2", b"analysis2"]) -> typing.Literal["static_analysis", "dynamic_analysis"] | None: ... global___Metadata = Metadata -@typing_extensions.final +@typing.final class MnemonicFeature(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -945,13 +952,13 @@ class MnemonicFeature(google.protobuf.message.Message): mnemonic: builtins.str = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description", "mnemonic", b"mnemonic", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "description", b"description", "mnemonic", b"mnemonic", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___MnemonicFeature = MnemonicFeature -@typing_extensions.final +@typing.final class NamespaceFeature(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -968,13 +975,13 @@ class NamespaceFeature(google.protobuf.message.Message): namespace: builtins.str = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description", "namespace", b"namespace", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "description", b"description", "namespace", b"namespace", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___NamespaceFeature = NamespaceFeature -@typing_extensions.final +@typing.final class NumberFeature(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -982,10 +989,11 @@ class NumberFeature(google.protobuf.message.Message): NUMBER_FIELD_NUMBER: builtins.int DESCRIPTION_FIELD_NUMBER: builtins.int type: builtins.str + description: builtins.str @property def number(self) -> global___Number: """this can be positive (range: u64), negative (range: i64), or a double.""" - description: builtins.str + def __init__( self, *, @@ -993,13 +1001,13 @@ class NumberFeature(google.protobuf.message.Message): number: global___Number | None = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description", "number", b"number"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description", "number", b"number", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description", "number", b"number"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "description", b"description", "number", b"number", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___NumberFeature = NumberFeature -@typing_extensions.final +@typing.final class OSFeature(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1016,13 +1024,13 @@ class OSFeature(google.protobuf.message.Message): os: builtins.str = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description", "os", b"os", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "description", b"description", "os", b"os", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___OSFeature = OSFeature -@typing_extensions.final +@typing.final class OffsetFeature(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1030,10 +1038,11 @@ class OffsetFeature(google.protobuf.message.Message): OFFSET_FIELD_NUMBER: builtins.int DESCRIPTION_FIELD_NUMBER: builtins.int type: builtins.str + description: builtins.str @property def offset(self) -> global___Integer: """offset can be negative""" - description: builtins.str + def __init__( self, *, @@ -1041,13 +1050,13 @@ class OffsetFeature(google.protobuf.message.Message): offset: global___Integer | None = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description", "offset", b"offset"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description", "offset", b"offset", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description", "offset", b"offset"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "description", b"description", "offset", b"offset", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___OffsetFeature = OffsetFeature -@typing_extensions.final +@typing.final class OperandNumberFeature(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1057,10 +1066,11 @@ class OperandNumberFeature(google.protobuf.message.Message): DESCRIPTION_FIELD_NUMBER: builtins.int type: builtins.str index: builtins.int + description: builtins.str @property def operand_number(self) -> global___Integer: """this can be positive (range: u64), negative (range: i64), or a double.""" - description: builtins.str + def __init__( self, *, @@ -1069,13 +1079,13 @@ class OperandNumberFeature(google.protobuf.message.Message): operand_number: global___Integer | None = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description", "operand_number", b"operand_number"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description", "index", b"index", "operand_number", b"operand_number", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description", "operand_number", b"operand_number"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "description", b"description", "index", b"index", "operand_number", b"operand_number", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___OperandNumberFeature = OperandNumberFeature -@typing_extensions.final +@typing.final class OperandOffsetFeature(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1085,9 +1095,9 @@ class OperandOffsetFeature(google.protobuf.message.Message): DESCRIPTION_FIELD_NUMBER: builtins.int type: builtins.str index: builtins.int + description: builtins.str @property def operand_offset(self) -> global___Integer: ... - description: builtins.str def __init__( self, *, @@ -1096,44 +1106,44 @@ class OperandOffsetFeature(google.protobuf.message.Message): operand_offset: global___Integer | None = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description", "operand_offset", b"operand_offset"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description", "index", b"index", "operand_offset", b"operand_offset", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description", "operand_offset", b"operand_offset"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "description", b"description", "index", b"index", "operand_offset", b"operand_offset", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___OperandOffsetFeature = OperandOffsetFeature -@typing_extensions.final +@typing.final class ProcessFeatureCount(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor ADDRESS_FIELD_NUMBER: builtins.int COUNT_FIELD_NUMBER: builtins.int + count: builtins.int @property def address(self) -> global___Address: ... - count: builtins.int def __init__( self, *, address: global___Address | None = ..., count: builtins.int = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["address", b"address"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["address", b"address", "count", b"count"]) -> None: ... + def HasField(self, field_name: typing.Literal["address", b"address"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["address", b"address", "count", b"count"]) -> None: ... global___ProcessFeatureCount = ProcessFeatureCount -@typing_extensions.final +@typing.final class ProcessLayout(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor ADDRESS_FIELD_NUMBER: builtins.int MATCHED_THREADS_FIELD_NUMBER: builtins.int NAME_FIELD_NUMBER: builtins.int + name: builtins.str @property def address(self) -> global___Address: ... @property def matched_threads(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ThreadLayout]: ... - name: builtins.str def __init__( self, *, @@ -1141,12 +1151,12 @@ class ProcessLayout(google.protobuf.message.Message): matched_threads: collections.abc.Iterable[global___ThreadLayout] | None = ..., name: builtins.str = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["address", b"address"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["address", b"address", "matched_threads", b"matched_threads", "name", b"name"]) -> None: ... + def HasField(self, field_name: typing.Literal["address", b"address"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["address", b"address", "matched_threads", b"matched_threads", "name", b"name"]) -> None: ... global___ProcessLayout = ProcessLayout -@typing_extensions.final +@typing.final class PropertyFeature(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1167,16 +1177,16 @@ class PropertyFeature(google.protobuf.message.Message): access: builtins.str | None = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_access", b"_access", "_description", b"_description", "access", b"access", "description", b"description"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_access", b"_access", "_description", b"_description", "access", b"access", "description", b"description", "property_", b"property_", "type", b"type"]) -> None: ... + def HasField(self, field_name: typing.Literal["_access", b"_access", "_description", b"_description", "access", b"access", "description", b"description"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_access", b"_access", "_description", b"_description", "access", b"access", "description", b"description", "property_", b"property_", "type", b"type"]) -> None: ... @typing.overload - def WhichOneof(self, oneof_group: typing_extensions.Literal["_access", b"_access"]) -> typing_extensions.Literal["access"] | None: ... + def WhichOneof(self, oneof_group: typing.Literal["_access", b"_access"]) -> typing.Literal["access"] | None: ... @typing.overload - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___PropertyFeature = PropertyFeature -@typing_extensions.final +@typing.final class RangeStatement(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1188,10 +1198,11 @@ class RangeStatement(google.protobuf.message.Message): type: builtins.str min: builtins.int max: builtins.int + description: builtins.str @property def child(self) -> global___FeatureNode: """reusing FeatureNode here to avoid duplication and list all features OSFeature, ArchFeature, ... again.""" - description: builtins.str + def __init__( self, *, @@ -1201,13 +1212,13 @@ class RangeStatement(google.protobuf.message.Message): child: global___FeatureNode | None = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "child", b"child", "description", b"description"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "child", b"child", "description", b"description", "max", b"max", "min", b"min", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "child", b"child", "description", b"description"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "child", b"child", "description", b"description", "max", b"max", "min", b"min", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___RangeStatement = RangeStatement -@typing_extensions.final +@typing.final class RegexFeature(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1224,17 +1235,17 @@ class RegexFeature(google.protobuf.message.Message): regex: builtins.str = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description", "regex", b"regex", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "description", b"description", "regex", b"regex", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___RegexFeature = RegexFeature -@typing_extensions.final +@typing.final class ResultDocument(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor - @typing_extensions.final + @typing.final class RulesEntry(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1249,8 +1260,8 @@ class ResultDocument(google.protobuf.message.Message): key: builtins.str = ..., value: global___RuleMatches | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["value", b"value"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "value", b"value"]) -> None: ... + def HasField(self, field_name: typing.Literal["value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["key", b"key", "value", b"value"]) -> None: ... META_FIELD_NUMBER: builtins.int RULES_FIELD_NUMBER: builtins.int @@ -1264,21 +1275,21 @@ class ResultDocument(google.protobuf.message.Message): meta: global___Metadata | None = ..., rules: collections.abc.Mapping[builtins.str, global___RuleMatches] | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["meta", b"meta"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["meta", b"meta", "rules", b"rules"]) -> None: ... + def HasField(self, field_name: typing.Literal["meta", b"meta"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["meta", b"meta", "rules", b"rules"]) -> None: ... global___ResultDocument = ResultDocument -@typing_extensions.final +@typing.final class RuleMatches(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor META_FIELD_NUMBER: builtins.int SOURCE_FIELD_NUMBER: builtins.int MATCHES_FIELD_NUMBER: builtins.int + source: builtins.str @property def meta(self) -> global___RuleMetadata: ... - source: builtins.str @property def matches(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Pair_Address_Match]: ... def __init__( @@ -1288,12 +1299,12 @@ class RuleMatches(google.protobuf.message.Message): source: builtins.str = ..., matches: collections.abc.Iterable[global___Pair_Address_Match] | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["meta", b"meta"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["matches", b"matches", "meta", b"meta", "source", b"source"]) -> None: ... + def HasField(self, field_name: typing.Literal["meta", b"meta"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["matches", b"matches", "meta", b"meta", "source", b"source"]) -> None: ... global___RuleMatches = RuleMatches -@typing_extensions.final +@typing.final class RuleMetadata(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1312,12 +1323,15 @@ class RuleMetadata(google.protobuf.message.Message): SCOPES_FIELD_NUMBER: builtins.int name: builtins.str namespace: builtins.str - @property - def authors(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: ... scope: global___Scope.ValueType """deprecated in v7.0. use scopes instead. """ + description: builtins.str + lib: builtins.bool + is_subscope_rule: builtins.bool + @property + def authors(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: ... @property def attack(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___AttackSpec]: ... @property @@ -1326,14 +1340,12 @@ class RuleMetadata(google.protobuf.message.Message): def references(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: ... @property def examples(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: ... - description: builtins.str - lib: builtins.bool @property def maec(self) -> global___MaecMetadata: ... - is_subscope_rule: builtins.bool @property def scopes(self) -> global___Scopes: """use scopes over scope (deprecated in v7.0).""" + def __init__( self, *, @@ -1351,12 +1363,12 @@ class RuleMetadata(google.protobuf.message.Message): is_subscope_rule: builtins.bool = ..., scopes: global___Scopes | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["maec", b"maec", "scopes", b"scopes"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["attack", b"attack", "authors", b"authors", "description", b"description", "examples", b"examples", "is_subscope_rule", b"is_subscope_rule", "lib", b"lib", "maec", b"maec", "mbc", b"mbc", "name", b"name", "namespace", b"namespace", "references", b"references", "scope", b"scope", "scopes", b"scopes"]) -> None: ... + def HasField(self, field_name: typing.Literal["maec", b"maec", "scopes", b"scopes"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["attack", b"attack", "authors", b"authors", "description", b"description", "examples", b"examples", "is_subscope_rule", b"is_subscope_rule", "lib", b"lib", "maec", b"maec", "mbc", b"mbc", "name", b"name", "namespace", b"namespace", "references", b"references", "scope", b"scope", "scopes", b"scopes"]) -> None: ... global___RuleMetadata = RuleMetadata -@typing_extensions.final +@typing.final class Sample(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1376,11 +1388,11 @@ class Sample(google.protobuf.message.Message): sha256: builtins.str = ..., path: builtins.str = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["md5", b"md5", "path", b"path", "sha1", b"sha1", "sha256", b"sha256"]) -> None: ... + def ClearField(self, field_name: typing.Literal["md5", b"md5", "path", b"path", "sha1", b"sha1", "sha256", b"sha256"]) -> None: ... global___Sample = Sample -@typing_extensions.final +@typing.final class Scopes(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1394,16 +1406,16 @@ class Scopes(google.protobuf.message.Message): static: global___Scope.ValueType | None = ..., dynamic: global___Scope.ValueType | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_dynamic", b"_dynamic", "_static", b"_static", "dynamic", b"dynamic", "static", b"static"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_dynamic", b"_dynamic", "_static", b"_static", "dynamic", b"dynamic", "static", b"static"]) -> None: ... + def HasField(self, field_name: typing.Literal["_dynamic", b"_dynamic", "_static", b"_static", "dynamic", b"dynamic", "static", b"static"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_dynamic", b"_dynamic", "_static", b"_static", "dynamic", b"dynamic", "static", b"static"]) -> None: ... @typing.overload - def WhichOneof(self, oneof_group: typing_extensions.Literal["_dynamic", b"_dynamic"]) -> typing_extensions.Literal["dynamic"] | None: ... + def WhichOneof(self, oneof_group: typing.Literal["_dynamic", b"_dynamic"]) -> typing.Literal["dynamic"] | None: ... @typing.overload - def WhichOneof(self, oneof_group: typing_extensions.Literal["_static", b"_static"]) -> typing_extensions.Literal["static"] | None: ... + def WhichOneof(self, oneof_group: typing.Literal["_static", b"_static"]) -> typing.Literal["static"] | None: ... global___Scopes = Scopes -@typing_extensions.final +@typing.final class SectionFeature(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1420,13 +1432,13 @@ class SectionFeature(google.protobuf.message.Message): section: builtins.str = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description", "section", b"section", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "description", b"description", "section", b"section", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___SectionFeature = SectionFeature -@typing_extensions.final +@typing.final class SomeStatement(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1443,13 +1455,13 @@ class SomeStatement(google.protobuf.message.Message): count: builtins.int = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "count", b"count", "description", b"description", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "count", b"count", "description", b"description", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___SomeStatement = SomeStatement -@typing_extensions.final +@typing.final class StatementNode(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1476,13 +1488,13 @@ class StatementNode(google.protobuf.message.Message): subscope: global___SubscopeStatement | None = ..., compound: global___CompoundStatement | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["compound", b"compound", "range", b"range", "some", b"some", "statement", b"statement", "subscope", b"subscope"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["compound", b"compound", "range", b"range", "some", b"some", "statement", b"statement", "subscope", b"subscope", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["statement", b"statement"]) -> typing_extensions.Literal["range", "some", "subscope", "compound"] | None: ... + def HasField(self, field_name: typing.Literal["compound", b"compound", "range", b"range", "some", b"some", "statement", b"statement", "subscope", b"subscope"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["compound", b"compound", "range", b"range", "some", b"some", "statement", b"statement", "subscope", b"subscope", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["statement", b"statement"]) -> typing.Literal["range", "some", "subscope", "compound"] | None: ... global___StatementNode = StatementNode -@typing_extensions.final +@typing.final class StaticAnalysis(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1522,12 +1534,12 @@ class StaticAnalysis(google.protobuf.message.Message): feature_counts: global___StaticFeatureCounts | None = ..., library_functions: collections.abc.Iterable[global___LibraryFunction] | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["base_address", b"base_address", "feature_counts", b"feature_counts", "layout", b"layout"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["arch", b"arch", "base_address", b"base_address", "extractor", b"extractor", "feature_counts", b"feature_counts", "format", b"format", "layout", b"layout", "library_functions", b"library_functions", "os", b"os", "rules", b"rules"]) -> None: ... + def HasField(self, field_name: typing.Literal["base_address", b"base_address", "feature_counts", b"feature_counts", "layout", b"layout"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["arch", b"arch", "base_address", b"base_address", "extractor", b"extractor", "feature_counts", b"feature_counts", "format", b"format", "layout", b"layout", "library_functions", b"library_functions", "os", b"os", "rules", b"rules"]) -> None: ... global___StaticAnalysis = StaticAnalysis -@typing_extensions.final +@typing.final class StaticFeatureCounts(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1542,11 +1554,11 @@ class StaticFeatureCounts(google.protobuf.message.Message): file: builtins.int = ..., functions: collections.abc.Iterable[global___FunctionFeatureCount] | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["file", b"file", "functions", b"functions"]) -> None: ... + def ClearField(self, field_name: typing.Literal["file", b"file", "functions", b"functions"]) -> None: ... global___StaticFeatureCounts = StaticFeatureCounts -@typing_extensions.final +@typing.final class StaticLayout(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1558,11 +1570,11 @@ class StaticLayout(google.protobuf.message.Message): *, functions: collections.abc.Iterable[global___FunctionLayout] | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["functions", b"functions"]) -> None: ... + def ClearField(self, field_name: typing.Literal["functions", b"functions"]) -> None: ... global___StaticLayout = StaticLayout -@typing_extensions.final +@typing.final class StringFeature(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1579,13 +1591,13 @@ class StringFeature(google.protobuf.message.Message): string: builtins.str = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description", "string", b"string", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "description", b"description", "string", b"string", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___StringFeature = StringFeature -@typing_extensions.final +@typing.final class SubscopeStatement(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1602,13 +1614,13 @@ class SubscopeStatement(google.protobuf.message.Message): scope: global___Scope.ValueType = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description", "scope", b"scope", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "description", b"description", "scope", b"scope", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___SubscopeStatement = SubscopeStatement -@typing_extensions.final +@typing.final class SubstringFeature(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1625,33 +1637,33 @@ class SubstringFeature(google.protobuf.message.Message): substring: builtins.str = ..., description: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_description", b"_description", "description", b"description", "substring", b"substring", "type", b"type"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... + def HasField(self, field_name: typing.Literal["_description", b"_description", "description", b"description"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_description", b"_description", "description", b"description", "substring", b"substring", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_description", b"_description"]) -> typing.Literal["description"] | None: ... global___SubstringFeature = SubstringFeature -@typing_extensions.final +@typing.final class CallLayout(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor ADDRESS_FIELD_NUMBER: builtins.int NAME_FIELD_NUMBER: builtins.int + name: builtins.str @property def address(self) -> global___Address: ... - name: builtins.str def __init__( self, *, address: global___Address | None = ..., name: builtins.str = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["address", b"address"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["address", b"address", "name", b"name"]) -> None: ... + def HasField(self, field_name: typing.Literal["address", b"address"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["address", b"address", "name", b"name"]) -> None: ... global___CallLayout = CallLayout -@typing_extensions.final +@typing.final class ThreadLayout(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1667,12 +1679,12 @@ class ThreadLayout(google.protobuf.message.Message): address: global___Address | None = ..., matched_calls: collections.abc.Iterable[global___CallLayout] | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["address", b"address"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["address", b"address", "matched_calls", b"matched_calls"]) -> None: ... + def HasField(self, field_name: typing.Literal["address", b"address"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["address", b"address", "matched_calls", b"matched_calls"]) -> None: ... global___ThreadLayout = ThreadLayout -@typing_extensions.final +@typing.final class Addresses(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1684,11 +1696,11 @@ class Addresses(google.protobuf.message.Message): *, address: collections.abc.Iterable[global___Address] | None = ..., ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["address", b"address"]) -> None: ... + def ClearField(self, field_name: typing.Literal["address", b"address"]) -> None: ... global___Addresses = Addresses -@typing_extensions.final +@typing.final class Pair_Address_Match(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1704,33 +1716,33 @@ class Pair_Address_Match(google.protobuf.message.Message): address: global___Address | None = ..., match: global___Match | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["address", b"address", "match", b"match"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["address", b"address", "match", b"match"]) -> None: ... + def HasField(self, field_name: typing.Literal["address", b"address", "match", b"match"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["address", b"address", "match", b"match"]) -> None: ... global___Pair_Address_Match = Pair_Address_Match -@typing_extensions.final +@typing.final class Token_Offset(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor TOKEN_FIELD_NUMBER: builtins.int OFFSET_FIELD_NUMBER: builtins.int - @property - def token(self) -> global___Integer: ... offset: builtins.int """offset is always >= 0""" + @property + def token(self) -> global___Integer: ... def __init__( self, *, token: global___Integer | None = ..., offset: builtins.int = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["token", b"token"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["offset", b"offset", "token", b"token"]) -> None: ... + def HasField(self, field_name: typing.Literal["token", b"token"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["offset", b"offset", "token", b"token"]) -> None: ... global___Token_Offset = Token_Offset -@typing_extensions.final +@typing.final class Ppid_Pid(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1746,12 +1758,12 @@ class Ppid_Pid(google.protobuf.message.Message): ppid: global___Integer | None = ..., pid: global___Integer | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["pid", b"pid", "ppid", b"ppid"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["pid", b"pid", "ppid", b"ppid"]) -> None: ... + def HasField(self, field_name: typing.Literal["pid", b"pid", "ppid", b"ppid"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["pid", b"pid", "ppid", b"ppid"]) -> None: ... global___Ppid_Pid = Ppid_Pid -@typing_extensions.final +@typing.final class Ppid_Pid_Tid(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1771,12 +1783,12 @@ class Ppid_Pid_Tid(google.protobuf.message.Message): pid: global___Integer | None = ..., tid: global___Integer | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["pid", b"pid", "ppid", b"ppid", "tid", b"tid"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["pid", b"pid", "ppid", b"ppid", "tid", b"tid"]) -> None: ... + def HasField(self, field_name: typing.Literal["pid", b"pid", "ppid", b"ppid", "tid", b"tid"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["pid", b"pid", "ppid", b"ppid", "tid", b"tid"]) -> None: ... global___Ppid_Pid_Tid = Ppid_Pid_Tid -@typing_extensions.final +@typing.final class Ppid_Pid_Tid_Id(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1800,12 +1812,12 @@ class Ppid_Pid_Tid_Id(google.protobuf.message.Message): tid: global___Integer | None = ..., id: global___Integer | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["id", b"id", "pid", b"pid", "ppid", b"ppid", "tid", b"tid"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["id", b"id", "pid", b"pid", "ppid", b"ppid", "tid", b"tid"]) -> None: ... + def HasField(self, field_name: typing.Literal["id", b"id", "pid", b"pid", "ppid", b"ppid", "tid", b"tid"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["id", b"id", "pid", b"pid", "ppid", b"ppid", "tid", b"tid"]) -> None: ... global___Ppid_Pid_Tid_Id = Ppid_Pid_Tid_Id -@typing_extensions.final +@typing.final class Integer(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1819,13 +1831,13 @@ class Integer(google.protobuf.message.Message): u: builtins.int = ..., i: builtins.int = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["i", b"i", "u", b"u", "value", b"value"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["i", b"i", "u", b"u", "value", b"value"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["value", b"value"]) -> typing_extensions.Literal["u", "i"] | None: ... + def HasField(self, field_name: typing.Literal["i", b"i", "u", b"u", "value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["i", b"i", "u", b"u", "value", b"value"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["value", b"value"]) -> typing.Literal["u", "i"] | None: ... global___Integer = Integer -@typing_extensions.final +@typing.final class Number(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -1842,8 +1854,8 @@ class Number(google.protobuf.message.Message): i: builtins.int = ..., f: builtins.float = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["f", b"f", "i", b"i", "u", b"u", "value", b"value"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["f", b"f", "i", b"i", "u", b"u", "value", b"value"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["value", b"value"]) -> typing_extensions.Literal["u", "i", "f"] | None: ... + def HasField(self, field_name: typing.Literal["f", b"f", "i", b"i", "u", b"u", "value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["f", b"f", "i", b"i", "u", b"u", "value", b"value"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["value", b"value"]) -> typing.Literal["u", "i", "f"] | None: ... global___Number = Number diff --git a/capa/render/verbose.py b/capa/render/verbose.py index 08c0707c..a89db503 100644 --- a/capa/render/verbose.py +++ b/capa/render/verbose.py @@ -126,6 +126,16 @@ def render_thread(layout: rd.DynamicLayout, addr: frz.Address) -> str: return f"{name}{{pid:{thread.process.pid},tid:{thread.tid}}}" +def render_sequence(layout: rd.DynamicLayout, addrs: list[frz.Address]) -> str: + calls: list[capa.features.address.DynamicCallAddress] = [addr.to_capa() for addr in addrs] # type: ignore + for call in calls: + assert isinstance(call, capa.features.address.DynamicCallAddress) + + pname = _get_process_name(layout, frz.Address.from_capa(calls[0].thread.process)) + call_ids = [str(call.id) for call in calls] + return f"{pname}{{pid:{call.thread.process.pid},tid:{call.thread.tid},calls:{{{','.join(call_ids)}}}}}" + + def render_call(layout: rd.DynamicLayout, addr: frz.Address) -> str: call = addr.to_capa() assert isinstance(call, capa.features.address.DynamicCallAddress) @@ -318,7 +328,7 @@ def render_rules(console: Console, doc: rd.ResultDocument): lines = [render_process(doc.meta.analysis.layout, loc) for loc in locations] elif rule.meta.scopes.dynamic == capa.rules.Scope.THREAD: lines = [render_thread(doc.meta.analysis.layout, loc) for loc in locations] - elif rule.meta.scopes.dynamic == capa.rules.Scope.CALL: + elif rule.meta.scopes.dynamic in (capa.rules.Scope.CALL, capa.rules.Scope.SEQUENCE): # because we're only in verbose mode, we won't show the full call details (name, args, retval) # we'll only show the details of the thread in which the calls are found. # so select the thread locations and render those. diff --git a/capa/render/vverbose.py b/capa/render/vverbose.py index 428dffcb..5a2f1718 100644 --- a/capa/render/vverbose.py +++ b/capa/render/vverbose.py @@ -311,6 +311,36 @@ def render_match( render_match(console, layout, rule, child, indent=indent + 1, mode=child_mode) +def collect_call_locations( + match: rd.Match, + mode=MODE_SUCCESS, +): + """ + Find all the DynamicCallAddress locations in the given match, recursively. + Useful to collect the calls used to match a sequence scoped rule. + """ + if isinstance(match.node, rd.StatementNode): + if ( + isinstance(match.node.statement, rd.CompoundStatement) + and match.node.statement.type == rd.CompoundStatementType.NOT + ): + child_mode = MODE_FAILURE if mode == MODE_SUCCESS else MODE_SUCCESS + for child in match.children: + yield from collect_call_locations(child, child_mode) + else: + for child in match.children: + yield from collect_call_locations(child, mode) + elif isinstance(match.node, rd.FeatureNode): + for location in match.locations: + if location.type != frz.AddressType.CALL: + continue + if mode == MODE_FAILURE: + continue + yield location + else: + raise ValueError("unexpected node type") + + def render_rules(console: Console, doc: rd.ResultDocument): """ like: @@ -450,6 +480,9 @@ def render_rules(console: Console, doc: rd.ResultDocument): console.write(v.render_process(doc.meta.analysis.layout, location)) elif rule.meta.scopes.dynamic == capa.rules.Scope.THREAD: console.write(v.render_thread(doc.meta.analysis.layout, location)) + elif rule.meta.scopes.dynamic == capa.rules.Scope.SEQUENCE: + calls = sorted(set(collect_call_locations(match))) + console.write(hanging_indent(v.render_sequence(doc.meta.analysis.layout, calls), indent=1)) elif rule.meta.scopes.dynamic == capa.rules.Scope.CALL: console.write(hanging_indent(v.render_call(doc.meta.analysis.layout, location), indent=1)) else: diff --git a/capa/rules/__init__.py b/capa/rules/__init__.py index 54b8f9ba..2b0813b6 100644 --- a/capa/rules/__init__.py +++ b/capa/rules/__init__.py @@ -86,6 +86,7 @@ class Scope(str, Enum): FILE = "file" PROCESS = "process" THREAD = "thread" + SEQUENCE = "sequence" CALL = "call" FUNCTION = "function" BASIC_BLOCK = "basic block" @@ -114,6 +115,7 @@ DYNAMIC_SCOPES = { Scope.GLOBAL, Scope.PROCESS, Scope.THREAD, + Scope.SEQUENCE, Scope.CALL, } @@ -199,6 +201,7 @@ SUPPORTED_FEATURES: dict[str, set] = { capa.features.common.MatchedRule, }, Scope.THREAD: set(), + Scope.SEQUENCE: set(), Scope.CALL: { capa.features.common.MatchedRule, capa.features.common.Regex, @@ -253,11 +256,14 @@ SUPPORTED_FEATURES[Scope.FUNCTION].update(SUPPORTED_FEATURES[Scope.GLOBAL]) SUPPORTED_FEATURES[Scope.FILE].update(SUPPORTED_FEATURES[Scope.GLOBAL]) SUPPORTED_FEATURES[Scope.PROCESS].update(SUPPORTED_FEATURES[Scope.GLOBAL]) SUPPORTED_FEATURES[Scope.THREAD].update(SUPPORTED_FEATURES[Scope.GLOBAL]) +SUPPORTED_FEATURES[Scope.SEQUENCE].update(SUPPORTED_FEATURES[Scope.GLOBAL]) SUPPORTED_FEATURES[Scope.CALL].update(SUPPORTED_FEATURES[Scope.GLOBAL]) -# all call scope features are also thread features -SUPPORTED_FEATURES[Scope.THREAD].update(SUPPORTED_FEATURES[Scope.CALL]) +# all call scope features are also sequence features +SUPPORTED_FEATURES[Scope.SEQUENCE].update(SUPPORTED_FEATURES[Scope.CALL]) +# all sequence scope features (and therefore, call features) are also thread features +SUPPORTED_FEATURES[Scope.THREAD].update(SUPPORTED_FEATURES[Scope.SEQUENCE]) # all thread scope features are also process features SUPPORTED_FEATURES[Scope.PROCESS].update(SUPPORTED_FEATURES[Scope.THREAD]) @@ -636,8 +642,19 @@ def build_statements(d, scopes: Scopes): Scope.THREAD, build_statements(d[key][0], Scopes(dynamic=Scope.THREAD)), description=description ) + elif key == "sequence": + if all(s not in scopes for s in (Scope.FILE, Scope.PROCESS, Scope.THREAD)): + raise InvalidRule("sequence subscope supported only for the process and thread scopes") + + if len(d[key]) != 1: + raise InvalidRule("subscope must have exactly one child statement") + + return ceng.Subscope( + Scope.SEQUENCE, build_statements(d[key][0], Scopes(dynamic=Scope.SEQUENCE)), description=description + ) + elif key == "call": - if all(s not in scopes for s in (Scope.FILE, Scope.PROCESS, Scope.THREAD, Scope.CALL)): + if all(s not in scopes for s in (Scope.FILE, Scope.PROCESS, Scope.THREAD, Scope.SEQUENCE, Scope.CALL)): raise InvalidRule("call subscope supported only for the process, thread, and call scopes") if len(d[key]) != 1: @@ -1383,6 +1400,7 @@ class RuleSet: scopes = ( Scope.CALL, + Scope.SEQUENCE, Scope.THREAD, Scope.PROCESS, Scope.INSTRUCTION, @@ -1413,6 +1431,10 @@ class RuleSet: def thread_rules(self): return self.rules_by_scope[Scope.THREAD] + @property + def sequence_rules(self): + return self.rules_by_scope[Scope.SEQUENCE] + @property def call_rules(self): return self.rules_by_scope[Scope.CALL] diff --git a/scripts/lint.py b/scripts/lint.py index 8f8627b5..7bf432e0 100644 --- a/scripts/lint.py +++ b/scripts/lint.py @@ -194,6 +194,7 @@ class InvalidDynamicScope(Lint): "file", "process", "thread", + "sequence", "call", "unsupported", ) diff --git a/tests/test_dynamic_sequence_scope.py b/tests/test_dynamic_sequence_scope.py new file mode 100644 index 00000000..810dc5b3 --- /dev/null +++ b/tests/test_dynamic_sequence_scope.py @@ -0,0 +1,256 @@ +# Copyright (C) 2024 Mandiant, Inc. All Rights Reserved. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: [package root]/LICENSE.txt +# Unless required by applicable law or agreed to in writing, software distributed under the License +# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and limitations under the License. + + +# tests/data/dynamic/cape/v2.2/0000a65749f5902c4d82ffa701198038f0b4870b00a27cfca109f8f933476d82.json.gz +# +# proc: 0000A65749F5902C4D82.exe (ppid=2456, pid=3052) +# ... +# thread: 3064 +# call 8: GetSystemTimeAsFileTime() +# call 9: GetSystemInfo() +# call 10: LdrGetDllHandle(1974337536, kernel32.dll) +# call 11: LdrGetProcedureAddress(2010595649, 0, AddVectoredExceptionHandler, 1974337536, kernel32.dll) +# call 12: LdrGetDllHandle(1974337536, kernel32.dll) +# call 13: LdrGetProcedureAddress(2010595072, 0, RemoveVectoredExceptionHandler, 1974337536, kernel32.dll) +# call 14: RtlAddVectoredExceptionHandler(1921490089, 0) +# call 15: GetSystemTime() +# call 16: NtAllocateVirtualMemory(no, 4, 786432, 4784128, 4294967295) +# call 17: NtAllocateVirtualMemory(no, 4, 12288, 4784128, 4294967295) +# call 18: GetSystemInfo() +# ... +# ... + +import textwrap +from functools import lru_cache + +import fixtures + +import capa.main +import capa.capabilities.dynamic +from capa.features.extractors.base_extractor import ThreadFilter, DynamicFeatureExtractor + + +def filter_threads(extractor: DynamicFeatureExtractor, ppid: int, pid: int, tid: int) -> DynamicFeatureExtractor: + for ph in extractor.get_processes(): + if (ph.address.ppid, ph.address.pid) != (ppid, pid): + continue + + for th in extractor.get_threads(ph): + if th.address.tid != tid: + continue + + return ThreadFilter( + extractor, + { + th.address, + }, + ) + + raise ValueError("failed to find target thread") + + +@lru_cache(maxsize=1) +def get_0000a657_thread3064(): + extractor = fixtures.get_cape_extractor(fixtures.get_data_path_by_name("0000a657")) + extractor = filter_threads(extractor, 2456, 3052, 3064) + return extractor + + +def get_call_ids(matches): + for address, _ in matches: + yield address.id + + +# sanity check: match the first call +# +# proc: 0000A65749F5902C4D82.exe (ppid=2456, pid=3052) +# thread: 3064 +# call 8: GetSystemTimeAsFileTime() +def test_dynamic_call_scope(): + extractor = get_0000a657_thread3064() + + rule = textwrap.dedent( + """ + rule: + meta: + name: test rule + scopes: + static: unsupported + dynamic: call + features: + - api: GetSystemTimeAsFileTime + """ + ) + + r = capa.rules.Rule.from_yaml(rule) + ruleset = capa.rules.RuleSet([r]) + + matches, features = capa.capabilities.dynamic.find_dynamic_capabilities(ruleset, extractor, disable_progress=True) + assert r.name in matches + assert 8 in get_call_ids(matches[r.name]) + + +# match the first 5-tuple sequence. +# +# proc: 0000A65749F5902C4D82.exe (ppid=2456, pid=3052) +# thread: 3064 +# call 8: GetSystemTimeAsFileTime() +# call 9: GetSystemInfo() +# call 10: LdrGetDllHandle(1974337536, kernel32.dll) +# call 11: LdrGetProcedureAddress(2010595649, 0, AddVectoredExceptionHandler, 1974337536, kernel32.dll) +# call 12: LdrGetDllHandle(1974337536, kernel32.dll) +def test_dynamic_sequence_scope(): + extractor = get_0000a657_thread3064() + + rule = textwrap.dedent( + """ + rule: + meta: + name: test rule + scopes: + static: unsupported + dynamic: sequence + features: + - and: + - api: GetSystemTimeAsFileTime + - api: GetSystemInfo + - api: LdrGetDllHandle + - api: LdrGetProcedureAddress + - count(api(LdrGetDllHandle)): 2 + """ + ) + + r = capa.rules.Rule.from_yaml(rule) + ruleset = capa.rules.RuleSet([r]) + + matches, features = capa.capabilities.dynamic.find_dynamic_capabilities(ruleset, extractor, disable_progress=True) + assert r.name in matches + assert 12 in get_call_ids(matches[r.name]) + + +# show the sequence is only 5 calls long, and doesn't match beyond that 5-tuple. +# +# proc: 0000A65749F5902C4D82.exe (ppid=2456, pid=3052) +# thread: 3064 +# call 8: GetSystemTimeAsFileTime() +# call 9: GetSystemInfo() +# call 10: LdrGetDllHandle(1974337536, kernel32.dll) +# call 11: LdrGetProcedureAddress(2010595649, 0, AddVectoredExceptionHandler, 1974337536, kernel32.dll) +# call 12: LdrGetDllHandle(1974337536, kernel32.dll) +# call 13: LdrGetProcedureAddress(2010595072, 0, RemoveVectoredExceptionHandler, 1974337536, kernel32.dll) +# call 14: RtlAddVectoredExceptionHandler(1921490089, 0) +# call 15: GetSystemTime() +# call 16: NtAllocateVirtualMemory(no, 4, 786432, 4784128, 4294967295) +def test_dynamic_sequence_scope2(): + extractor = get_0000a657_thread3064() + + rule = textwrap.dedent( + """ + rule: + meta: + name: test rule + scopes: + static: unsupported + dynamic: sequence + features: + - and: + - api: GetSystemTimeAsFileTime + - api: RtlAddVectoredExceptionHandler + """ + ) + + r = capa.rules.Rule.from_yaml(rule) + ruleset = capa.rules.RuleSet([r]) + + matches, features = capa.capabilities.dynamic.find_dynamic_capabilities(ruleset, extractor, disable_progress=True) + assert r.name not in matches + + +# show how you might use a sequence rule: to match a small window for a collection of features. +# +# proc: 0000A65749F5902C4D82.exe (ppid=2456, pid=3052) +# thread: 3064 +# call 10: LdrGetDllHandle(1974337536, kernel32.dll) +# call 11: LdrGetProcedureAddress(2010595649, 0, AddVectoredExceptionHandler, 1974337536, kernel32.dll) +# call 12: ... +# call 13: ... +# call 14: RtlAddVectoredExceptionHandler(1921490089, 0) +def test_dynamic_sequence_example(): + extractor = get_0000a657_thread3064() + + rule = textwrap.dedent( + """ + rule: + meta: + name: test rule + scopes: + static: unsupported + dynamic: sequence + features: + - and: + - call: + - and: + - api: LdrGetDllHandle + - string: "kernel32.dll" + - call: + - and: + - api: LdrGetProcedureAddress + - string: "AddVectoredExceptionHandler" + - api: RtlAddVectoredExceptionHandler + """ + ) + + r = capa.rules.Rule.from_yaml(rule) + ruleset = capa.rules.RuleSet([r]) + + matches, features = capa.capabilities.dynamic.find_dynamic_capabilities(ruleset, extractor, disable_progress=True) + assert r.name in matches + assert 14 in get_call_ids(matches[r.name]) + + +# show how sequences that overlap a single event are handled. +# TODO(williballenthin): but I think we really just want one match for this, not copies of the same thing. +# +# proc: 0000A65749F5902C4D82.exe (ppid=2456, pid=3052) +# thread: 3064 +# ... +# call 10: ... +# call 11: LdrGetProcedureAddress(2010595649, 0, AddVectoredExceptionHandler, 1974337536, kernel32.dll) +# call 12: ... +# call 13: ... +# call 14: ... +# call 15: ... +# ... +def test_dynamic_sequence_multiple_sequences_overlapping_single_event(): + extractor = get_0000a657_thread3064() + + rule = textwrap.dedent( + """ + rule: + meta: + name: test rule + scopes: + static: unsupported + dynamic: sequence + features: + - and: + - call: + - and: + - api: LdrGetProcedureAddress + - string: "AddVectoredExceptionHandler" + """ + ) + + r = capa.rules.Rule.from_yaml(rule) + ruleset = capa.rules.RuleSet([r]) + + matches, features = capa.capabilities.dynamic.find_dynamic_capabilities(ruleset, extractor, disable_progress=True) + assert r.name in matches + assert [11, 12, 13, 14, 15] == list(get_call_ids(matches[r.name])) + diff --git a/tests/test_proto.py b/tests/test_proto.py index 8e6e12bd..474efc01 100644 --- a/tests/test_proto.py +++ b/tests/test_proto.py @@ -129,6 +129,7 @@ def test_scope_to_pb2(): assert capa.render.proto.scope_to_pb2(capa.rules.Scope.INSTRUCTION) == capa_pb2.SCOPE_INSTRUCTION assert capa.render.proto.scope_to_pb2(capa.rules.Scope.PROCESS) == capa_pb2.SCOPE_PROCESS assert capa.render.proto.scope_to_pb2(capa.rules.Scope.THREAD) == capa_pb2.SCOPE_THREAD + assert capa.render.proto.scope_to_pb2(capa.rules.Scope.SEQUENCE) == capa_pb2.SCOPE_SEQUENCE assert capa.render.proto.scope_to_pb2(capa.rules.Scope.CALL) == capa_pb2.SCOPE_CALL