From 0358b46fcd57263720428728246aa745fecd0803 Mon Sep 17 00:00:00 2001 From: Pratham Chauhan Date: Thu, 23 Mar 2023 18:07:03 +0530 Subject: [PATCH 01/79] add FORMAT_RESULT --- capa/features/common.py | 1 + capa/features/extractors/common.py | 9 ++++++++- capa/main.py | 19 ++++++++++++------- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/capa/features/common.py b/capa/features/common.py index d2f1a4ff..b6c89ed9 100644 --- a/capa/features/common.py +++ b/capa/features/common.py @@ -448,6 +448,7 @@ FORMAT_AUTO = "auto" FORMAT_SC32 = "sc32" FORMAT_SC64 = "sc64" FORMAT_FREEZE = "freeze" +FORMAT_RESULT = "result" FORMAT_UNKNOWN = "unknown" diff --git a/capa/features/extractors/common.py b/capa/features/extractors/common.py index d72fcefd..dc5d1c3a 100644 --- a/capa/features/extractors/common.py +++ b/capa/features/extractors/common.py @@ -10,7 +10,7 @@ import capa.features import capa.features.extractors.elf import capa.features.extractors.pefile import capa.features.extractors.strings -from capa.features.common import OS, FORMAT_PE, FORMAT_ELF, OS_WINDOWS, FORMAT_FREEZE, Arch, Format, String, Feature +from capa.features.common import OS, FORMAT_PE, FORMAT_ELF, OS_ANY, OS_WINDOWS, FORMAT_FREEZE, FORMAT_RESULT, ARCH_ANY, Arch, Format, String, Feature from capa.features.freeze import is_freeze from capa.features.address import NO_ADDRESS, Address, FileOffsetAddress @@ -35,6 +35,8 @@ def extract_format(buf) -> Iterator[Tuple[Feature, Address]]: yield Format(FORMAT_ELF), NO_ADDRESS elif is_freeze(buf): yield Format(FORMAT_FREEZE), NO_ADDRESS + elif buf.startswith(b"{\"meta\":"): + yield Format(FORMAT_RESULT), NO_ADDRESS else: # we likely end up here: # 1. handling a file format (e.g. macho) @@ -51,6 +53,9 @@ def extract_arch(buf) -> Iterator[Tuple[Feature, Address]]: elif buf.startswith(b"\x7fELF"): with contextlib.closing(io.BytesIO(buf)) as f: arch = capa.features.extractors.elf.detect_elf_arch(f) + + elif buf.startswith(b"{\"meta\":"): + arch = ARCH_ANY if arch not in capa.features.common.VALID_ARCH: logger.debug("unsupported arch: %s", arch) @@ -79,6 +84,8 @@ def extract_os(buf) -> Iterator[Tuple[Feature, Address]]: elif buf.startswith(b"\x7fELF"): with contextlib.closing(io.BytesIO(buf)) as f: os = capa.features.extractors.elf.detect_elf_os(f) + elif buf.startswith(b"{\"meta\":"): + os = OS_ANY if os not in capa.features.common.VALID_OS: logger.debug("unsupported os: %s", os) diff --git a/capa/main.py b/capa/main.py index 6d024778..338a3f34 100644 --- a/capa/main.py +++ b/capa/main.py @@ -65,6 +65,7 @@ from capa.features.common import ( FORMAT_SC64, FORMAT_DOTNET, FORMAT_FREEZE, + FORMAT_RESULT ) from capa.features.address import NO_ADDRESS, Address from capa.features.extractors.base_extractor import BBHandle, InsnHandle, FunctionHandle, FeatureExtractor @@ -1123,8 +1124,11 @@ def main(argv=None): if not (args.verbose or args.vverbose or args.json): logger.debug("file limitation short circuit, won't analyze fully.") return E_FILE_LIMITATION - - if format_ == FORMAT_FREEZE: + if format_ == FORMAT_RESULT: + with open(args.sample, "rb") as f: + buf = f.read() + print(buf) + elif format_ == FORMAT_FREEZE: with open(args.sample, "rb") as f: extractor = capa.features.freeze.load(f.read()) else: @@ -1153,12 +1157,13 @@ def main(argv=None): except UnsupportedOSError: log_unsupported_os_error() return E_INVALID_FILE_OS + + if not FORMAT_RESULT: + meta = collect_metadata(argv, args.sample, args.rules, extractor) - meta = collect_metadata(argv, args.sample, args.rules, extractor) - - capabilities, counts = find_capabilities(rules, extractor, disable_progress=args.quiet) - meta["analysis"].update(counts) - meta["analysis"]["layout"] = compute_layout(rules, extractor, capabilities) + capabilities, counts = find_capabilities(rules, extractor, disable_progress=args.quiet) + meta["analysis"].update(counts) + meta["analysis"]["layout"] = compute_layout(rules, extractor, capabilities) if has_file_limitation(rules, capabilities): # bail if capa encountered file limitation e.g. a packed binary From 3e98115dc28673da4745fe40ed78b90820576fc0 Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Thu, 23 Mar 2023 16:11:21 +0100 Subject: [PATCH 02/79] main: fix variable shadowing module os --- capa/main.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/capa/main.py b/capa/main.py index f5f1178a..a3744032 100644 --- a/capa/main.py +++ b/capa/main.py @@ -497,7 +497,7 @@ def get_workspace(path, format_, sigpaths): def get_extractor( path: str, format_: str, - os: str, + os_: str, backend: str, sigpaths: List[str], should_save_workspace=False, @@ -516,7 +516,7 @@ def get_extractor( if not is_supported_arch(path): raise UnsupportedArchError() - if os == OS_AUTO and not is_supported_os(path): + if os_ == OS_AUTO and not is_supported_os(path): raise UnsupportedOSError() if format_ == FORMAT_DOTNET: @@ -568,7 +568,7 @@ def get_extractor( else: logger.debug("CAPA_SAVE_WORKSPACE unset, not saving workspace") - return capa.features.extractors.viv.extractor.VivisectFeatureExtractor(vw, path, os) + return capa.features.extractors.viv.extractor.VivisectFeatureExtractor(vw, path, os_) def get_file_extractors(sample: str, format_: str) -> List[FeatureExtractor]: From 0ff22d319fb58d624367f05ddb32a4c92dfc4c91 Mon Sep 17 00:00:00 2001 From: Pratham Chauhan Date: Fri, 24 Mar 2023 01:22:29 +0530 Subject: [PATCH 03/79] fix --- capa/main.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/capa/main.py b/capa/main.py index 338a3f34..1463c6e2 100644 --- a/capa/main.py +++ b/capa/main.py @@ -1126,8 +1126,7 @@ def main(argv=None): return E_FILE_LIMITATION if format_ == FORMAT_RESULT: with open(args.sample, "rb") as f: - buf = f.read() - print(buf) + buf = f.read() elif format_ == FORMAT_FREEZE: with open(args.sample, "rb") as f: extractor = capa.features.freeze.load(f.read()) @@ -1165,11 +1164,11 @@ def main(argv=None): meta["analysis"].update(counts) meta["analysis"]["layout"] = compute_layout(rules, extractor, capabilities) - if has_file_limitation(rules, capabilities): - # bail if capa encountered file limitation e.g. a packed binary - # do show the output in verbose mode, though. - if not (args.verbose or args.vverbose or args.json): - return E_FILE_LIMITATION + if has_file_limitation(rules, capabilities): + # bail if capa encountered file limitation e.g. a packed binary + # do show the output in verbose mode, though. + if not (args.verbose or args.vverbose or args.json): + return E_FILE_LIMITATION if args.json: print(capa.render.json.render(meta, rules, capabilities)) From 248229a383e8ae0fcba4537f8cd5ef8f5cb100df Mon Sep 17 00:00:00 2001 From: Pratham Chauhan Date: Fri, 24 Mar 2023 10:29:37 +0530 Subject: [PATCH 04/79] Functioning parse_raw --- capa/main.py | 7 ++++--- capa/render/result_document.py | 29 ++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/capa/main.py b/capa/main.py index 1463c6e2..320a2b22 100644 --- a/capa/main.py +++ b/capa/main.py @@ -1126,7 +1126,9 @@ def main(argv=None): return E_FILE_LIMITATION if format_ == FORMAT_RESULT: with open(args.sample, "rb") as f: - buf = f.read() + buf = f.read() + buf.decode("utf-8") + meta, rules, capabilities = capa.render.result_document.ResultDocument.parse_raw(buf) elif format_ == FORMAT_FREEZE: with open(args.sample, "rb") as f: extractor = capa.features.freeze.load(f.read()) @@ -1156,8 +1158,7 @@ def main(argv=None): except UnsupportedOSError: log_unsupported_os_error() return E_INVALID_FILE_OS - - if not FORMAT_RESULT: + meta = collect_metadata(argv, args.sample, args.rules, extractor) capabilities, counts = find_capabilities(rules, extractor, disable_progress=args.quiet) diff --git a/capa/render/result_document.py b/capa/render/result_document.py index 71bdb6bd..3449d9f6 100644 --- a/capa/render/result_document.py +++ b/capa/render/result_document.py @@ -6,6 +6,7 @@ # 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. import datetime +import json from typing import Any, Dict, Tuple, Union, Optional from pydantic import Field, BaseModel @@ -16,7 +17,7 @@ import capa.features.common import capa.features.freeze as frz import capa.features.address import capa.features.freeze.features as frzf -from capa.rules import RuleSet +from capa.rules import Rule, RuleSet from capa.engine import MatchResults from capa.helpers import assert_never @@ -540,3 +541,29 @@ class ResultDocument(BaseModel): ) return ResultDocument(meta=Metadata.from_capa(meta), rules=rule_matches) + + @classmethod + def parse_raw(cls, raw: str): + data = json.loads(raw) + result_doc = ResultDocument(**data) + meta = result_doc.meta + + rules = {} + capabilities = {} + for rule_name, rule_match in result_doc.rules.items(): + # Extract the rule definition and metadata + rule_definition = rule_match.source + rule_metadata = rule_match.meta + + # Add the rule to the rules dictionary + rules[rule_name] = (rule_metadata, rule_definition) + + # Extract the capabilities from the RuleMatches object + for address, match in rule_match.matches: + if address not in capabilities: + capabilities[address] = [] + + capabilities[address].append((rule_name, match)) + return meta , rules, capabilities + + \ No newline at end of file From fbb348bc823da695c218a9136ffae14ecd4f3bf0 Mon Sep 17 00:00:00 2001 From: AG <98327736+ggold7046@users.noreply.github.com> Date: Fri, 24 Mar 2023 20:50:45 +0530 Subject: [PATCH 05/79] Update utils.py Changed the colour/highlight to "cyan" instead of "blue" for easy noticing. --- capa/render/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/capa/render/utils.py b/capa/render/utils.py index c65b705b..20a817d7 100644 --- a/capa/render/utils.py +++ b/capa/render/utils.py @@ -16,7 +16,7 @@ import capa.render.result_document as rd def bold(s: str) -> str: """draw attention to the given string""" - return termcolor.colored(s, "blue") + return termcolor.colored(s, "cyan") def bold2(s: str) -> str: From 3f2e698684799cc1ba67489cd2a0ba5423c8fe24 Mon Sep 17 00:00:00 2001 From: manasghandat Date: Fri, 24 Mar 2023 22:20:37 +0530 Subject: [PATCH 06/79] fix mypy issue --- capa/render/proto/__init__.py | 67 +-- capa/render/proto/capa_pb2.py | 240 ++++----- capa/render/proto/capa_pb2.pyi | 889 ++++++++++++++++++++++++++++----- 3 files changed, 930 insertions(+), 266 deletions(-) diff --git a/capa/render/proto/__init__.py b/capa/render/proto/__init__.py index 58486f43..0b43f2c1 100644 --- a/capa/render/proto/__init__.py +++ b/capa/render/proto/__init__.py @@ -502,27 +502,36 @@ def metadata_from_pb2(meta: capa_pb2.Metadata) -> rd.Metadata: rules=tuple(meta.analysis.rules), base_address=addr_from_pb2(meta.analysis.base_address), layout=rd.Layout( - functions=[ - rd.FunctionLayout( - address=addr_from_pb2(f.address), - matched_basic_blocks=[ - rd.BasicBlockLayout(address=addr_from_pb2(bb.address)) for bb in f.matched_basic_blocks - ], - ) - for f in meta.analysis.layout.functions - ] + functions=tuple( + [ + rd.FunctionLayout( + address=addr_from_pb2(f.address), + matched_basic_blocks=tuple( + [ + rd.BasicBlockLayout(address=addr_from_pb2(bb.address)) + for bb in f.matched_basic_blocks + ] + ), + ) + for f in meta.analysis.layout.functions + ] + ) ), feature_counts=rd.FeatureCounts( file=meta.analysis.feature_counts.file, - functions=[ - rd.FunctionFeatureCount(address=addr_from_pb2(f.address), count=f.count) - for f in meta.analysis.feature_counts.functions - ], + functions=tuple( + [ + rd.FunctionFeatureCount(address=addr_from_pb2(f.address), count=f.count) + for f in meta.analysis.feature_counts.functions + ] + ), + ), + library_functions=tuple( + [ + rd.LibraryFunction(address=addr_from_pb2(lf.address), name=lf.name) + for lf in meta.analysis.library_functions + ] ), - library_functions=[ - rd.LibraryFunction(address=addr_from_pb2(lf.address), name=lf.name) - for lf in meta.analysis.library_functions - ], ), ) @@ -585,13 +594,13 @@ def feature_from_pb2(f: capa_pb2.FeatureNode) -> frzf.Feature: return frzf.ExportFeature(export=ff.export, description=ff.description or None) elif type_ == "import_": ff = f.import_ - return frzf.ImportFeature(import_=ff.import_, description=ff.description or None) + return frzf.ImportFeature(import_=ff.import_, description=ff.description or None) # type: ignore elif type_ == "section": ff = f.section return frzf.SectionFeature(section=ff.section, description=ff.description or None) elif type_ == "function_name": ff = f.function_name - return frzf.FunctionNameFeature(function_name=ff.function_name, description=ff.description or None) + return frzf.FunctionNameFeature(function_name=ff.function_name, description=ff.description or None) # type: ignore elif type_ == "substring": ff = f.substring return frzf.SubstringFeature(substring=ff.substring, description=ff.description or None) @@ -603,7 +612,7 @@ def feature_from_pb2(f: capa_pb2.FeatureNode) -> frzf.Feature: return frzf.StringFeature(string=ff.string, description=ff.description or None) elif type_ == "class_": ff = f.class_ - return frzf.ClassFeature(class_=ff.class_, description=ff.description or None) + return frzf.ClassFeature(class_=ff.class_, description=ff.description or None) # type: ignore elif type_ == "namespace": ff = f.namespace return frzf.NamespaceFeature(namespace=ff.namespace, description=ff.description or None) @@ -629,12 +638,12 @@ def feature_from_pb2(f: capa_pb2.FeatureNode) -> frzf.Feature: ff = f.operand_number return frzf.OperandNumberFeature( index=ff.index, operand_number=number_from_pb2(ff.operand_number), description=ff.description or None - ) + ) # type: ignore elif type_ == "operand_offset": ff = f.operand_offset return frzf.OperandOffsetFeature( index=ff.index, operand_offset=int_from_pb2(ff.operand_offset), description=ff.description or None - ) + ) # type: ignore elif type_ == "basic_block": ff = f.basic_block return frzf.BasicBlockFeature(description=ff.description or None) @@ -651,16 +660,16 @@ def match_from_pb2(match: capa_pb2.Match) -> rd.Match: return rd.Match( success=match.success, node=rd.StatementNode(statement=statement_from_pb2(match.statement)), - children=children, - locations=locations, + children=tuple(children), + locations=tuple(locations), captures={}, ) elif node_type == "feature": return rd.Match( success=match.success, node=rd.FeatureNode(feature=feature_from_pb2(match.feature)), - children=children, - locations=locations, + children=tuple(children), + locations=tuple(locations), captures={capture: tuple(map(addr_from_pb2, locs.address)) for capture, locs in match.captures.items()}, ) else: @@ -694,7 +703,8 @@ def maec_from_pb2(pb: capa_pb2.MaecMetadata) -> rd.MaecMetadata: malware_family=pb.malware_family or None, malware_category=pb.malware_category or None, malware_category_ov=pb.malware_category_ov or None, - ) + ) # type: ignore + # Mypy is unable to recognise arguments due to alias def rule_metadata_from_pb2(pb: capa_pb2.RuleMetadata) -> rd.RuleMetadata: @@ -711,7 +721,8 @@ def rule_metadata_from_pb2(pb: capa_pb2.RuleMetadata) -> rd.RuleMetadata: lib=pb.lib, is_subscope_rule=pb.is_subscope_rule, maec=maec_from_pb2(pb.maec), - ) + ) # type: ignore + # Mypy is unable to recognise `attack` and `is_subscope_rule` as arguments due to alias def doc_from_pb2(doc: capa_pb2.ResultDocument) -> rd.ResultDocument: diff --git a/capa/render/proto/capa_pb2.py b/capa/render/proto/capa_pb2.py index d4ca17d0..ad9dc304 100644 --- a/capa/render/proto/capa_pb2.py +++ b/capa/render/proto/capa_pb2.py @@ -6,132 +6,132 @@ 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 + # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1c\x63\x61pa/render/proto/capa.proto\"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\"l\n\x07\x41\x64\x64ress\x12\x1a\n\x04type\x18\x01 \x01(\x0e\x32\x0c.AddressType\x12\x15\n\x01v\x18\x02 \x01(\x0b\x32\x08.IntegerH\x00\x12%\n\x0ctoken_offset\x18\x03 \x01(\x0b\x32\r.Token_OffsetH\x00\x42\x07\n\x05value\"\xe4\x01\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\x1e\n\x0c\x62\x61se_address\x18\x06 \x01(\x0b\x32\x08.Address\x12\x17\n\x06layout\x18\x07 \x01(\x0b\x32\x07.Layout\x12&\n\x0e\x66\x65\x61ture_counts\x18\x08 \x01(\x0b\x32\x0e.FeatureCounts\x12+\n\x11library_functions\x18\t \x03(\x0b\x32\x10.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\x19\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x08.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\"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\"G\n\rFeatureCounts\x12\x0c\n\x04\x66ile\x18\x01 \x01(\x04\x12(\n\tfunctions\x18\x02 \x03(\x0b\x32\x15.FunctionFeatureCount\"\xf7\x06\n\x0b\x46\x65\x61tureNode\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x18\n\x02os\x18\x02 \x01(\x0b\x32\n.OSFeatureH\x00\x12\x1c\n\x04\x61rch\x18\x03 \x01(\x0b\x32\x0c.ArchFeatureH\x00\x12 \n\x06\x66ormat\x18\x04 \x01(\x0b\x32\x0e.FormatFeatureH\x00\x12\x1e\n\x05match\x18\x05 \x01(\x0b\x32\r.MatchFeatureH\x00\x12\x30\n\x0e\x63haracteristic\x18\x06 \x01(\x0b\x32\x16.CharacteristicFeatureH\x00\x12 \n\x06\x65xport\x18\x07 \x01(\x0b\x32\x0e.ExportFeatureH\x00\x12!\n\x07import_\x18\x08 \x01(\x0b\x32\x0e.ImportFeatureH\x00\x12\"\n\x07section\x18\t \x01(\x0b\x32\x0f.SectionFeatureH\x00\x12-\n\rfunction_name\x18\n \x01(\x0b\x32\x14.FunctionNameFeatureH\x00\x12&\n\tsubstring\x18\x0b \x01(\x0b\x32\x11.SubstringFeatureH\x00\x12\x1e\n\x05regex\x18\x0c \x01(\x0b\x32\r.RegexFeatureH\x00\x12 \n\x06string\x18\r \x01(\x0b\x32\x0e.StringFeatureH\x00\x12\x1f\n\x06\x63lass_\x18\x0e \x01(\x0b\x32\r.ClassFeatureH\x00\x12&\n\tnamespace\x18\x0f \x01(\x0b\x32\x11.NamespaceFeatureH\x00\x12\x1a\n\x03\x61pi\x18\x10 \x01(\x0b\x32\x0b.APIFeatureH\x00\x12%\n\tproperty_\x18\x11 \x01(\x0b\x32\x10.PropertyFeatureH\x00\x12 \n\x06number\x18\x12 \x01(\x0b\x32\x0e.NumberFeatureH\x00\x12\x1e\n\x05\x62ytes\x18\x13 \x01(\x0b\x32\r.BytesFeatureH\x00\x12 \n\x06offset\x18\x14 \x01(\x0b\x32\x0e.OffsetFeatureH\x00\x12$\n\x08mnemonic\x18\x15 \x01(\x0b\x32\x10.MnemonicFeatureH\x00\x12/\n\x0eoperand_number\x18\x16 \x01(\x0b\x32\x15.OperandNumberFeatureH\x00\x12/\n\x0eoperand_offset\x18\x17 \x01(\x0b\x32\x15.OperandOffsetFeatureH\x00\x12)\n\x0b\x62\x61sic_block\x18\x18 \x01(\x0b\x32\x12.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\x14\x46unctionFeatureCount\x12\x19\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x08.Address\x12\r\n\x05\x63ount\x18\x02 \x01(\x04\"\\\n\x0e\x46unctionLayout\x12\x19\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x08.Address\x12/\n\x14matched_basic_blocks\x18\x02 \x03(\x0b\x32\x11.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\"\n\tfunctions\x18\x01 \x03(\x0b\x32\x0f.FunctionLayout\":\n\x0fLibraryFunction\x12\x19\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x08.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\"\x82\x02\n\x05Match\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12#\n\tstatement\x18\x02 \x01(\x0b\x32\x0e.StatementNodeH\x00\x12\x1f\n\x07\x66\x65\x61ture\x18\x03 \x01(\x0b\x32\x0c.FeatureNodeH\x00\x12\x18\n\x08\x63hildren\x18\x05 \x03(\x0b\x32\x06.Match\x12\x1b\n\tlocations\x18\x06 \x03(\x0b\x32\x08.Address\x12&\n\x08\x63\x61ptures\x18\x07 \x03(\x0b\x32\x14.Match.CapturesEntry\x1a;\n\rCapturesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x19\n\x05value\x18\x02 \x01(\x0b\x32\n.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\"r\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\x17\n\x06sample\x18\x04 \x01(\x0b\x32\x07.Sample\x12\x1b\n\x08\x61nalysis\x18\x05 \x01(\x0b\x32\t.Analysis\"[\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\rNumberFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x17\n\x06number\x18\x02 \x01(\x0b\x32\x07.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\"a\n\rOffsetFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x18\n\x06offset\x18\x02 \x01(\x0b\x32\x08.Integer\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\x7f\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\x08.Integer\x12\x18\n\x0b\x64\x65scription\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\x7f\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\x08.Integer\x12\x18\n\x0b\x64\x65scription\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"|\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\"\x7f\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\x1b\n\x05\x63hild\x18\x04 \x01(\x0b\x32\x0c.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\"\x90\x01\n\x0eResultDocument\x12\x17\n\x04meta\x18\x01 \x01(\x0b\x32\t.Metadata\x12)\n\x05rules\x18\x02 \x03(\x0b\x32\x1a.ResultDocument.RulesEntry\x1a:\n\nRulesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x1b\n\x05value\x18\x02 \x01(\x0b\x32\x0c.RuleMatches:\x02\x38\x01\"`\n\x0bRuleMatches\x12\x1b\n\x04meta\x18\x01 \x01(\x0b\x32\r.RuleMetadata\x12\x0e\n\x06source\x18\x02 \x01(\t\x12$\n\x07matches\x18\x03 \x03(\x0b\x32\x13.Pair_Address_Match\"\x8a\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\x15\n\x05scope\x18\x04 \x01(\x0e\x32\x06.Scope\x12\x1b\n\x06\x61ttack\x18\x05 \x03(\x0b\x32\x0b.AttackSpec\x12\x15\n\x03mbc\x18\x06 \x03(\x0b\x32\x08.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\x1b\n\x04maec\x18\x0b \x01(\x0b\x32\r.MaecMetadata\x12\x18\n\x10is_subscope_rule\x18\x0c \x01(\x08\"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\"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\"\xbc\x01\n\rStatementNode\x12\x0c\n\x04type\x18\x01 \x01(\t\x12 \n\x05range\x18\x02 \x01(\x0b\x32\x0f.RangeStatementH\x00\x12\x1e\n\x04some\x18\x03 \x01(\x0b\x32\x0e.SomeStatementH\x00\x12&\n\x08subscope\x18\x04 \x01(\x0b\x32\x12.SubscopeStatementH\x00\x12&\n\x08\x63ompound\x18\x05 \x01(\x0b\x32\x12.CompoundStatementH\x00\x42\x0b\n\tstatement\"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\"b\n\x11SubscopeStatement\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x15\n\x05scope\x18\x02 \x01(\x0e\x32\x06.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\"&\n\tAddresses\x12\x19\n\x07\x61\x64\x64ress\x18\x01 \x03(\x0b\x32\x08.Address\"F\n\x12Pair_Address_Match\x12\x19\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x08.Address\x12\x15\n\x05match\x18\x02 \x01(\x0b\x32\x06.Match\"7\n\x0cToken_Offset\x12\x17\n\x05token\x18\x01 \x01(\x0b\x32\x08.Integer\x12\x0e\n\x06offset\x18\x02 \x01(\x04\",\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*\xcb\x01\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*p\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\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x1c\x63\x61pa/render/proto/capa.proto"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"l\n\x07\x41\x64\x64ress\x12\x1a\n\x04type\x18\x01 \x01(\x0e\x32\x0c.AddressType\x12\x15\n\x01v\x18\x02 \x01(\x0b\x32\x08.IntegerH\x00\x12%\n\x0ctoken_offset\x18\x03 \x01(\x0b\x32\r.Token_OffsetH\x00\x42\x07\n\x05value"\xe4\x01\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\x1e\n\x0c\x62\x61se_address\x18\x06 \x01(\x0b\x32\x08.Address\x12\x17\n\x06layout\x18\x07 \x01(\x0b\x32\x07.Layout\x12&\n\x0e\x66\x65\x61ture_counts\x18\x08 \x01(\x0b\x32\x0e.FeatureCounts\x12+\n\x11library_functions\x18\t \x03(\x0b\x32\x10.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\x19\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x08.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"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"G\n\rFeatureCounts\x12\x0c\n\x04\x66ile\x18\x01 \x01(\x04\x12(\n\tfunctions\x18\x02 \x03(\x0b\x32\x15.FunctionFeatureCount"\xf7\x06\n\x0b\x46\x65\x61tureNode\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x18\n\x02os\x18\x02 \x01(\x0b\x32\n.OSFeatureH\x00\x12\x1c\n\x04\x61rch\x18\x03 \x01(\x0b\x32\x0c.ArchFeatureH\x00\x12 \n\x06\x66ormat\x18\x04 \x01(\x0b\x32\x0e.FormatFeatureH\x00\x12\x1e\n\x05match\x18\x05 \x01(\x0b\x32\r.MatchFeatureH\x00\x12\x30\n\x0e\x63haracteristic\x18\x06 \x01(\x0b\x32\x16.CharacteristicFeatureH\x00\x12 \n\x06\x65xport\x18\x07 \x01(\x0b\x32\x0e.ExportFeatureH\x00\x12!\n\x07import_\x18\x08 \x01(\x0b\x32\x0e.ImportFeatureH\x00\x12"\n\x07section\x18\t \x01(\x0b\x32\x0f.SectionFeatureH\x00\x12-\n\rfunction_name\x18\n \x01(\x0b\x32\x14.FunctionNameFeatureH\x00\x12&\n\tsubstring\x18\x0b \x01(\x0b\x32\x11.SubstringFeatureH\x00\x12\x1e\n\x05regex\x18\x0c \x01(\x0b\x32\r.RegexFeatureH\x00\x12 \n\x06string\x18\r \x01(\x0b\x32\x0e.StringFeatureH\x00\x12\x1f\n\x06\x63lass_\x18\x0e \x01(\x0b\x32\r.ClassFeatureH\x00\x12&\n\tnamespace\x18\x0f \x01(\x0b\x32\x11.NamespaceFeatureH\x00\x12\x1a\n\x03\x61pi\x18\x10 \x01(\x0b\x32\x0b.APIFeatureH\x00\x12%\n\tproperty_\x18\x11 \x01(\x0b\x32\x10.PropertyFeatureH\x00\x12 \n\x06number\x18\x12 \x01(\x0b\x32\x0e.NumberFeatureH\x00\x12\x1e\n\x05\x62ytes\x18\x13 \x01(\x0b\x32\r.BytesFeatureH\x00\x12 \n\x06offset\x18\x14 \x01(\x0b\x32\x0e.OffsetFeatureH\x00\x12$\n\x08mnemonic\x18\x15 \x01(\x0b\x32\x10.MnemonicFeatureH\x00\x12/\n\x0eoperand_number\x18\x16 \x01(\x0b\x32\x15.OperandNumberFeatureH\x00\x12/\n\x0eoperand_offset\x18\x17 \x01(\x0b\x32\x15.OperandOffsetFeatureH\x00\x12)\n\x0b\x62\x61sic_block\x18\x18 \x01(\x0b\x32\x12.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\x14\x46unctionFeatureCount\x12\x19\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x08.Address\x12\r\n\x05\x63ount\x18\x02 \x01(\x04"\\\n\x0e\x46unctionLayout\x12\x19\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x08.Address\x12/\n\x14matched_basic_blocks\x18\x02 \x03(\x0b\x32\x11.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"\n\tfunctions\x18\x01 \x03(\x0b\x32\x0f.FunctionLayout":\n\x0fLibraryFunction\x12\x19\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x08.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"\x82\x02\n\x05Match\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12#\n\tstatement\x18\x02 \x01(\x0b\x32\x0e.StatementNodeH\x00\x12\x1f\n\x07\x66\x65\x61ture\x18\x03 \x01(\x0b\x32\x0c.FeatureNodeH\x00\x12\x18\n\x08\x63hildren\x18\x05 \x03(\x0b\x32\x06.Match\x12\x1b\n\tlocations\x18\x06 \x03(\x0b\x32\x08.Address\x12&\n\x08\x63\x61ptures\x18\x07 \x03(\x0b\x32\x14.Match.CapturesEntry\x1a;\n\rCapturesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x19\n\x05value\x18\x02 \x01(\x0b\x32\n.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"r\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\x17\n\x06sample\x18\x04 \x01(\x0b\x32\x07.Sample\x12\x1b\n\x08\x61nalysis\x18\x05 \x01(\x0b\x32\t.Analysis"[\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\rNumberFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x17\n\x06number\x18\x02 \x01(\x0b\x32\x07.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"a\n\rOffsetFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x18\n\x06offset\x18\x02 \x01(\x0b\x32\x08.Integer\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description"\x7f\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\x08.Integer\x12\x18\n\x0b\x64\x65scription\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description"\x7f\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\x08.Integer\x12\x18\n\x0b\x64\x65scription\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description"|\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"\x7f\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\x1b\n\x05\x63hild\x18\x04 \x01(\x0b\x32\x0c.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"\x90\x01\n\x0eResultDocument\x12\x17\n\x04meta\x18\x01 \x01(\x0b\x32\t.Metadata\x12)\n\x05rules\x18\x02 \x03(\x0b\x32\x1a.ResultDocument.RulesEntry\x1a:\n\nRulesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x1b\n\x05value\x18\x02 \x01(\x0b\x32\x0c.RuleMatches:\x02\x38\x01"`\n\x0bRuleMatches\x12\x1b\n\x04meta\x18\x01 \x01(\x0b\x32\r.RuleMetadata\x12\x0e\n\x06source\x18\x02 \x01(\t\x12$\n\x07matches\x18\x03 \x03(\x0b\x32\x13.Pair_Address_Match"\x8a\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\x15\n\x05scope\x18\x04 \x01(\x0e\x32\x06.Scope\x12\x1b\n\x06\x61ttack\x18\x05 \x03(\x0b\x32\x0b.AttackSpec\x12\x15\n\x03mbc\x18\x06 \x03(\x0b\x32\x08.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\x1b\n\x04maec\x18\x0b \x01(\x0b\x32\r.MaecMetadata\x12\x18\n\x10is_subscope_rule\x18\x0c \x01(\x08"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"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"\xbc\x01\n\rStatementNode\x12\x0c\n\x04type\x18\x01 \x01(\t\x12 \n\x05range\x18\x02 \x01(\x0b\x32\x0f.RangeStatementH\x00\x12\x1e\n\x04some\x18\x03 \x01(\x0b\x32\x0e.SomeStatementH\x00\x12&\n\x08subscope\x18\x04 \x01(\x0b\x32\x12.SubscopeStatementH\x00\x12&\n\x08\x63ompound\x18\x05 \x01(\x0b\x32\x12.CompoundStatementH\x00\x42\x0b\n\tstatement"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"b\n\x11SubscopeStatement\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x15\n\x05scope\x18\x02 \x01(\x0e\x32\x06.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"&\n\tAddresses\x12\x19\n\x07\x61\x64\x64ress\x18\x01 \x03(\x0b\x32\x08.Address"F\n\x12Pair_Address_Match\x12\x19\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x08.Address\x12\x15\n\x05match\x18\x02 \x01(\x0b\x32\x06.Match"7\n\x0cToken_Offset\x12\x17\n\x05token\x18\x01 \x01(\x0b\x32\x08.Integer\x12\x0e\n\x06offset\x18\x02 \x01(\x04",\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*\xcb\x01\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*p\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\x62\x06proto3' +) _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'capa.render.proto.capa_pb2', 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' - _RESULTDOCUMENT_RULESENTRY._options = None - _RESULTDOCUMENT_RULESENTRY._serialized_options = b'8\001' - _ADDRESSTYPE._serialized_start=6006 - _ADDRESSTYPE._serialized_end=6209 - _SCOPE._serialized_start=6211 - _SCOPE._serialized_end=6323 - _APIFEATURE._serialized_start=32 - _APIFEATURE._serialized_end=113 - _ADDRESS._serialized_start=115 - _ADDRESS._serialized_end=223 - _ANALYSIS._serialized_start=226 - _ANALYSIS._serialized_end=454 - _ARCHFEATURE._serialized_start=456 - _ARCHFEATURE._serialized_end=539 - _ATTACKSPEC._serialized_start=541 - _ATTACKSPEC._serialized_end=637 - _BASICBLOCKFEATURE._serialized_start=639 - _BASICBLOCKFEATURE._serialized_end=714 - _BASICBLOCKLAYOUT._serialized_start=716 - _BASICBLOCKLAYOUT._serialized_end=761 - _BYTESFEATURE._serialized_start=763 - _BYTESFEATURE._serialized_end=848 - _CHARACTERISTICFEATURE._serialized_start=850 - _CHARACTERISTICFEATURE._serialized_end=953 - _CLASSFEATURE._serialized_start=955 - _CLASSFEATURE._serialized_end=1041 - _COMPOUNDSTATEMENT._serialized_start=1043 - _COMPOUNDSTATEMENT._serialized_end=1118 - _EXPORTFEATURE._serialized_start=1120 - _EXPORTFEATURE._serialized_end=1207 - _FEATURECOUNTS._serialized_start=1209 - _FEATURECOUNTS._serialized_end=1280 - _FEATURENODE._serialized_start=1283 - _FEATURENODE._serialized_end=2170 - _FORMATFEATURE._serialized_start=2172 - _FORMATFEATURE._serialized_end=2259 - _FUNCTIONFEATURECOUNT._serialized_start=2261 - _FUNCTIONFEATURECOUNT._serialized_end=2325 - _FUNCTIONLAYOUT._serialized_start=2327 - _FUNCTIONLAYOUT._serialized_end=2419 - _FUNCTIONNAMEFEATURE._serialized_start=2421 - _FUNCTIONNAMEFEATURE._serialized_end=2521 - _IMPORTFEATURE._serialized_start=2523 - _IMPORTFEATURE._serialized_end=2611 - _LAYOUT._serialized_start=2613 - _LAYOUT._serialized_end=2657 - _LIBRARYFUNCTION._serialized_start=2659 - _LIBRARYFUNCTION._serialized_end=2717 - _MBCSPEC._serialized_start=2719 - _MBCSPEC._serialized_end=2808 - _MAECMETADATA._serialized_start=2811 - _MAECMETADATA._serialized_end=2965 - _MATCH._serialized_start=2968 - _MATCH._serialized_end=3226 - _MATCH_CAPTURESENTRY._serialized_start=3159 - _MATCH_CAPTURESENTRY._serialized_end=3218 - _MATCHFEATURE._serialized_start=3228 - _MATCHFEATURE._serialized_end=3313 - _METADATA._serialized_start=3315 - _METADATA._serialized_end=3429 - _MNEMONICFEATURE._serialized_start=3431 - _MNEMONICFEATURE._serialized_end=3522 - _NAMESPACEFEATURE._serialized_start=3524 - _NAMESPACEFEATURE._serialized_end=3617 - _NUMBERFEATURE._serialized_start=3619 - _NUMBERFEATURE._serialized_end=3715 - _OSFEATURE._serialized_start=3717 - _OSFEATURE._serialized_end=3796 - _OFFSETFEATURE._serialized_start=3798 - _OFFSETFEATURE._serialized_end=3895 - _OPERANDNUMBERFEATURE._serialized_start=3897 - _OPERANDNUMBERFEATURE._serialized_end=4024 - _OPERANDOFFSETFEATURE._serialized_start=4026 - _OPERANDOFFSETFEATURE._serialized_end=4153 - _PROPERTYFEATURE._serialized_start=4155 - _PROPERTYFEATURE._serialized_end=4279 - _RANGESTATEMENT._serialized_start=4281 - _RANGESTATEMENT._serialized_end=4408 - _REGEXFEATURE._serialized_start=4410 - _REGEXFEATURE._serialized_end=4495 - _RESULTDOCUMENT._serialized_start=4498 - _RESULTDOCUMENT._serialized_end=4642 - _RESULTDOCUMENT_RULESENTRY._serialized_start=4584 - _RESULTDOCUMENT_RULESENTRY._serialized_end=4642 - _RULEMATCHES._serialized_start=4644 - _RULEMATCHES._serialized_end=4740 - _RULEMETADATA._serialized_start=4743 - _RULEMETADATA._serialized_end=5009 - _SAMPLE._serialized_start=5011 - _SAMPLE._serialized_end=5076 - _SECTIONFEATURE._serialized_start=5078 - _SECTIONFEATURE._serialized_end=5167 - _SOMESTATEMENT._serialized_start=5169 - _SOMESTATEMENT._serialized_end=5255 - _STATEMENTNODE._serialized_start=5258 - _STATEMENTNODE._serialized_end=5446 - _STRINGFEATURE._serialized_start=5448 - _STRINGFEATURE._serialized_end=5535 - _SUBSCOPESTATEMENT._serialized_start=5537 - _SUBSCOPESTATEMENT._serialized_end=5635 - _SUBSTRINGFEATURE._serialized_start=5637 - _SUBSTRINGFEATURE._serialized_end=5730 - _ADDRESSES._serialized_start=5732 - _ADDRESSES._serialized_end=5770 - _PAIR_ADDRESS_MATCH._serialized_start=5772 - _PAIR_ADDRESS_MATCH._serialized_end=5842 - _TOKEN_OFFSET._serialized_start=5844 - _TOKEN_OFFSET._serialized_end=5899 - _INTEGER._serialized_start=5901 - _INTEGER._serialized_end=5945 - _NUMBER._serialized_start=5947 - _NUMBER._serialized_end=6003 + DESCRIPTOR._options = None + _MATCH_CAPTURESENTRY._options = None + _MATCH_CAPTURESENTRY._serialized_options = b"8\001" + _RESULTDOCUMENT_RULESENTRY._options = None + _RESULTDOCUMENT_RULESENTRY._serialized_options = b"8\001" + _ADDRESSTYPE._serialized_start = 6006 + _ADDRESSTYPE._serialized_end = 6209 + _SCOPE._serialized_start = 6211 + _SCOPE._serialized_end = 6323 + _APIFEATURE._serialized_start = 32 + _APIFEATURE._serialized_end = 113 + _ADDRESS._serialized_start = 115 + _ADDRESS._serialized_end = 223 + _ANALYSIS._serialized_start = 226 + _ANALYSIS._serialized_end = 454 + _ARCHFEATURE._serialized_start = 456 + _ARCHFEATURE._serialized_end = 539 + _ATTACKSPEC._serialized_start = 541 + _ATTACKSPEC._serialized_end = 637 + _BASICBLOCKFEATURE._serialized_start = 639 + _BASICBLOCKFEATURE._serialized_end = 714 + _BASICBLOCKLAYOUT._serialized_start = 716 + _BASICBLOCKLAYOUT._serialized_end = 761 + _BYTESFEATURE._serialized_start = 763 + _BYTESFEATURE._serialized_end = 848 + _CHARACTERISTICFEATURE._serialized_start = 850 + _CHARACTERISTICFEATURE._serialized_end = 953 + _CLASSFEATURE._serialized_start = 955 + _CLASSFEATURE._serialized_end = 1041 + _COMPOUNDSTATEMENT._serialized_start = 1043 + _COMPOUNDSTATEMENT._serialized_end = 1118 + _EXPORTFEATURE._serialized_start = 1120 + _EXPORTFEATURE._serialized_end = 1207 + _FEATURECOUNTS._serialized_start = 1209 + _FEATURECOUNTS._serialized_end = 1280 + _FEATURENODE._serialized_start = 1283 + _FEATURENODE._serialized_end = 2170 + _FORMATFEATURE._serialized_start = 2172 + _FORMATFEATURE._serialized_end = 2259 + _FUNCTIONFEATURECOUNT._serialized_start = 2261 + _FUNCTIONFEATURECOUNT._serialized_end = 2325 + _FUNCTIONLAYOUT._serialized_start = 2327 + _FUNCTIONLAYOUT._serialized_end = 2419 + _FUNCTIONNAMEFEATURE._serialized_start = 2421 + _FUNCTIONNAMEFEATURE._serialized_end = 2521 + _IMPORTFEATURE._serialized_start = 2523 + _IMPORTFEATURE._serialized_end = 2611 + _LAYOUT._serialized_start = 2613 + _LAYOUT._serialized_end = 2657 + _LIBRARYFUNCTION._serialized_start = 2659 + _LIBRARYFUNCTION._serialized_end = 2717 + _MBCSPEC._serialized_start = 2719 + _MBCSPEC._serialized_end = 2808 + _MAECMETADATA._serialized_start = 2811 + _MAECMETADATA._serialized_end = 2965 + _MATCH._serialized_start = 2968 + _MATCH._serialized_end = 3226 + _MATCH_CAPTURESENTRY._serialized_start = 3159 + _MATCH_CAPTURESENTRY._serialized_end = 3218 + _MATCHFEATURE._serialized_start = 3228 + _MATCHFEATURE._serialized_end = 3313 + _METADATA._serialized_start = 3315 + _METADATA._serialized_end = 3429 + _MNEMONICFEATURE._serialized_start = 3431 + _MNEMONICFEATURE._serialized_end = 3522 + _NAMESPACEFEATURE._serialized_start = 3524 + _NAMESPACEFEATURE._serialized_end = 3617 + _NUMBERFEATURE._serialized_start = 3619 + _NUMBERFEATURE._serialized_end = 3715 + _OSFEATURE._serialized_start = 3717 + _OSFEATURE._serialized_end = 3796 + _OFFSETFEATURE._serialized_start = 3798 + _OFFSETFEATURE._serialized_end = 3895 + _OPERANDNUMBERFEATURE._serialized_start = 3897 + _OPERANDNUMBERFEATURE._serialized_end = 4024 + _OPERANDOFFSETFEATURE._serialized_start = 4026 + _OPERANDOFFSETFEATURE._serialized_end = 4153 + _PROPERTYFEATURE._serialized_start = 4155 + _PROPERTYFEATURE._serialized_end = 4279 + _RANGESTATEMENT._serialized_start = 4281 + _RANGESTATEMENT._serialized_end = 4408 + _REGEXFEATURE._serialized_start = 4410 + _REGEXFEATURE._serialized_end = 4495 + _RESULTDOCUMENT._serialized_start = 4498 + _RESULTDOCUMENT._serialized_end = 4642 + _RESULTDOCUMENT_RULESENTRY._serialized_start = 4584 + _RESULTDOCUMENT_RULESENTRY._serialized_end = 4642 + _RULEMATCHES._serialized_start = 4644 + _RULEMATCHES._serialized_end = 4740 + _RULEMETADATA._serialized_start = 4743 + _RULEMETADATA._serialized_end = 5009 + _SAMPLE._serialized_start = 5011 + _SAMPLE._serialized_end = 5076 + _SECTIONFEATURE._serialized_start = 5078 + _SECTIONFEATURE._serialized_end = 5167 + _SOMESTATEMENT._serialized_start = 5169 + _SOMESTATEMENT._serialized_end = 5255 + _STATEMENTNODE._serialized_start = 5258 + _STATEMENTNODE._serialized_end = 5446 + _STRINGFEATURE._serialized_start = 5448 + _STRINGFEATURE._serialized_end = 5535 + _SUBSCOPESTATEMENT._serialized_start = 5537 + _SUBSCOPESTATEMENT._serialized_end = 5635 + _SUBSTRINGFEATURE._serialized_start = 5637 + _SUBSTRINGFEATURE._serialized_end = 5730 + _ADDRESSES._serialized_start = 5732 + _ADDRESSES._serialized_end = 5770 + _PAIR_ADDRESS_MATCH._serialized_start = 5772 + _PAIR_ADDRESS_MATCH._serialized_end = 5842 + _TOKEN_OFFSET._serialized_start = 5844 + _TOKEN_OFFSET._serialized_end = 5899 + _INTEGER._serialized_start = 5901 + _INTEGER._serialized_end = 5945 + _NUMBER._serialized_start = 5947 + _NUMBER._serialized_end = 6003 # @@protoc_insertion_point(module_scope) diff --git a/capa/render/proto/capa_pb2.pyi b/capa/render/proto/capa_pb2.pyi index 174b1a97..861a155c 100644 --- a/capa/render/proto/capa_pb2.pyi +++ b/capa/render/proto/capa_pb2.pyi @@ -22,7 +22,9 @@ class _AddressType: ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType -class _AddressTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_AddressType.ValueType], builtins.type): +class _AddressTypeEnumTypeWrapper( + google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_AddressType.ValueType], builtins.type +): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor ADDRESSTYPE_UNSPECIFIED: _AddressType.ValueType # 0 ADDRESSTYPE_ABSOLUTE: _AddressType.ValueType # 1 @@ -47,7 +49,9 @@ class _Scope: ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType -class _ScopeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_Scope.ValueType], builtins.type): +class _ScopeEnumTypeWrapper( + google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_Scope.ValueType], builtins.type +): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor SCOPE_UNSPECIFIED: _Scope.ValueType # 0 SCOPE_FILE: _Scope.ValueType # 1 @@ -81,9 +85,18 @@ 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_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: ... global___APIFeature = APIFeature @@ -106,9 +119,18 @@ class Address(google.protobuf.message.Message): v: global___Integer | None = ..., token_offset: global___Token_Offset | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["token_offset", b"token_offset", "v", b"v", "value", b"value"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["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"] | None: ... + def HasField( + self, field_name: typing_extensions.Literal["token_offset", b"token_offset", "v", b"v", "value", b"value"] + ) -> builtins.bool: ... + def ClearField( + self, + field_name: typing_extensions.Literal[ + "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"] | None: ... global___Address = Address @@ -138,7 +160,9 @@ class Analysis(google.protobuf.message.Message): @property def feature_counts(self) -> global___FeatureCounts: ... @property - def library_functions(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___LibraryFunction]: ... + def library_functions( + self, + ) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___LibraryFunction]: ... def __init__( self, *, @@ -152,8 +176,35 @@ 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_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: ... global___Analysis = Analysis @@ -174,9 +225,18 @@ 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_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: ... global___ArchFeature = ArchFeature @@ -204,7 +264,21 @@ 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_extensions.Literal[ + "id", + b"id", + "parts", + b"parts", + "subtechnique", + b"subtechnique", + "tactic", + b"tactic", + "technique", + b"technique", + ], + ) -> None: ... global___AttackSpec = AttackSpec @@ -222,9 +296,18 @@ 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_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: ... global___BasicBlockFeature = BasicBlockFeature @@ -262,9 +345,18 @@ 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_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: ... global___BytesFeature = BytesFeature @@ -285,9 +377,25 @@ 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_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: ... global___CharacteristicFeature = CharacteristicFeature @@ -309,9 +417,18 @@ 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_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: ... global___ClassFeature = ClassFeature @@ -329,9 +446,18 @@ 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_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: ... global___CompoundStatement = CompoundStatement @@ -352,9 +478,18 @@ 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_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: ... global___ExportFeature = ExportFeature @@ -366,7 +501,9 @@ class FeatureCounts(google.protobuf.message.Message): FUNCTIONS_FIELD_NUMBER: builtins.int file: builtins.int @property - def functions(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___FunctionFeatureCount]: ... + def functions( + self, + ) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___FunctionFeatureCount]: ... def __init__( self, *, @@ -482,9 +619,144 @@ 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_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 + ): ... global___FeatureNode = FeatureNode @@ -505,9 +777,18 @@ 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_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: ... global___FormatFeature = FormatFeature @@ -540,7 +821,9 @@ class FunctionLayout(google.protobuf.message.Message): @property def address(self) -> global___Address: ... @property - def matched_basic_blocks(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___BasicBlockLayout]: ... + def matched_basic_blocks( + self, + ) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___BasicBlockLayout]: ... def __init__( self, *, @@ -548,7 +831,10 @@ class FunctionLayout(google.protobuf.message.Message): 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 ClearField( + self, + field_name: typing_extensions.Literal["address", b"address", "matched_basic_blocks", b"matched_basic_blocks"], + ) -> None: ... global___FunctionLayout = FunctionLayout @@ -569,9 +855,25 @@ 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_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: ... global___FunctionNameFeature = FunctionNameFeature @@ -592,9 +894,18 @@ 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_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: ... global___ImportFeature = ImportFeature @@ -604,7 +915,9 @@ class Layout(google.protobuf.message.Message): FUNCTIONS_FIELD_NUMBER: builtins.int @property - def functions(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___FunctionLayout]: ... + def functions( + self, + ) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___FunctionLayout]: ... def __init__( self, *, @@ -658,7 +971,12 @@ 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_extensions.Literal[ + "behavior", b"behavior", "id", b"id", "method", b"method", "objective", b"objective", "parts", b"parts" + ], + ) -> None: ... global___MBCSpec = MBCSpec @@ -685,7 +1003,21 @@ 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_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: ... global___MaecMetadata = MaecMetadata @@ -738,9 +1070,31 @@ 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_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: ... global___Match = Match @@ -761,9 +1115,18 @@ 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_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: ... global___MatchFeature = MatchFeature @@ -794,8 +1157,24 @@ class Metadata(google.protobuf.message.Message): sample: global___Sample | None = ..., analysis: global___Analysis | None = ..., ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["analysis", b"analysis", "sample", b"sample"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["analysis", b"analysis", "argv", b"argv", "sample", b"sample", "timestamp", b"timestamp", "version", b"version"]) -> None: ... + def HasField( + self, field_name: typing_extensions.Literal["analysis", b"analysis", "sample", b"sample"] + ) -> builtins.bool: ... + def ClearField( + self, + field_name: typing_extensions.Literal[ + "analysis", + b"analysis", + "argv", + b"argv", + "sample", + b"sample", + "timestamp", + b"timestamp", + "version", + b"version", + ], + ) -> None: ... global___Metadata = Metadata @@ -816,9 +1195,18 @@ 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_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: ... global___MnemonicFeature = MnemonicFeature @@ -839,9 +1227,18 @@ 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_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: ... global___NamespaceFeature = NamespaceFeature @@ -864,9 +1261,21 @@ 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_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: ... global___NumberFeature = NumberFeature @@ -887,9 +1296,18 @@ 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_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: ... global___OSFeature = OSFeature @@ -912,9 +1330,21 @@ 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_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: ... global___OffsetFeature = OffsetFeature @@ -940,9 +1370,30 @@ 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_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: ... global___OperandNumberFeature = OperandNumberFeature @@ -967,9 +1418,30 @@ 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_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: ... global___OperandOffsetFeature = OperandOffsetFeature @@ -994,12 +1466,37 @@ 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_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: ... @typing.overload - def WhichOneof(self, oneof_group: typing_extensions.Literal["_access", b"_access"]) -> typing_extensions.Literal["access"] | None: ... + def WhichOneof( + self, oneof_group: typing_extensions.Literal["_access", b"_access"] + ) -> typing_extensions.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_extensions.Literal["_description", b"_description"] + ) -> typing_extensions.Literal["description"] | None: ... global___PropertyFeature = PropertyFeature @@ -1028,9 +1525,32 @@ 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_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: ... global___RangeStatement = RangeStatement @@ -1051,9 +1571,18 @@ 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_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: ... global___RegexFeature = RegexFeature @@ -1107,7 +1636,9 @@ class RuleMatches(google.protobuf.message.Message): def meta(self) -> global___RuleMetadata: ... source: builtins.str @property - def matches(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Pair_Address_Match]: ... + def matches( + self, + ) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Pair_Address_Match]: ... def __init__( self, *, @@ -1116,7 +1647,9 @@ class RuleMatches(google.protobuf.message.Message): 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 ClearField( + self, field_name: typing_extensions.Literal["matches", b"matches", "meta", b"meta", "source", b"source"] + ) -> None: ... global___RuleMatches = RuleMatches @@ -1171,7 +1704,35 @@ class RuleMetadata(google.protobuf.message.Message): is_subscope_rule: builtins.bool = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["maec", b"maec"]) -> 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"]) -> None: ... + 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", + ], + ) -> None: ... global___RuleMetadata = RuleMetadata @@ -1195,7 +1756,10 @@ 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_extensions.Literal["md5", b"md5", "path", b"path", "sha1", b"sha1", "sha256", b"sha256"], + ) -> None: ... global___Sample = Sample @@ -1216,9 +1780,18 @@ 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_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: ... global___SectionFeature = SectionFeature @@ -1239,9 +1812,18 @@ 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_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: ... global___SomeStatement = SomeStatement @@ -1272,9 +1854,41 @@ 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_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: ... global___StatementNode = StatementNode @@ -1295,9 +1909,18 @@ 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_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: ... global___StringFeature = StringFeature @@ -1318,9 +1941,18 @@ 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_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: ... global___SubscopeStatement = SubscopeStatement @@ -1341,9 +1973,18 @@ 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_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: ... global___SubstringFeature = SubstringFeature @@ -1379,7 +2020,9 @@ 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 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: ... global___Pair_Address_Match = Pair_Address_Match @@ -1419,9 +2062,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 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 WhichOneof( + self, oneof_group: typing_extensions.Literal["value", b"value"] + ) -> typing_extensions.Literal["u", "i"] | None: ... global___Integer = Integer @@ -1442,8 +2089,14 @@ 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_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: ... global___Number = Number From 03f0034d33d6c868c14241ccb2923ea416b70e81 Mon Sep 17 00:00:00 2001 From: Pratham Chauhan Date: Sat, 25 Mar 2023 14:47:59 +0530 Subject: [PATCH 07/79] working meta parsing --- capa/render/result_document.py | 47 +++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/capa/render/result_document.py b/capa/render/result_document.py index 3449d9f6..b709ac4c 100644 --- a/capa/render/result_document.py +++ b/capa/render/result_document.py @@ -125,6 +125,45 @@ class Metadata(FrozenModel): ), ) + def to_capa(self) -> Dict[str, Any]: + capa_meta = { + "timestamp": self.timestamp.isoformat(), + "version": self.version, + "sample": { + "md5": self.sample.md5, + "sha1": self.sample.sha1, + "sha256": self.sample.sha256, + "path": self.sample.path, + }, + "analysis": { + "format": self.analysis.format, + "arch": self.analysis.arch, + "os": self.analysis.os, + "extractor": self.analysis.extractor, + "rules": self.analysis.rules, + "base_address": self.analysis.base_address.to_capa(), + "layout": { + "functions": { + f.address.to_capa(): { + "matched_basic_blocks": [bb.address.to_capa() for bb in f.matched_basic_blocks] + } + for f in self.analysis.layout.functions + } + }, + "feature_counts": { + "file": self.analysis.feature_counts.file, + "functions": { + fc.address.to_capa(): fc.count for fc in self.analysis.feature_counts.functions + }, + }, + "library_functions": { + lf.address.to_capa(): lf.name for lf in self.analysis.library_functions + }, + }, + } + + return capa_meta + class CompoundStatementType: AND = "and" @@ -526,6 +565,8 @@ class ResultDocument(BaseModel): def from_capa(cls, meta, rules: RuleSet, capabilities: MatchResults) -> "ResultDocument": rule_matches: Dict[str, RuleMatches] = {} for rule_name, matches in capabilities.items(): + if rule_name not in rules: + continue rule = rules[rule_name] if rule.meta.get("capa/subscope-rule"): @@ -546,7 +587,7 @@ class ResultDocument(BaseModel): def parse_raw(cls, raw: str): data = json.loads(raw) result_doc = ResultDocument(**data) - meta = result_doc.meta + #meta = Metadata(**result_doc.meta) rules = {} capabilities = {} @@ -564,6 +605,4 @@ class ResultDocument(BaseModel): capabilities[address] = [] capabilities[address].append((rule_name, match)) - return meta , rules, capabilities - - \ No newline at end of file + return result_doc.meta.to_capa(), rules, capabilities \ No newline at end of file From 78d0111a6c8614c5d8f069fc1546ca6dbea7eb14 Mon Sep 17 00:00:00 2001 From: Pratham Chauhan Date: Sun, 26 Mar 2023 22:09:04 +0530 Subject: [PATCH 08/79] Final changes --- capa/main.py | 2 +- capa/render/result_document.py | 48 +++++++++++++++++++++------------- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/capa/main.py b/capa/main.py index 320a2b22..38f0837d 100644 --- a/capa/main.py +++ b/capa/main.py @@ -1128,7 +1128,7 @@ def main(argv=None): with open(args.sample, "rb") as f: buf = f.read() buf.decode("utf-8") - meta, rules, capabilities = capa.render.result_document.ResultDocument.parse_raw(buf) + meta, capabilities = capa.render.result_document.ResultDocument.parse_raw(buf,rules) elif format_ == FORMAT_FREEZE: with open(args.sample, "rb") as f: extractor = capa.features.freeze.load(f.read()) diff --git a/capa/render/result_document.py b/capa/render/result_document.py index b709ac4c..7470acf7 100644 --- a/capa/render/result_document.py +++ b/capa/render/result_document.py @@ -7,7 +7,7 @@ # See the License for the specific language governing permissions and limitations under the License. import datetime import json -from typing import Any, Dict, Tuple, Union, Optional +from typing import Any, Dict, List, Tuple, Union, Optional from pydantic import Field, BaseModel @@ -17,7 +17,7 @@ import capa.features.common import capa.features.freeze as frz import capa.features.address import capa.features.freeze.features as frzf -from capa.rules import Rule, RuleSet +from capa.rules import RuleSet from capa.engine import MatchResults from capa.helpers import assert_never @@ -584,25 +584,37 @@ class ResultDocument(BaseModel): return ResultDocument(meta=Metadata.from_capa(meta), rules=rule_matches) @classmethod - def parse_raw(cls, raw: str): + def parse_raw(cls, raw: str, rules: RuleSet): data = json.loads(raw) result_doc = ResultDocument(**data) - #meta = Metadata(**result_doc.meta) - - rules = {} - capabilities = {} - for rule_name, rule_match in result_doc.rules.items(): - # Extract the rule definition and metadata - rule_definition = rule_match.source - rule_metadata = rule_match.meta - # Add the rule to the rules dictionary - rules[rule_name] = (rule_metadata, rule_definition) + capabilities: Dict[str, List[Tuple[frz.Address, capa.features.common.Result]]] ={} + for rule_name, rule_match in result_doc.rules.items(): + # Extract the capabilities from the RuleMatches object - for address, match in rule_match.matches: - if address not in capabilities: - capabilities[address] = [] + for addr, match in rule_match.matches: - capabilities[address].append((rule_name, match)) - return result_doc.meta.to_capa(), rules, capabilities \ No newline at end of file + if isinstance(match.node, StatementNode): + if isinstance(match.node.statement, CompoundStatement): + statement = rules[rule_name].statement + else: + statement = statement_from_capa(match.node.statement) + elif isinstance(match.node, FeatureNode): + statement = match.node.feature.to_capa() + if isinstance(statement, (capa.features.common.String, capa.features.common.Regex)): + statement.matches = match.captures + else: + raise ValueError("Invalid node type") + + result = capa.features.common.Result( + statement=statement, + success=match.success, + locations=[frz.Address.to_capa(loc) for loc in match.locations], + children=[]) + + if rule_name not in capabilities: + capabilities[rule_name]=[] + capabilities[rule_name].append((frz.Address.from_capa(addr),result)) + + return result_doc.meta.to_capa(), capabilities \ No newline at end of file From e26deb472ec51ba0c0bee97b50dc4207663c0f39 Mon Sep 17 00:00:00 2001 From: Pratham Chauhan Date: Sun, 26 Mar 2023 22:54:12 +0530 Subject: [PATCH 09/79] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13f72602..d13efac1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## master (unreleased) ### New Features +- add new format to parse output json back to capa #1396 @ooprathamm ### Breaking Changes From 2bedc6b181383d5933676b5964dbb9379989ffee Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Mon, 27 Mar 2023 11:47:53 +0200 Subject: [PATCH 10/79] ci: tests: run binja after code style/linter --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2cb190b3..e9701c9e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -94,6 +94,7 @@ jobs: binja-tests: name: Binary Ninja tests for ${{ matrix.python-version }} on ${{ matrix.os }} runs-on: ubuntu-20.04 + needs: [code_style, rule_linter] strategy: fail-fast: false matrix: From ea2acea668f1325c1b510f031fd933943af8eddb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 14:08:45 +0000 Subject: [PATCH 11/79] build(deps-dev): bump types-protobuf from 4.21.0.5 to 4.22.0.0 Bumps [types-protobuf](https://github.com/python/typeshed) from 4.21.0.5 to 4.22.0.0. - [Release notes](https://github.com/python/typeshed/releases) - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-protobuf dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 642b0e4d..b8b32e1f 100644 --- a/setup.py +++ b/setup.py @@ -89,7 +89,7 @@ setuptools.setup( "types-termcolor==1.1.4", "types-psutil==5.8.23", "types_requests==2.28.1", - "types-protobuf==4.21.0.5", + "types-protobuf==4.22.0.0", ], "build": [ "pyinstaller==5.9.0", From d873cc025727d4cec96cfdf91c6e51f70e79a038 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 14:09:09 +0000 Subject: [PATCH 12/79] build(deps): bump pydantic from 1.10.6 to 1.10.7 Bumps [pydantic](https://github.com/pydantic/pydantic) from 1.10.6 to 1.10.7. - [Release notes](https://github.com/pydantic/pydantic/releases) - [Changelog](https://github.com/pydantic/pydantic/blob/v1.10.7/HISTORY.md) - [Commits](https://github.com/pydantic/pydantic/compare/v1.10.6...v1.10.7) --- updated-dependencies: - dependency-name: pydantic dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 642b0e4d..c9f7a3a5 100644 --- a/setup.py +++ b/setup.py @@ -27,7 +27,7 @@ requirements = [ "pyelftools==0.29", "dnfile==0.13.0", "dncil==1.0.2", - "pydantic==1.10.6", + "pydantic==1.10.7", "protobuf==4.21.12", ] From 02359e5e84781661bea7d77a1d5c112ae98f910f Mon Sep 17 00:00:00 2001 From: Pratham Chauhan Date: Mon, 27 Mar 2023 22:22:25 +0530 Subject: [PATCH 13/79] fix --- capa/features/extractors/common.py | 4 ++-- capa/render/result_document.py | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/capa/features/extractors/common.py b/capa/features/extractors/common.py index dc5d1c3a..e9d77cee 100644 --- a/capa/features/extractors/common.py +++ b/capa/features/extractors/common.py @@ -81,11 +81,11 @@ def extract_arch(buf) -> Iterator[Tuple[Feature, Address]]: def extract_os(buf) -> Iterator[Tuple[Feature, Address]]: if buf.startswith(b"MZ"): yield OS(OS_WINDOWS), NO_ADDRESS + elif buf.startswith(b"{\"meta\":"): + yield OS(OS_ANY), NO_ADDRESS elif buf.startswith(b"\x7fELF"): with contextlib.closing(io.BytesIO(buf)) as f: os = capa.features.extractors.elf.detect_elf_os(f) - elif buf.startswith(b"{\"meta\":"): - os = OS_ANY if os not in capa.features.common.VALID_OS: logger.debug("unsupported os: %s", os) diff --git a/capa/render/result_document.py b/capa/render/result_document.py index 7470acf7..39a9e7a9 100644 --- a/capa/render/result_document.py +++ b/capa/render/result_document.py @@ -565,8 +565,6 @@ class ResultDocument(BaseModel): def from_capa(cls, meta, rules: RuleSet, capabilities: MatchResults) -> "ResultDocument": rule_matches: Dict[str, RuleMatches] = {} for rule_name, matches in capabilities.items(): - if rule_name not in rules: - continue rule = rules[rule_name] if rule.meta.get("capa/subscope-rule"): From cd2ef15a8a37dbec1459ab4c9621186016a74027 Mon Sep 17 00:00:00 2001 From: AG <98327736+ggold7046@users.noreply.github.com> Date: Tue, 28 Mar 2023 01:11:23 +0530 Subject: [PATCH 14/79] Update CHANGELOG.md Update changelog to reflect changes introduced in pull request #1399 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a92a5a9..2d4a887d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - extractor: add Binary Ninja feature extractor @xusheng6 - new cli flag `--os` to override auto-detected operating system for a sample @captainGeech42 +- Change colour/highlight to "cyan" instead of "blue" for easy noticing.#1384 @ggold7046 ### Breaking Changes From af1500825af9454e716b05548360d45393c87295 Mon Sep 17 00:00:00 2001 From: Capa Bot Date: Tue, 28 Mar 2023 07:20:10 +0000 Subject: [PATCH 15/79] Sync capa rules submodule --- CHANGELOG.md | 3 ++- README.md | 2 +- rules | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a92a5a9..692055b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ ### Breaking Changes -### New Rules (22) +### New Rules (23) - persistence/scheduled-tasks/schedule-task-via-at joren485 - data-manipulation/prng/generate-random-numbers-via-rtlgenrandom william.ballenthin@mandiant.com @@ -34,6 +34,7 @@ - nursery/set-web-proxy-in-dotnet michael.hunhoff@mandiant.com - nursery/check-for-windows-sandbox-via-subdirectory echernofsky@google.com - nursery/enumerate-pe-sections-in-dotnet @mr-tz +- nursery/destroy-software-breakpoint-capability echernofsky@google.com - ### Bug Fixes diff --git a/README.md b/README.md index 996467b2..91945fa4 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/flare-capa)](https://pypi.org/project/flare-capa) [![Last release](https://img.shields.io/github/v/release/mandiant/capa)](https://github.com/mandiant/capa/releases) -[![Number of rules](https://img.shields.io/badge/rules-789-blue.svg)](https://github.com/mandiant/capa-rules) +[![Number of rules](https://img.shields.io/badge/rules-791-blue.svg)](https://github.com/mandiant/capa-rules) [![CI status](https://github.com/mandiant/capa/workflows/CI/badge.svg)](https://github.com/mandiant/capa/actions?query=workflow%3ACI+event%3Apush+branch%3Amaster) [![Downloads](https://img.shields.io/github/downloads/mandiant/capa/total)](https://github.com/mandiant/capa/releases) [![License](https://img.shields.io/badge/license-Apache--2.0-green.svg)](LICENSE.txt) diff --git a/rules b/rules index 4ca80233..48692d18 160000 --- a/rules +++ b/rules @@ -1 +1 @@ -Subproject commit 4ca802336320e9b2f1f524d5aa95ef102ad3c1e4 +Subproject commit 48692d18cc3fc6c96a608abe9fd9d8b010c63f83 From ac2d01a60af412c788dc32e76000d81c7f9690c3 Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Tue, 28 Mar 2023 11:43:49 +0200 Subject: [PATCH 16/79] use f-strings as appropriate closes #600 --- capa/features/extractors/binja/file.py | 4 ++-- capa/features/extractors/binja/find_binja_api.py | 2 +- capa/features/insn.py | 2 +- capa/main.py | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/capa/features/extractors/binja/file.py b/capa/features/extractors/binja/file.py index 8469a808..9700a8c1 100644 --- a/capa/features/extractors/binja/file.py +++ b/capa/features/extractors/binja/file.py @@ -103,7 +103,7 @@ def extract_file_import_names(bv: BinaryView) -> Iterator[Tuple[Feature, Address ordinal = sym.ordinal if ordinal != 0 and (lib_name != ""): - ordinal_name = "#%d" % (ordinal) + ordinal_name = f"#{ordinal}" for name in capa.features.extractors.helpers.generate_symbols(lib_name, ordinal_name): yield Import(name), addr @@ -147,7 +147,7 @@ def extract_file_format(bv: BinaryView) -> Iterator[Tuple[Feature, Address]]: # no file type to return when processing a binary file, but we want to continue processing return else: - raise NotImplementedError("unexpected file format: %d" % view_type) + raise NotImplementedError(f"unexpected file format: {view_type}") def extract_features(bv: BinaryView) -> Iterator[Tuple[Feature, Address]]: diff --git a/capa/features/extractors/binja/find_binja_api.py b/capa/features/extractors/binja/find_binja_api.py index 7cb78d7a..6356c074 100644 --- a/capa/features/extractors/binja/find_binja_api.py +++ b/capa/features/extractors/binja/find_binja_api.py @@ -26,7 +26,7 @@ if spec is not None: def find_binja_path() -> str: - raw_output = subprocess.check_output(["python", "-c", "%s" % code]).decode("ascii").strip() + raw_output = subprocess.check_output(["python", "-c", code]).decode("ascii").strip() return bytes.fromhex(raw_output).decode("utf8") diff --git a/capa/features/insn.py b/capa/features/insn.py index 24b7c7b5..f4be23c8 100644 --- a/capa/features/insn.py +++ b/capa/features/insn.py @@ -70,7 +70,7 @@ class Number(Feature): elif isinstance(self.value, float): return str(self.value) else: - raise ValueError("invalid value type %s" % (type(self.value))) + raise ValueError(f"invalid value type {type(self.value)}") # max recognized structure size (and therefore, offset size) diff --git a/capa/main.py b/capa/main.py index a3744032..70e086c2 100644 --- a/capa/main.py +++ b/capa/main.py @@ -547,7 +547,7 @@ def get_extractor( with halo.Halo(text="analyzing program", spinner="simpleDots", stream=sys.stderr, enabled=not disable_progress): bv: BinaryView = BinaryViewType.get_view_of_file(path) if bv is None: - raise RuntimeError("Binary Ninja cannot open file %s" % (path)) + raise RuntimeError(f"Binary Ninja cannot open file {path}") return capa.features.extractors.binja.extractor.BinjaFeatureExtractor(bv) @@ -912,12 +912,12 @@ def install_common_args(parser, wanted=None): (OS_MACOS,), (OS_WINDOWS,), ] - os_help = ", ".join(["%s (%s)" % (o[0], o[1]) if len(o) == 2 else o[0] for o in oses]) + os_help = ", ".join([f"{o[0]} ({o[1]})" if len(o) == 2 else o[0] for o in oses]) parser.add_argument( "--os", choices=[o[0] for o in oses], default=OS_AUTO, - help="select sample OS: %s" % os_help, + help=f"select sample OS: {os_help}", ) if "rules" in wanted: From b5f274bf56a29c8af86ad72d844c021f081370de Mon Sep 17 00:00:00 2001 From: Capa Bot Date: Tue, 28 Mar 2023 14:07:51 +0000 Subject: [PATCH 17/79] Sync capa rules submodule --- CHANGELOG.md | 3 ++- README.md | 2 +- rules | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81fe2abe..b17b00c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ ### Breaking Changes -### New Rules (23) +### New Rules (24) - persistence/scheduled-tasks/schedule-task-via-at joren485 - data-manipulation/prng/generate-random-numbers-via-rtlgenrandom william.ballenthin@mandiant.com @@ -36,6 +36,7 @@ - nursery/check-for-windows-sandbox-via-subdirectory echernofsky@google.com - nursery/enumerate-pe-sections-in-dotnet @mr-tz - nursery/destroy-software-breakpoint-capability echernofsky@google.com +- nursery/send-data-to-internet michael.hunhoff@mandiant.com - ### Bug Fixes diff --git a/README.md b/README.md index 91945fa4..2a40aaf1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/flare-capa)](https://pypi.org/project/flare-capa) [![Last release](https://img.shields.io/github/v/release/mandiant/capa)](https://github.com/mandiant/capa/releases) -[![Number of rules](https://img.shields.io/badge/rules-791-blue.svg)](https://github.com/mandiant/capa-rules) +[![Number of rules](https://img.shields.io/badge/rules-792-blue.svg)](https://github.com/mandiant/capa-rules) [![CI status](https://github.com/mandiant/capa/workflows/CI/badge.svg)](https://github.com/mandiant/capa/actions?query=workflow%3ACI+event%3Apush+branch%3Amaster) [![Downloads](https://img.shields.io/github/downloads/mandiant/capa/total)](https://github.com/mandiant/capa/releases) [![License](https://img.shields.io/badge/license-Apache--2.0-green.svg)](LICENSE.txt) diff --git a/rules b/rules index 48692d18..d0e54bb0 160000 --- a/rules +++ b/rules @@ -1 +1 @@ -Subproject commit 48692d18cc3fc6c96a608abe9fd9d8b010c63f83 +Subproject commit d0e54bb05d8549cd3979ff1b21a22ee33c533ad6 From 4990f7a2c8278f77c53bc6de04cd41867966157c Mon Sep 17 00:00:00 2001 From: manasghandat Date: Tue, 28 Mar 2023 22:11:37 +0530 Subject: [PATCH 18/79] Fix requested changes --- capa/render/proto/__init__.py | 1 + capa/render/proto/capa_pb2.py | 240 ++++----- capa/render/proto/capa_pb2.pyi | 889 +++++---------------------------- 3 files changed, 239 insertions(+), 891 deletions(-) diff --git a/capa/render/proto/__init__.py b/capa/render/proto/__init__.py index 0b43f2c1..7af7b664 100644 --- a/capa/render/proto/__init__.py +++ b/capa/render/proto/__init__.py @@ -595,6 +595,7 @@ def feature_from_pb2(f: capa_pb2.FeatureNode) -> frzf.Feature: elif type_ == "import_": ff = f.import_ return frzf.ImportFeature(import_=ff.import_, description=ff.description or None) # type: ignore + # Mypy is unable to recognize `import_` as an argument elif type_ == "section": ff = f.section return frzf.SectionFeature(section=ff.section, description=ff.description or None) diff --git a/capa/render/proto/capa_pb2.py b/capa/render/proto/capa_pb2.py index ad9dc304..d4ca17d0 100644 --- a/capa/render/proto/capa_pb2.py +++ b/capa/render/proto/capa_pb2.py @@ -6,132 +6,132 @@ 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 - # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1c\x63\x61pa/render/proto/capa.proto"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"l\n\x07\x41\x64\x64ress\x12\x1a\n\x04type\x18\x01 \x01(\x0e\x32\x0c.AddressType\x12\x15\n\x01v\x18\x02 \x01(\x0b\x32\x08.IntegerH\x00\x12%\n\x0ctoken_offset\x18\x03 \x01(\x0b\x32\r.Token_OffsetH\x00\x42\x07\n\x05value"\xe4\x01\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\x1e\n\x0c\x62\x61se_address\x18\x06 \x01(\x0b\x32\x08.Address\x12\x17\n\x06layout\x18\x07 \x01(\x0b\x32\x07.Layout\x12&\n\x0e\x66\x65\x61ture_counts\x18\x08 \x01(\x0b\x32\x0e.FeatureCounts\x12+\n\x11library_functions\x18\t \x03(\x0b\x32\x10.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\x19\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x08.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"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"G\n\rFeatureCounts\x12\x0c\n\x04\x66ile\x18\x01 \x01(\x04\x12(\n\tfunctions\x18\x02 \x03(\x0b\x32\x15.FunctionFeatureCount"\xf7\x06\n\x0b\x46\x65\x61tureNode\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x18\n\x02os\x18\x02 \x01(\x0b\x32\n.OSFeatureH\x00\x12\x1c\n\x04\x61rch\x18\x03 \x01(\x0b\x32\x0c.ArchFeatureH\x00\x12 \n\x06\x66ormat\x18\x04 \x01(\x0b\x32\x0e.FormatFeatureH\x00\x12\x1e\n\x05match\x18\x05 \x01(\x0b\x32\r.MatchFeatureH\x00\x12\x30\n\x0e\x63haracteristic\x18\x06 \x01(\x0b\x32\x16.CharacteristicFeatureH\x00\x12 \n\x06\x65xport\x18\x07 \x01(\x0b\x32\x0e.ExportFeatureH\x00\x12!\n\x07import_\x18\x08 \x01(\x0b\x32\x0e.ImportFeatureH\x00\x12"\n\x07section\x18\t \x01(\x0b\x32\x0f.SectionFeatureH\x00\x12-\n\rfunction_name\x18\n \x01(\x0b\x32\x14.FunctionNameFeatureH\x00\x12&\n\tsubstring\x18\x0b \x01(\x0b\x32\x11.SubstringFeatureH\x00\x12\x1e\n\x05regex\x18\x0c \x01(\x0b\x32\r.RegexFeatureH\x00\x12 \n\x06string\x18\r \x01(\x0b\x32\x0e.StringFeatureH\x00\x12\x1f\n\x06\x63lass_\x18\x0e \x01(\x0b\x32\r.ClassFeatureH\x00\x12&\n\tnamespace\x18\x0f \x01(\x0b\x32\x11.NamespaceFeatureH\x00\x12\x1a\n\x03\x61pi\x18\x10 \x01(\x0b\x32\x0b.APIFeatureH\x00\x12%\n\tproperty_\x18\x11 \x01(\x0b\x32\x10.PropertyFeatureH\x00\x12 \n\x06number\x18\x12 \x01(\x0b\x32\x0e.NumberFeatureH\x00\x12\x1e\n\x05\x62ytes\x18\x13 \x01(\x0b\x32\r.BytesFeatureH\x00\x12 \n\x06offset\x18\x14 \x01(\x0b\x32\x0e.OffsetFeatureH\x00\x12$\n\x08mnemonic\x18\x15 \x01(\x0b\x32\x10.MnemonicFeatureH\x00\x12/\n\x0eoperand_number\x18\x16 \x01(\x0b\x32\x15.OperandNumberFeatureH\x00\x12/\n\x0eoperand_offset\x18\x17 \x01(\x0b\x32\x15.OperandOffsetFeatureH\x00\x12)\n\x0b\x62\x61sic_block\x18\x18 \x01(\x0b\x32\x12.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\x14\x46unctionFeatureCount\x12\x19\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x08.Address\x12\r\n\x05\x63ount\x18\x02 \x01(\x04"\\\n\x0e\x46unctionLayout\x12\x19\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x08.Address\x12/\n\x14matched_basic_blocks\x18\x02 \x03(\x0b\x32\x11.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"\n\tfunctions\x18\x01 \x03(\x0b\x32\x0f.FunctionLayout":\n\x0fLibraryFunction\x12\x19\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x08.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"\x82\x02\n\x05Match\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12#\n\tstatement\x18\x02 \x01(\x0b\x32\x0e.StatementNodeH\x00\x12\x1f\n\x07\x66\x65\x61ture\x18\x03 \x01(\x0b\x32\x0c.FeatureNodeH\x00\x12\x18\n\x08\x63hildren\x18\x05 \x03(\x0b\x32\x06.Match\x12\x1b\n\tlocations\x18\x06 \x03(\x0b\x32\x08.Address\x12&\n\x08\x63\x61ptures\x18\x07 \x03(\x0b\x32\x14.Match.CapturesEntry\x1a;\n\rCapturesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x19\n\x05value\x18\x02 \x01(\x0b\x32\n.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"r\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\x17\n\x06sample\x18\x04 \x01(\x0b\x32\x07.Sample\x12\x1b\n\x08\x61nalysis\x18\x05 \x01(\x0b\x32\t.Analysis"[\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\rNumberFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x17\n\x06number\x18\x02 \x01(\x0b\x32\x07.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"a\n\rOffsetFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x18\n\x06offset\x18\x02 \x01(\x0b\x32\x08.Integer\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description"\x7f\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\x08.Integer\x12\x18\n\x0b\x64\x65scription\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description"\x7f\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\x08.Integer\x12\x18\n\x0b\x64\x65scription\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description"|\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"\x7f\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\x1b\n\x05\x63hild\x18\x04 \x01(\x0b\x32\x0c.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"\x90\x01\n\x0eResultDocument\x12\x17\n\x04meta\x18\x01 \x01(\x0b\x32\t.Metadata\x12)\n\x05rules\x18\x02 \x03(\x0b\x32\x1a.ResultDocument.RulesEntry\x1a:\n\nRulesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x1b\n\x05value\x18\x02 \x01(\x0b\x32\x0c.RuleMatches:\x02\x38\x01"`\n\x0bRuleMatches\x12\x1b\n\x04meta\x18\x01 \x01(\x0b\x32\r.RuleMetadata\x12\x0e\n\x06source\x18\x02 \x01(\t\x12$\n\x07matches\x18\x03 \x03(\x0b\x32\x13.Pair_Address_Match"\x8a\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\x15\n\x05scope\x18\x04 \x01(\x0e\x32\x06.Scope\x12\x1b\n\x06\x61ttack\x18\x05 \x03(\x0b\x32\x0b.AttackSpec\x12\x15\n\x03mbc\x18\x06 \x03(\x0b\x32\x08.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\x1b\n\x04maec\x18\x0b \x01(\x0b\x32\r.MaecMetadata\x12\x18\n\x10is_subscope_rule\x18\x0c \x01(\x08"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"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"\xbc\x01\n\rStatementNode\x12\x0c\n\x04type\x18\x01 \x01(\t\x12 \n\x05range\x18\x02 \x01(\x0b\x32\x0f.RangeStatementH\x00\x12\x1e\n\x04some\x18\x03 \x01(\x0b\x32\x0e.SomeStatementH\x00\x12&\n\x08subscope\x18\x04 \x01(\x0b\x32\x12.SubscopeStatementH\x00\x12&\n\x08\x63ompound\x18\x05 \x01(\x0b\x32\x12.CompoundStatementH\x00\x42\x0b\n\tstatement"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"b\n\x11SubscopeStatement\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x15\n\x05scope\x18\x02 \x01(\x0e\x32\x06.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"&\n\tAddresses\x12\x19\n\x07\x61\x64\x64ress\x18\x01 \x03(\x0b\x32\x08.Address"F\n\x12Pair_Address_Match\x12\x19\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x08.Address\x12\x15\n\x05match\x18\x02 \x01(\x0b\x32\x06.Match"7\n\x0cToken_Offset\x12\x17\n\x05token\x18\x01 \x01(\x0b\x32\x08.Integer\x12\x0e\n\x06offset\x18\x02 \x01(\x04",\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*\xcb\x01\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*p\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\x62\x06proto3' -) + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1c\x63\x61pa/render/proto/capa.proto\"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\"l\n\x07\x41\x64\x64ress\x12\x1a\n\x04type\x18\x01 \x01(\x0e\x32\x0c.AddressType\x12\x15\n\x01v\x18\x02 \x01(\x0b\x32\x08.IntegerH\x00\x12%\n\x0ctoken_offset\x18\x03 \x01(\x0b\x32\r.Token_OffsetH\x00\x42\x07\n\x05value\"\xe4\x01\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\x1e\n\x0c\x62\x61se_address\x18\x06 \x01(\x0b\x32\x08.Address\x12\x17\n\x06layout\x18\x07 \x01(\x0b\x32\x07.Layout\x12&\n\x0e\x66\x65\x61ture_counts\x18\x08 \x01(\x0b\x32\x0e.FeatureCounts\x12+\n\x11library_functions\x18\t \x03(\x0b\x32\x10.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\x19\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x08.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\"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\"G\n\rFeatureCounts\x12\x0c\n\x04\x66ile\x18\x01 \x01(\x04\x12(\n\tfunctions\x18\x02 \x03(\x0b\x32\x15.FunctionFeatureCount\"\xf7\x06\n\x0b\x46\x65\x61tureNode\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x18\n\x02os\x18\x02 \x01(\x0b\x32\n.OSFeatureH\x00\x12\x1c\n\x04\x61rch\x18\x03 \x01(\x0b\x32\x0c.ArchFeatureH\x00\x12 \n\x06\x66ormat\x18\x04 \x01(\x0b\x32\x0e.FormatFeatureH\x00\x12\x1e\n\x05match\x18\x05 \x01(\x0b\x32\r.MatchFeatureH\x00\x12\x30\n\x0e\x63haracteristic\x18\x06 \x01(\x0b\x32\x16.CharacteristicFeatureH\x00\x12 \n\x06\x65xport\x18\x07 \x01(\x0b\x32\x0e.ExportFeatureH\x00\x12!\n\x07import_\x18\x08 \x01(\x0b\x32\x0e.ImportFeatureH\x00\x12\"\n\x07section\x18\t \x01(\x0b\x32\x0f.SectionFeatureH\x00\x12-\n\rfunction_name\x18\n \x01(\x0b\x32\x14.FunctionNameFeatureH\x00\x12&\n\tsubstring\x18\x0b \x01(\x0b\x32\x11.SubstringFeatureH\x00\x12\x1e\n\x05regex\x18\x0c \x01(\x0b\x32\r.RegexFeatureH\x00\x12 \n\x06string\x18\r \x01(\x0b\x32\x0e.StringFeatureH\x00\x12\x1f\n\x06\x63lass_\x18\x0e \x01(\x0b\x32\r.ClassFeatureH\x00\x12&\n\tnamespace\x18\x0f \x01(\x0b\x32\x11.NamespaceFeatureH\x00\x12\x1a\n\x03\x61pi\x18\x10 \x01(\x0b\x32\x0b.APIFeatureH\x00\x12%\n\tproperty_\x18\x11 \x01(\x0b\x32\x10.PropertyFeatureH\x00\x12 \n\x06number\x18\x12 \x01(\x0b\x32\x0e.NumberFeatureH\x00\x12\x1e\n\x05\x62ytes\x18\x13 \x01(\x0b\x32\r.BytesFeatureH\x00\x12 \n\x06offset\x18\x14 \x01(\x0b\x32\x0e.OffsetFeatureH\x00\x12$\n\x08mnemonic\x18\x15 \x01(\x0b\x32\x10.MnemonicFeatureH\x00\x12/\n\x0eoperand_number\x18\x16 \x01(\x0b\x32\x15.OperandNumberFeatureH\x00\x12/\n\x0eoperand_offset\x18\x17 \x01(\x0b\x32\x15.OperandOffsetFeatureH\x00\x12)\n\x0b\x62\x61sic_block\x18\x18 \x01(\x0b\x32\x12.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\x14\x46unctionFeatureCount\x12\x19\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x08.Address\x12\r\n\x05\x63ount\x18\x02 \x01(\x04\"\\\n\x0e\x46unctionLayout\x12\x19\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x08.Address\x12/\n\x14matched_basic_blocks\x18\x02 \x03(\x0b\x32\x11.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\"\n\tfunctions\x18\x01 \x03(\x0b\x32\x0f.FunctionLayout\":\n\x0fLibraryFunction\x12\x19\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x08.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\"\x82\x02\n\x05Match\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12#\n\tstatement\x18\x02 \x01(\x0b\x32\x0e.StatementNodeH\x00\x12\x1f\n\x07\x66\x65\x61ture\x18\x03 \x01(\x0b\x32\x0c.FeatureNodeH\x00\x12\x18\n\x08\x63hildren\x18\x05 \x03(\x0b\x32\x06.Match\x12\x1b\n\tlocations\x18\x06 \x03(\x0b\x32\x08.Address\x12&\n\x08\x63\x61ptures\x18\x07 \x03(\x0b\x32\x14.Match.CapturesEntry\x1a;\n\rCapturesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x19\n\x05value\x18\x02 \x01(\x0b\x32\n.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\"r\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\x17\n\x06sample\x18\x04 \x01(\x0b\x32\x07.Sample\x12\x1b\n\x08\x61nalysis\x18\x05 \x01(\x0b\x32\t.Analysis\"[\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\rNumberFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x17\n\x06number\x18\x02 \x01(\x0b\x32\x07.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\"a\n\rOffsetFeature\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x18\n\x06offset\x18\x02 \x01(\x0b\x32\x08.Integer\x12\x18\n\x0b\x64\x65scription\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\x7f\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\x08.Integer\x12\x18\n\x0b\x64\x65scription\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\x7f\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\x08.Integer\x12\x18\n\x0b\x64\x65scription\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"|\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\"\x7f\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\x1b\n\x05\x63hild\x18\x04 \x01(\x0b\x32\x0c.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\"\x90\x01\n\x0eResultDocument\x12\x17\n\x04meta\x18\x01 \x01(\x0b\x32\t.Metadata\x12)\n\x05rules\x18\x02 \x03(\x0b\x32\x1a.ResultDocument.RulesEntry\x1a:\n\nRulesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x1b\n\x05value\x18\x02 \x01(\x0b\x32\x0c.RuleMatches:\x02\x38\x01\"`\n\x0bRuleMatches\x12\x1b\n\x04meta\x18\x01 \x01(\x0b\x32\r.RuleMetadata\x12\x0e\n\x06source\x18\x02 \x01(\t\x12$\n\x07matches\x18\x03 \x03(\x0b\x32\x13.Pair_Address_Match\"\x8a\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\x15\n\x05scope\x18\x04 \x01(\x0e\x32\x06.Scope\x12\x1b\n\x06\x61ttack\x18\x05 \x03(\x0b\x32\x0b.AttackSpec\x12\x15\n\x03mbc\x18\x06 \x03(\x0b\x32\x08.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\x1b\n\x04maec\x18\x0b \x01(\x0b\x32\r.MaecMetadata\x12\x18\n\x10is_subscope_rule\x18\x0c \x01(\x08\"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\"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\"\xbc\x01\n\rStatementNode\x12\x0c\n\x04type\x18\x01 \x01(\t\x12 \n\x05range\x18\x02 \x01(\x0b\x32\x0f.RangeStatementH\x00\x12\x1e\n\x04some\x18\x03 \x01(\x0b\x32\x0e.SomeStatementH\x00\x12&\n\x08subscope\x18\x04 \x01(\x0b\x32\x12.SubscopeStatementH\x00\x12&\n\x08\x63ompound\x18\x05 \x01(\x0b\x32\x12.CompoundStatementH\x00\x42\x0b\n\tstatement\"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\"b\n\x11SubscopeStatement\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x15\n\x05scope\x18\x02 \x01(\x0e\x32\x06.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\"&\n\tAddresses\x12\x19\n\x07\x61\x64\x64ress\x18\x01 \x03(\x0b\x32\x08.Address\"F\n\x12Pair_Address_Match\x12\x19\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0b\x32\x08.Address\x12\x15\n\x05match\x18\x02 \x01(\x0b\x32\x06.Match\"7\n\x0cToken_Offset\x12\x17\n\x05token\x18\x01 \x01(\x0b\x32\x08.Integer\x12\x0e\n\x06offset\x18\x02 \x01(\x04\",\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*\xcb\x01\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*p\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\x62\x06proto3') _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "capa.render.proto.capa_pb2", 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" - _RESULTDOCUMENT_RULESENTRY._options = None - _RESULTDOCUMENT_RULESENTRY._serialized_options = b"8\001" - _ADDRESSTYPE._serialized_start = 6006 - _ADDRESSTYPE._serialized_end = 6209 - _SCOPE._serialized_start = 6211 - _SCOPE._serialized_end = 6323 - _APIFEATURE._serialized_start = 32 - _APIFEATURE._serialized_end = 113 - _ADDRESS._serialized_start = 115 - _ADDRESS._serialized_end = 223 - _ANALYSIS._serialized_start = 226 - _ANALYSIS._serialized_end = 454 - _ARCHFEATURE._serialized_start = 456 - _ARCHFEATURE._serialized_end = 539 - _ATTACKSPEC._serialized_start = 541 - _ATTACKSPEC._serialized_end = 637 - _BASICBLOCKFEATURE._serialized_start = 639 - _BASICBLOCKFEATURE._serialized_end = 714 - _BASICBLOCKLAYOUT._serialized_start = 716 - _BASICBLOCKLAYOUT._serialized_end = 761 - _BYTESFEATURE._serialized_start = 763 - _BYTESFEATURE._serialized_end = 848 - _CHARACTERISTICFEATURE._serialized_start = 850 - _CHARACTERISTICFEATURE._serialized_end = 953 - _CLASSFEATURE._serialized_start = 955 - _CLASSFEATURE._serialized_end = 1041 - _COMPOUNDSTATEMENT._serialized_start = 1043 - _COMPOUNDSTATEMENT._serialized_end = 1118 - _EXPORTFEATURE._serialized_start = 1120 - _EXPORTFEATURE._serialized_end = 1207 - _FEATURECOUNTS._serialized_start = 1209 - _FEATURECOUNTS._serialized_end = 1280 - _FEATURENODE._serialized_start = 1283 - _FEATURENODE._serialized_end = 2170 - _FORMATFEATURE._serialized_start = 2172 - _FORMATFEATURE._serialized_end = 2259 - _FUNCTIONFEATURECOUNT._serialized_start = 2261 - _FUNCTIONFEATURECOUNT._serialized_end = 2325 - _FUNCTIONLAYOUT._serialized_start = 2327 - _FUNCTIONLAYOUT._serialized_end = 2419 - _FUNCTIONNAMEFEATURE._serialized_start = 2421 - _FUNCTIONNAMEFEATURE._serialized_end = 2521 - _IMPORTFEATURE._serialized_start = 2523 - _IMPORTFEATURE._serialized_end = 2611 - _LAYOUT._serialized_start = 2613 - _LAYOUT._serialized_end = 2657 - _LIBRARYFUNCTION._serialized_start = 2659 - _LIBRARYFUNCTION._serialized_end = 2717 - _MBCSPEC._serialized_start = 2719 - _MBCSPEC._serialized_end = 2808 - _MAECMETADATA._serialized_start = 2811 - _MAECMETADATA._serialized_end = 2965 - _MATCH._serialized_start = 2968 - _MATCH._serialized_end = 3226 - _MATCH_CAPTURESENTRY._serialized_start = 3159 - _MATCH_CAPTURESENTRY._serialized_end = 3218 - _MATCHFEATURE._serialized_start = 3228 - _MATCHFEATURE._serialized_end = 3313 - _METADATA._serialized_start = 3315 - _METADATA._serialized_end = 3429 - _MNEMONICFEATURE._serialized_start = 3431 - _MNEMONICFEATURE._serialized_end = 3522 - _NAMESPACEFEATURE._serialized_start = 3524 - _NAMESPACEFEATURE._serialized_end = 3617 - _NUMBERFEATURE._serialized_start = 3619 - _NUMBERFEATURE._serialized_end = 3715 - _OSFEATURE._serialized_start = 3717 - _OSFEATURE._serialized_end = 3796 - _OFFSETFEATURE._serialized_start = 3798 - _OFFSETFEATURE._serialized_end = 3895 - _OPERANDNUMBERFEATURE._serialized_start = 3897 - _OPERANDNUMBERFEATURE._serialized_end = 4024 - _OPERANDOFFSETFEATURE._serialized_start = 4026 - _OPERANDOFFSETFEATURE._serialized_end = 4153 - _PROPERTYFEATURE._serialized_start = 4155 - _PROPERTYFEATURE._serialized_end = 4279 - _RANGESTATEMENT._serialized_start = 4281 - _RANGESTATEMENT._serialized_end = 4408 - _REGEXFEATURE._serialized_start = 4410 - _REGEXFEATURE._serialized_end = 4495 - _RESULTDOCUMENT._serialized_start = 4498 - _RESULTDOCUMENT._serialized_end = 4642 - _RESULTDOCUMENT_RULESENTRY._serialized_start = 4584 - _RESULTDOCUMENT_RULESENTRY._serialized_end = 4642 - _RULEMATCHES._serialized_start = 4644 - _RULEMATCHES._serialized_end = 4740 - _RULEMETADATA._serialized_start = 4743 - _RULEMETADATA._serialized_end = 5009 - _SAMPLE._serialized_start = 5011 - _SAMPLE._serialized_end = 5076 - _SECTIONFEATURE._serialized_start = 5078 - _SECTIONFEATURE._serialized_end = 5167 - _SOMESTATEMENT._serialized_start = 5169 - _SOMESTATEMENT._serialized_end = 5255 - _STATEMENTNODE._serialized_start = 5258 - _STATEMENTNODE._serialized_end = 5446 - _STRINGFEATURE._serialized_start = 5448 - _STRINGFEATURE._serialized_end = 5535 - _SUBSCOPESTATEMENT._serialized_start = 5537 - _SUBSCOPESTATEMENT._serialized_end = 5635 - _SUBSTRINGFEATURE._serialized_start = 5637 - _SUBSTRINGFEATURE._serialized_end = 5730 - _ADDRESSES._serialized_start = 5732 - _ADDRESSES._serialized_end = 5770 - _PAIR_ADDRESS_MATCH._serialized_start = 5772 - _PAIR_ADDRESS_MATCH._serialized_end = 5842 - _TOKEN_OFFSET._serialized_start = 5844 - _TOKEN_OFFSET._serialized_end = 5899 - _INTEGER._serialized_start = 5901 - _INTEGER._serialized_end = 5945 - _NUMBER._serialized_start = 5947 - _NUMBER._serialized_end = 6003 + + DESCRIPTOR._options = None + _MATCH_CAPTURESENTRY._options = None + _MATCH_CAPTURESENTRY._serialized_options = b'8\001' + _RESULTDOCUMENT_RULESENTRY._options = None + _RESULTDOCUMENT_RULESENTRY._serialized_options = b'8\001' + _ADDRESSTYPE._serialized_start=6006 + _ADDRESSTYPE._serialized_end=6209 + _SCOPE._serialized_start=6211 + _SCOPE._serialized_end=6323 + _APIFEATURE._serialized_start=32 + _APIFEATURE._serialized_end=113 + _ADDRESS._serialized_start=115 + _ADDRESS._serialized_end=223 + _ANALYSIS._serialized_start=226 + _ANALYSIS._serialized_end=454 + _ARCHFEATURE._serialized_start=456 + _ARCHFEATURE._serialized_end=539 + _ATTACKSPEC._serialized_start=541 + _ATTACKSPEC._serialized_end=637 + _BASICBLOCKFEATURE._serialized_start=639 + _BASICBLOCKFEATURE._serialized_end=714 + _BASICBLOCKLAYOUT._serialized_start=716 + _BASICBLOCKLAYOUT._serialized_end=761 + _BYTESFEATURE._serialized_start=763 + _BYTESFEATURE._serialized_end=848 + _CHARACTERISTICFEATURE._serialized_start=850 + _CHARACTERISTICFEATURE._serialized_end=953 + _CLASSFEATURE._serialized_start=955 + _CLASSFEATURE._serialized_end=1041 + _COMPOUNDSTATEMENT._serialized_start=1043 + _COMPOUNDSTATEMENT._serialized_end=1118 + _EXPORTFEATURE._serialized_start=1120 + _EXPORTFEATURE._serialized_end=1207 + _FEATURECOUNTS._serialized_start=1209 + _FEATURECOUNTS._serialized_end=1280 + _FEATURENODE._serialized_start=1283 + _FEATURENODE._serialized_end=2170 + _FORMATFEATURE._serialized_start=2172 + _FORMATFEATURE._serialized_end=2259 + _FUNCTIONFEATURECOUNT._serialized_start=2261 + _FUNCTIONFEATURECOUNT._serialized_end=2325 + _FUNCTIONLAYOUT._serialized_start=2327 + _FUNCTIONLAYOUT._serialized_end=2419 + _FUNCTIONNAMEFEATURE._serialized_start=2421 + _FUNCTIONNAMEFEATURE._serialized_end=2521 + _IMPORTFEATURE._serialized_start=2523 + _IMPORTFEATURE._serialized_end=2611 + _LAYOUT._serialized_start=2613 + _LAYOUT._serialized_end=2657 + _LIBRARYFUNCTION._serialized_start=2659 + _LIBRARYFUNCTION._serialized_end=2717 + _MBCSPEC._serialized_start=2719 + _MBCSPEC._serialized_end=2808 + _MAECMETADATA._serialized_start=2811 + _MAECMETADATA._serialized_end=2965 + _MATCH._serialized_start=2968 + _MATCH._serialized_end=3226 + _MATCH_CAPTURESENTRY._serialized_start=3159 + _MATCH_CAPTURESENTRY._serialized_end=3218 + _MATCHFEATURE._serialized_start=3228 + _MATCHFEATURE._serialized_end=3313 + _METADATA._serialized_start=3315 + _METADATA._serialized_end=3429 + _MNEMONICFEATURE._serialized_start=3431 + _MNEMONICFEATURE._serialized_end=3522 + _NAMESPACEFEATURE._serialized_start=3524 + _NAMESPACEFEATURE._serialized_end=3617 + _NUMBERFEATURE._serialized_start=3619 + _NUMBERFEATURE._serialized_end=3715 + _OSFEATURE._serialized_start=3717 + _OSFEATURE._serialized_end=3796 + _OFFSETFEATURE._serialized_start=3798 + _OFFSETFEATURE._serialized_end=3895 + _OPERANDNUMBERFEATURE._serialized_start=3897 + _OPERANDNUMBERFEATURE._serialized_end=4024 + _OPERANDOFFSETFEATURE._serialized_start=4026 + _OPERANDOFFSETFEATURE._serialized_end=4153 + _PROPERTYFEATURE._serialized_start=4155 + _PROPERTYFEATURE._serialized_end=4279 + _RANGESTATEMENT._serialized_start=4281 + _RANGESTATEMENT._serialized_end=4408 + _REGEXFEATURE._serialized_start=4410 + _REGEXFEATURE._serialized_end=4495 + _RESULTDOCUMENT._serialized_start=4498 + _RESULTDOCUMENT._serialized_end=4642 + _RESULTDOCUMENT_RULESENTRY._serialized_start=4584 + _RESULTDOCUMENT_RULESENTRY._serialized_end=4642 + _RULEMATCHES._serialized_start=4644 + _RULEMATCHES._serialized_end=4740 + _RULEMETADATA._serialized_start=4743 + _RULEMETADATA._serialized_end=5009 + _SAMPLE._serialized_start=5011 + _SAMPLE._serialized_end=5076 + _SECTIONFEATURE._serialized_start=5078 + _SECTIONFEATURE._serialized_end=5167 + _SOMESTATEMENT._serialized_start=5169 + _SOMESTATEMENT._serialized_end=5255 + _STATEMENTNODE._serialized_start=5258 + _STATEMENTNODE._serialized_end=5446 + _STRINGFEATURE._serialized_start=5448 + _STRINGFEATURE._serialized_end=5535 + _SUBSCOPESTATEMENT._serialized_start=5537 + _SUBSCOPESTATEMENT._serialized_end=5635 + _SUBSTRINGFEATURE._serialized_start=5637 + _SUBSTRINGFEATURE._serialized_end=5730 + _ADDRESSES._serialized_start=5732 + _ADDRESSES._serialized_end=5770 + _PAIR_ADDRESS_MATCH._serialized_start=5772 + _PAIR_ADDRESS_MATCH._serialized_end=5842 + _TOKEN_OFFSET._serialized_start=5844 + _TOKEN_OFFSET._serialized_end=5899 + _INTEGER._serialized_start=5901 + _INTEGER._serialized_end=5945 + _NUMBER._serialized_start=5947 + _NUMBER._serialized_end=6003 # @@protoc_insertion_point(module_scope) diff --git a/capa/render/proto/capa_pb2.pyi b/capa/render/proto/capa_pb2.pyi index 861a155c..174b1a97 100644 --- a/capa/render/proto/capa_pb2.pyi +++ b/capa/render/proto/capa_pb2.pyi @@ -22,9 +22,7 @@ class _AddressType: ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType -class _AddressTypeEnumTypeWrapper( - google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_AddressType.ValueType], builtins.type -): +class _AddressTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_AddressType.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor ADDRESSTYPE_UNSPECIFIED: _AddressType.ValueType # 0 ADDRESSTYPE_ABSOLUTE: _AddressType.ValueType # 1 @@ -49,9 +47,7 @@ class _Scope: ValueType = typing.NewType("ValueType", builtins.int) V: typing_extensions.TypeAlias = ValueType -class _ScopeEnumTypeWrapper( - google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_Scope.ValueType], builtins.type -): +class _ScopeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_Scope.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor SCOPE_UNSPECIFIED: _Scope.ValueType # 0 SCOPE_FILE: _Scope.ValueType # 1 @@ -85,18 +81,9 @@ 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_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: ... global___APIFeature = APIFeature @@ -119,18 +106,9 @@ class Address(google.protobuf.message.Message): v: global___Integer | None = ..., token_offset: global___Token_Offset | None = ..., ) -> None: ... - def HasField( - self, field_name: typing_extensions.Literal["token_offset", b"token_offset", "v", b"v", "value", b"value"] - ) -> builtins.bool: ... - def ClearField( - self, - field_name: typing_extensions.Literal[ - "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"] | None: ... + def HasField(self, field_name: typing_extensions.Literal["token_offset", b"token_offset", "v", b"v", "value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["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"] | None: ... global___Address = Address @@ -160,9 +138,7 @@ class Analysis(google.protobuf.message.Message): @property def feature_counts(self) -> global___FeatureCounts: ... @property - def library_functions( - self, - ) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___LibraryFunction]: ... + def library_functions(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___LibraryFunction]: ... def __init__( self, *, @@ -176,35 +152,8 @@ 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_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: ... global___Analysis = Analysis @@ -225,18 +174,9 @@ 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_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: ... global___ArchFeature = ArchFeature @@ -264,21 +204,7 @@ 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_extensions.Literal["id", b"id", "parts", b"parts", "subtechnique", b"subtechnique", "tactic", b"tactic", "technique", b"technique"]) -> None: ... global___AttackSpec = AttackSpec @@ -296,18 +222,9 @@ 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_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: ... global___BasicBlockFeature = BasicBlockFeature @@ -345,18 +262,9 @@ 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_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: ... global___BytesFeature = BytesFeature @@ -377,25 +285,9 @@ 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_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: ... global___CharacteristicFeature = CharacteristicFeature @@ -417,18 +309,9 @@ 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_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: ... global___ClassFeature = ClassFeature @@ -446,18 +329,9 @@ 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_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: ... global___CompoundStatement = CompoundStatement @@ -478,18 +352,9 @@ 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_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: ... global___ExportFeature = ExportFeature @@ -501,9 +366,7 @@ class FeatureCounts(google.protobuf.message.Message): FUNCTIONS_FIELD_NUMBER: builtins.int file: builtins.int @property - def functions( - self, - ) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___FunctionFeatureCount]: ... + def functions(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___FunctionFeatureCount]: ... def __init__( self, *, @@ -619,144 +482,9 @@ 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_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: ... global___FeatureNode = FeatureNode @@ -777,18 +505,9 @@ 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_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: ... global___FormatFeature = FormatFeature @@ -821,9 +540,7 @@ class FunctionLayout(google.protobuf.message.Message): @property def address(self) -> global___Address: ... @property - def matched_basic_blocks( - self, - ) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___BasicBlockLayout]: ... + def matched_basic_blocks(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___BasicBlockLayout]: ... def __init__( self, *, @@ -831,10 +548,7 @@ class FunctionLayout(google.protobuf.message.Message): 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 ClearField(self, field_name: typing_extensions.Literal["address", b"address", "matched_basic_blocks", b"matched_basic_blocks"]) -> None: ... global___FunctionLayout = FunctionLayout @@ -855,25 +569,9 @@ 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_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: ... global___FunctionNameFeature = FunctionNameFeature @@ -894,18 +592,9 @@ 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_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: ... global___ImportFeature = ImportFeature @@ -915,9 +604,7 @@ class Layout(google.protobuf.message.Message): FUNCTIONS_FIELD_NUMBER: builtins.int @property - def functions( - self, - ) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___FunctionLayout]: ... + def functions(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___FunctionLayout]: ... def __init__( self, *, @@ -971,12 +658,7 @@ 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_extensions.Literal["behavior", b"behavior", "id", b"id", "method", b"method", "objective", b"objective", "parts", b"parts"]) -> None: ... global___MBCSpec = MBCSpec @@ -1003,21 +685,7 @@ 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_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: ... global___MaecMetadata = MaecMetadata @@ -1070,31 +738,9 @@ 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_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: ... global___Match = Match @@ -1115,18 +761,9 @@ 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_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: ... global___MatchFeature = MatchFeature @@ -1157,24 +794,8 @@ class Metadata(google.protobuf.message.Message): sample: global___Sample | None = ..., analysis: global___Analysis | None = ..., ) -> None: ... - def HasField( - self, field_name: typing_extensions.Literal["analysis", b"analysis", "sample", b"sample"] - ) -> builtins.bool: ... - def ClearField( - self, - field_name: typing_extensions.Literal[ - "analysis", - b"analysis", - "argv", - b"argv", - "sample", - b"sample", - "timestamp", - b"timestamp", - "version", - b"version", - ], - ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["analysis", b"analysis", "sample", b"sample"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["analysis", b"analysis", "argv", b"argv", "sample", b"sample", "timestamp", b"timestamp", "version", b"version"]) -> None: ... global___Metadata = Metadata @@ -1195,18 +816,9 @@ 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_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: ... global___MnemonicFeature = MnemonicFeature @@ -1227,18 +839,9 @@ 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_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: ... global___NamespaceFeature = NamespaceFeature @@ -1261,21 +864,9 @@ 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_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: ... global___NumberFeature = NumberFeature @@ -1296,18 +887,9 @@ 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_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: ... global___OSFeature = OSFeature @@ -1330,21 +912,9 @@ 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_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: ... global___OffsetFeature = OffsetFeature @@ -1370,30 +940,9 @@ 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_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: ... global___OperandNumberFeature = OperandNumberFeature @@ -1418,30 +967,9 @@ 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_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: ... global___OperandOffsetFeature = OperandOffsetFeature @@ -1466,37 +994,12 @@ 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_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: ... @typing.overload - def WhichOneof( - self, oneof_group: typing_extensions.Literal["_access", b"_access"] - ) -> typing_extensions.Literal["access"] | None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["_access", b"_access"]) -> typing_extensions.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_extensions.Literal["_description", b"_description"]) -> typing_extensions.Literal["description"] | None: ... global___PropertyFeature = PropertyFeature @@ -1525,32 +1028,9 @@ 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_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: ... global___RangeStatement = RangeStatement @@ -1571,18 +1051,9 @@ 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_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: ... global___RegexFeature = RegexFeature @@ -1636,9 +1107,7 @@ class RuleMatches(google.protobuf.message.Message): def meta(self) -> global___RuleMetadata: ... source: builtins.str @property - def matches( - self, - ) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Pair_Address_Match]: ... + def matches(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Pair_Address_Match]: ... def __init__( self, *, @@ -1647,9 +1116,7 @@ class RuleMatches(google.protobuf.message.Message): 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 ClearField(self, field_name: typing_extensions.Literal["matches", b"matches", "meta", b"meta", "source", b"source"]) -> None: ... global___RuleMatches = RuleMatches @@ -1704,35 +1171,7 @@ class RuleMetadata(google.protobuf.message.Message): is_subscope_rule: builtins.bool = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["maec", b"maec"]) -> 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", - ], - ) -> None: ... + 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"]) -> None: ... global___RuleMetadata = RuleMetadata @@ -1756,10 +1195,7 @@ 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_extensions.Literal["md5", b"md5", "path", b"path", "sha1", b"sha1", "sha256", b"sha256"]) -> None: ... global___Sample = Sample @@ -1780,18 +1216,9 @@ 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_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: ... global___SectionFeature = SectionFeature @@ -1812,18 +1239,9 @@ 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_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: ... global___SomeStatement = SomeStatement @@ -1854,41 +1272,9 @@ 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_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: ... global___StatementNode = StatementNode @@ -1909,18 +1295,9 @@ 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_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: ... global___StringFeature = StringFeature @@ -1941,18 +1318,9 @@ 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_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: ... global___SubscopeStatement = SubscopeStatement @@ -1973,18 +1341,9 @@ 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_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: ... global___SubstringFeature = SubstringFeature @@ -2020,9 +1379,7 @@ 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 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: ... global___Pair_Address_Match = Pair_Address_Match @@ -2062,13 +1419,9 @@ 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 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 WhichOneof(self, oneof_group: typing_extensions.Literal["value", b"value"]) -> typing_extensions.Literal["u", "i"] | None: ... global___Integer = Integer @@ -2089,14 +1442,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_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: ... global___Number = Number From fdc95303520031a49a2364181ea7c2d14e19c079 Mon Sep 17 00:00:00 2001 From: Pratham Chauhan Date: Wed, 29 Mar 2023 08:34:06 +0530 Subject: [PATCH 19/79] seperating loading json and to_capa logic --- capa/main.py | 6 ++---- capa/render/result_document.py | 14 +++++++++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/capa/main.py b/capa/main.py index 38f0837d..cf3d68c9 100644 --- a/capa/main.py +++ b/capa/main.py @@ -1125,10 +1125,8 @@ def main(argv=None): logger.debug("file limitation short circuit, won't analyze fully.") return E_FILE_LIMITATION if format_ == FORMAT_RESULT: - with open(args.sample, "rb") as f: - buf = f.read() - buf.decode("utf-8") - meta, capabilities = capa.render.result_document.ResultDocument.parse_raw(buf,rules) + result_doc = capa.render.result_document.ResultDocument.parse_raw(args.sample) + meta, capabilities = result_doc.to_capa(rules) elif format_ == FORMAT_FREEZE: with open(args.sample, "rb") as f: extractor = capa.features.freeze.load(f.read()) diff --git a/capa/render/result_document.py b/capa/render/result_document.py index 39a9e7a9..877595cf 100644 --- a/capa/render/result_document.py +++ b/capa/render/result_document.py @@ -582,13 +582,17 @@ class ResultDocument(BaseModel): return ResultDocument(meta=Metadata.from_capa(meta), rules=rule_matches) @classmethod - def parse_raw(cls, raw: str, rules: RuleSet): - data = json.loads(raw) - result_doc = ResultDocument(**data) + def parse_raw(cls, path: str): + with open(path, "rb") as f: + buf= f.read() + data = json.loads(buf) + return ResultDocument(**data) + def to_capa(self, rules: RuleSet) -> Tuple[Dict, Dict]: + meta = self.meta.to_capa() capabilities: Dict[str, List[Tuple[frz.Address, capa.features.common.Result]]] ={} - for rule_name, rule_match in result_doc.rules.items(): + for rule_name, rule_match in self.rules.items(): # Extract the capabilities from the RuleMatches object for addr, match in rule_match.matches: @@ -615,4 +619,4 @@ class ResultDocument(BaseModel): capabilities[rule_name]=[] capabilities[rule_name].append((frz.Address.from_capa(addr),result)) - return result_doc.meta.to_capa(), capabilities \ No newline at end of file + return meta, capabilities \ No newline at end of file From 637dd6bf0ace1d89ac5ea756913f10eefa9170dd Mon Sep 17 00:00:00 2001 From: Pratham Chauhan Date: Wed, 29 Mar 2023 15:51:25 +0530 Subject: [PATCH 20/79] Added a unit test --- tests/test_result_document.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/test_result_document.py b/tests/test_result_document.py index 8172c601..ad949bf0 100644 --- a/tests/test_result_document.py +++ b/tests/test_result_document.py @@ -6,6 +6,11 @@ # 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. +from typing import Dict, Tuple +import textwrap +import fixtures +from fixtures import * + import capa import capa.engine as ceng import capa.render.result_document as rdoc @@ -227,3 +232,10 @@ def test_basic_block_node_from_capa(): node = rdoc.node_from_capa(capa.features.basicblock.BasicBlock("")) assert isinstance(node, rdoc.FeatureNode) assert isinstance(node.feature, frzf.BasicBlockFeature) + +def test_json_to_rdoc (capsys, tmpdir): + path = fixtures.get_data_path_by_name("pma01-01") + assert capa.main.main([path, "-j"]) == 0 + temp_file = tmpdir.join("capa.json") + temp_file.write(capsys.readouterr().out) + assert isinstance(rdoc.ResultDocument.parse_raw(temp_file),rdoc.ResultDocument) \ No newline at end of file From 530e28cbc32b13d0a5a9c6d0955a86dd05439977 Mon Sep 17 00:00:00 2001 From: Pratham Chauhan Date: Wed, 29 Mar 2023 16:00:02 +0530 Subject: [PATCH 21/79] introducing match strings constant for formats --- capa/features/extractors/common.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/capa/features/extractors/common.py b/capa/features/extractors/common.py index e9d77cee..806f895c 100644 --- a/capa/features/extractors/common.py +++ b/capa/features/extractors/common.py @@ -16,6 +16,10 @@ from capa.features.address import NO_ADDRESS, Address, FileOffsetAddress logger = logging.getLogger(__name__) +#match strings for formats +MATCH_PE = b"MZ" +MATCH_ELF = b"\x7fELF" +MATCH_RESULT = b"{\"meta\":" def extract_file_strings(buf, **kwargs) -> Iterator[Tuple[String, Address]]: """ @@ -29,13 +33,13 @@ def extract_file_strings(buf, **kwargs) -> Iterator[Tuple[String, Address]]: def extract_format(buf) -> Iterator[Tuple[Feature, Address]]: - if buf.startswith(b"MZ"): + if buf.startswith(MATCH_PE): yield Format(FORMAT_PE), NO_ADDRESS - elif buf.startswith(b"\x7fELF"): + elif buf.startswith(MATCH_ELF): yield Format(FORMAT_ELF), NO_ADDRESS elif is_freeze(buf): yield Format(FORMAT_FREEZE), NO_ADDRESS - elif buf.startswith(b"{\"meta\":"): + elif buf.startswith(MATCH_RESULT): yield Format(FORMAT_RESULT), NO_ADDRESS else: # we likely end up here: @@ -47,14 +51,14 @@ def extract_format(buf) -> Iterator[Tuple[Feature, Address]]: def extract_arch(buf) -> Iterator[Tuple[Feature, Address]]: - if buf.startswith(b"MZ"): + if buf.startswith(MATCH_PE): yield from capa.features.extractors.pefile.extract_file_arch(pe=pefile.PE(data=buf)) - elif buf.startswith(b"\x7fELF"): + elif buf.startswith(MATCH_ELF): with contextlib.closing(io.BytesIO(buf)) as f: arch = capa.features.extractors.elf.detect_elf_arch(f) - elif buf.startswith(b"{\"meta\":"): + elif buf.startswith(MATCH_RESULT): arch = ARCH_ANY if arch not in capa.features.common.VALID_ARCH: @@ -79,11 +83,11 @@ def extract_arch(buf) -> Iterator[Tuple[Feature, Address]]: def extract_os(buf) -> Iterator[Tuple[Feature, Address]]: - if buf.startswith(b"MZ"): + if buf.startswith(MATCH_PE): yield OS(OS_WINDOWS), NO_ADDRESS - elif buf.startswith(b"{\"meta\":"): + elif buf.startswith(MATCH_RESULT): yield OS(OS_ANY), NO_ADDRESS - elif buf.startswith(b"\x7fELF"): + elif buf.startswith(MATCH_ELF): with contextlib.closing(io.BytesIO(buf)) as f: os = capa.features.extractors.elf.detect_elf_os(f) From 9e12c563bc0d17725c2b360bb837a20e121f6bd8 Mon Sep 17 00:00:00 2001 From: Pratham Chauhan Date: Wed, 29 Mar 2023 16:02:17 +0530 Subject: [PATCH 22/79] remove unused imports --- rules | 2 +- tests/data | 2 +- tests/test_result_document.py | 3 --- tmp0xt29tvs | 1 + 4 files changed, 3 insertions(+), 5 deletions(-) create mode 100644 tmp0xt29tvs diff --git a/rules b/rules index aa2dc113..4ca80233 160000 --- a/rules +++ b/rules @@ -1 +1 @@ -Subproject commit aa2dc1137dca05215f71a48926c56345cc462173 +Subproject commit 4ca802336320e9b2f1f524d5aa95ef102ad3c1e4 diff --git a/tests/data b/tests/data index d19468ce..3cbd7768 160000 --- a/tests/data +++ b/tests/data @@ -1 +1 @@ -Subproject commit d19468ce08c1f887626971f6ff92b9ad28c32360 +Subproject commit 3cbd7768c27fbcc77dc46d8f7bddd16834e352f1 diff --git a/tests/test_result_document.py b/tests/test_result_document.py index ad949bf0..c3c47f71 100644 --- a/tests/test_result_document.py +++ b/tests/test_result_document.py @@ -6,10 +6,7 @@ # 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. -from typing import Dict, Tuple -import textwrap import fixtures -from fixtures import * import capa import capa.engine as ceng diff --git a/tmp0xt29tvs b/tmp0xt29tvs new file mode 100644 index 00000000..62db661f --- /dev/null +++ b/tmp0xt29tvs @@ -0,0 +1 @@ +"{\"meta\": {\"timestamp\": \"2023-03-29T09:12:40.844121\", \"version\": \"5.0.0\", \"argv\": [\"/home/ooprathamm/Comding/capa/tests/data/Practical Malware Analysis Lab 01-01.dll_\", \"-j\"], \"sample\": {\"md5\": \"290934c61de9176ad682ffdd65f0a669\", \"sha1\": \"a4b35de71ca20fe776dc72d12fb2886736f43c22\", \"sha256\": \"f50e42c8dfaab649bde0398867e930b86c2a599e8db83b8260393082268f2dba\", \"path\": \"/home/ooprathamm/Comding/capa/tests/data/Practical Malware Analysis Lab 01-01.dll_\"}, \"analysis\": {\"format\": \"pe\", \"arch\": \"i386\", \"os\": \"windows\", \"extractor\": \"VivisectFeatureExtractor\", \"rules\": [\"/home/ooprathamm/Comding/capa/rules\"], \"base_address\": {\"type\": \"absolute\", \"value\": 268435456}, \"layout\": {\"functions\": [{\"address\": {\"type\": \"absolute\", \"value\": 268439568}, \"matched_basic_blocks\": [{\"address\": {\"type\": \"absolute\", \"value\": 268439598}}, {\"address\": {\"type\": \"absolute\", \"value\": 268439692}}, {\"address\": {\"type\": \"absolute\", \"value\": 268439868}}, {\"address\": {\"type\": \"absolute\", \"value\": 268439892}}, {\"address\": {\"type\": \"absolute\", \"value\": 268439905}}, {\"address\": {\"type\": \"absolute\", \"value\": 268439929}}, {\"address\": {\"type\": \"absolute\", \"value\": 268440000}}, {\"address\": {\"type\": \"absolute\", \"value\": 268440040}}]}, {\"address\": {\"type\": \"absolute\", \"value\": 268440096}, \"matched_basic_blocks\": []}, {\"address\": {\"type\": \"absolute\", \"value\": 268440143}, \"matched_basic_blocks\": []}, {\"address\": {\"type\": \"absolute\", \"value\": 268440314}, \"matched_basic_blocks\": []}, {\"address\": {\"type\": \"absolute\", \"value\": 268440472}, \"matched_basic_blocks\": []}]}, \"feature_counts\": {\"file\": 127, \"functions\": [{\"address\": {\"type\": \"absolute\", \"value\": 268439568}, \"count\": 160}, {\"address\": {\"type\": \"absolute\", \"value\": 268440472}, \"count\": 7}]}, \"library_functions\": [{\"address\": {\"type\": \"absolute\", \"value\": 268440096}, \"name\": \"__alloca_probe\"}, {\"address\": {\"type\": \"absolute\", \"value\": 268440143}, \"name\": \"__CRT_INIT@12\"}, {\"address\": {\"type\": \"absolute\", \"value\": 268440314}, \"name\": \"__DllMainCRTStartup@12\"}]}}, \"rules\": {\"check mutex\": {\"meta\": {\"name\": \"check mutex\", \"namespace\": \"host-interaction/mutex\", \"authors\": [\"moritz.raabe@mandiant.com\", \"anushka.virgaonkar@mandiant.com\"], \"scope\": \"basic block\", \"attack\": [], \"mbc\": [{\"parts\": [\"Process\", \"Check Mutex\"], \"objective\": \"Process\", \"behavior\": \"Check Mutex\", \"method\": \"\", \"id\": \"C0043\"}], \"references\": [], \"examples\": [\"Practical Malware Analysis Lab 01-01.dll_:0x10001010\"], \"description\": \"\", \"lib\": false, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: check mutex\\n namespace: host-interaction/mutex\\n authors:\\n - moritz.raabe@mandiant.com\\n - anushka.virgaonkar@mandiant.com\\n scope: basic block\\n mbc:\\n - Process::Check Mutex [C0043]\\n examples:\\n - Practical Malware Analysis Lab 01-01.dll_:0x10001010\\n features:\\n - and:\\n - or:\\n - api: kernel32.OpenMutex\\n - match: create mutex\\n - api: System.Threading.Mutex::OpenExisting\\n - api: System.Threading.Mutex::TryOpenExisting\\n - optional:\\n - or:\\n - api: kernel32.GetLastError\\n - number: 2 = ERROR_FILE_NOT_FOUND\\n - number: 0xB7 = ERROR_ALREADY_EXISTS\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439598}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.OpenMutex\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439641}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"create mutex\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Threading.Mutex::OpenExisting\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Threading.Mutex::TryOpenExisting\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"optional\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.GetLastError\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 2, \"description\": \"ERROR_FILE_NOT_FOUND\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 183, \"description\": \"ERROR_ALREADY_EXISTS\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"create TCP socket\": {\"meta\": {\"name\": \"create TCP socket\", \"namespace\": \"communication/socket/tcp\", \"authors\": [\"william.ballenthin@mandiant.com\", \"joakim@intezer.com\", \"anushka.virgaonkar@mandiant.com\"], \"scope\": \"basic block\", \"attack\": [], \"mbc\": [{\"parts\": [\"Communication\", \"Socket Communication\", \"Create TCP Socket\"], \"objective\": \"Communication\", \"behavior\": \"Socket Communication\", \"method\": \"Create TCP Socket\", \"id\": \"C0001.011\"}], \"references\": [], \"examples\": [\"Practical Malware Analysis Lab 01-01.dll_:0x10001010\"], \"description\": \"\", \"lib\": false, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: create TCP socket\\n namespace: communication/socket/tcp\\n authors:\\n - william.ballenthin@mandiant.com\\n - joakim@intezer.com\\n - anushka.virgaonkar@mandiant.com\\n scope: basic block\\n mbc:\\n - Communication::Socket Communication::Create TCP Socket [C0001.011]\\n examples:\\n - Practical Malware Analysis Lab 01-01.dll_:0x10001010\\n features:\\n - or:\\n - and:\\n - number: 6 = IPPROTO_TCP\\n - number: 1 = SOCK_STREAM\\n - number: 2 = AF_INET\\n - or:\\n - api: ws2_32.socket\\n - api: ws2_32.WSASocket\\n - api: socket\\n - property/read: System.Net.Sockets.TcpClient::Client\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439692}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"property\", \"access\": \"read\", \"property\": \"System.Net.Sockets.TcpClient::Client\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 6, \"description\": \"IPPROTO_TCP\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439692}], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 1, \"description\": \"SOCK_STREAM\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439694}], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 2, \"description\": \"AF_INET\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439696}], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.socket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439698}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASocket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"socket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439698}], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"delay execution\": {\"meta\": {\"name\": \"delay execution\", \"authors\": [\"michael.hunhoff@mandiant.com\", \"@ramen0x3f\"], \"scope\": \"basic block\", \"attack\": [], \"mbc\": [{\"parts\": [\"Anti-Behavioral Analysis\", \"Dynamic Analysis Evasion\", \"Delayed Execution\"], \"objective\": \"Anti-Behavioral Analysis\", \"behavior\": \"Dynamic Analysis Evasion\", \"method\": \"Delayed Execution\", \"id\": \"B0003.003\"}], \"references\": [\"https://docs.microsoft.com/en-us/windows/win32/sync/wait-functions\", \"https://github.com/LordNoteworthy/al-khaser/blob/master/al-khaser/TimingAttacks/timing.cpp\"], \"examples\": [\"al-khaser_x86.exe_:0x449770\", \"B5F85C26D7AA5A1FB4AF5821B6B5AB9B:0x402FA6\"], \"description\": \"\", \"lib\": true, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: delay execution\\n authors:\\n - michael.hunhoff@mandiant.com\\n - \\\"@ramen0x3f\\\"\\n lib: true\\n scope: basic block\\n mbc:\\n - Anti-Behavioral Analysis::Dynamic Analysis Evasion::Delayed Execution [B0003.003]\\n references:\\n - https://docs.microsoft.com/en-us/windows/win32/sync/wait-functions\\n - https://github.com/LordNoteworthy/al-khaser/blob/master/al-khaser/TimingAttacks/timing.cpp\\n examples:\\n - al-khaser_x86.exe_:0x449770\\n - B5F85C26D7AA5A1FB4AF5821B6B5AB9B:0x402FA6\\n features:\\n - or:\\n - and:\\n - os: windows\\n - or:\\n - api: kernel32.Sleep\\n - api: kernel32.SleepEx\\n - api: kernel32.WaitForSingleObject\\n - api: kernel32.SignalObjectAndWait\\n - api: kernel32.WaitForSingleObjectEx\\n - api: kernel32.WaitForMultipleObjects\\n - api: kernel32.WaitForMultipleObjectsEx\\n - api: kernel32.RegisterWaitForSingleObject\\n - api: WaitOnAddress\\n - api: user32.MsgWaitForMultipleObjects\\n - api: user32.MsgWaitForMultipleObjectsEx\\n - api: NtDelayExecution\\n - api: KeWaitForSingleObject\\n - api: KeDelayExecutionThread\\n - and:\\n - os: linux\\n - or:\\n - api: sleep\\n - api: usleep\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439892}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"os\", \"os\": \"linux\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"sleep\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"usleep\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"os\", \"os\": \"windows\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"no address\"}], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.Sleep\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439897}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.SleepEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.WaitForSingleObject\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.SignalObjectAndWait\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.WaitForSingleObjectEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.WaitForMultipleObjects\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.WaitForMultipleObjectsEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.RegisterWaitForSingleObject\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"WaitOnAddress\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"user32.MsgWaitForMultipleObjects\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"user32.MsgWaitForMultipleObjectsEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"NtDelayExecution\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"KeWaitForSingleObject\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"KeDelayExecutionThread\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], [{\"type\": \"absolute\", \"value\": 268440000}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"os\", \"os\": \"linux\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"sleep\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"usleep\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"os\", \"os\": \"windows\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"no address\"}], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.Sleep\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268440005}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.SleepEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.WaitForSingleObject\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.SignalObjectAndWait\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.WaitForSingleObjectEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.WaitForMultipleObjects\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.WaitForMultipleObjectsEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.RegisterWaitForSingleObject\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"WaitOnAddress\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"user32.MsgWaitForMultipleObjects\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"user32.MsgWaitForMultipleObjectsEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"NtDelayExecution\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"KeWaitForSingleObject\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"KeDelayExecutionThread\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"create process on Windows\": {\"meta\": {\"name\": \"create process on Windows\", \"namespace\": \"host-interaction/process/create\", \"authors\": [\"moritz.raabe@mandiant.com\"], \"scope\": \"basic block\", \"attack\": [], \"mbc\": [{\"parts\": [\"Process\", \"Create Process\"], \"objective\": \"Process\", \"behavior\": \"Create Process\", \"method\": \"\", \"id\": \"C0017\"}], \"references\": [], \"examples\": [\"9324D1A8AE37A36AE560C37448C9705A:0x406DB0\", \"Practical Malware Analysis Lab 01-04.exe_:0x4011FC\", \"692f7fd6d198e804d6af98eb9e390d61:0x6000003\"], \"description\": \"\", \"lib\": false, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: create process on Windows\\n namespace: host-interaction/process/create\\n authors:\\n - moritz.raabe@mandiant.com\\n scope: basic block\\n mbc:\\n - Process::Create Process [C0017]\\n examples:\\n - 9324D1A8AE37A36AE560C37448C9705A:0x406DB0\\n - Practical Malware Analysis Lab 01-04.exe_:0x4011FC\\n - 692f7fd6d198e804d6af98eb9e390d61:0x6000003\\n features:\\n - or:\\n - api: kernel32.WinExec\\n - api: kernel32.CreateProcess\\n - api: shell32.ShellExecute\\n - api: shell32.ShellExecuteEx\\n - api: advapi32.CreateProcessAsUser\\n - api: advapi32.CreateProcessWithLogon\\n - api: advapi32.CreateProcessWithToken\\n - api: kernel32.CreateProcessInternal\\n - api: ntdll.NtCreateUserProcess\\n - api: ntdll.NtCreateProcess\\n - api: ntdll.NtCreateProcessEx\\n - api: ntdll.ZwCreateProcess\\n - api: ZwCreateProcessEx\\n - api: ntdll.ZwCreateUserProcess\\n - api: ntdll.RtlCreateUserProcess\\n - api: System.Diagnostics.Process::Start\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439929}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.WinExec\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.CreateProcess\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439983}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"shell32.ShellExecute\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"shell32.ShellExecuteEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"advapi32.CreateProcessAsUser\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"advapi32.CreateProcessWithLogon\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"advapi32.CreateProcessWithToken\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.CreateProcessInternal\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ntdll.NtCreateUserProcess\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ntdll.NtCreateProcess\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ntdll.NtCreateProcessEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ntdll.ZwCreateProcess\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ZwCreateProcessEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ntdll.ZwCreateUserProcess\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ntdll.RtlCreateUserProcess\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Diagnostics.Process::Start\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"create mutex\": {\"meta\": {\"name\": \"create mutex\", \"namespace\": \"host-interaction/mutex\", \"authors\": [\"moritz.raabe@mandiant.com\", \"michael.hunhoff@mandiant.com\"], \"scope\": \"function\", \"attack\": [], \"mbc\": [{\"parts\": [\"Process\", \"Create Mutex\"], \"objective\": \"Process\", \"behavior\": \"Create Mutex\", \"method\": \"\", \"id\": \"C0042\"}], \"references\": [], \"examples\": [\"Practical Malware Analysis Lab 01-01.dll_:0x10001010\"], \"description\": \"\", \"lib\": false, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: create mutex\\n namespace: host-interaction/mutex\\n authors:\\n - moritz.raabe@mandiant.com\\n - michael.hunhoff@mandiant.com\\n scope: function\\n mbc:\\n - Process::Create Mutex [C0042]\\n examples:\\n - Practical Malware Analysis Lab 01-01.dll_:0x10001010\\n features:\\n - or:\\n - api: kernel32.CreateMutex\\n - api: kernel32.CreateMutexEx\\n - api: System.Threading.Mutex::ctor\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439568}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.CreateMutex\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439662}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.CreateMutexEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Threading.Mutex::ctor\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"contain loop\": {\"meta\": {\"name\": \"contain loop\", \"authors\": [\"moritz.raabe@mandiant.com\"], \"scope\": \"function\", \"attack\": [], \"mbc\": [], \"references\": [], \"examples\": [\"08AC667C65D36D6542917655571E61C8:0x406EAA\"], \"description\": \"\", \"lib\": true, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: contain loop\\n authors:\\n - moritz.raabe@mandiant.com\\n lib: true\\n scope: function\\n examples:\\n - 08AC667C65D36D6542917655571E61C8:0x406EAA\\n features:\\n - or:\\n - characteristic: loop\\n - characteristic: tight loop\\n - characteristic: recursive call\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439568}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"characteristic\", \"characteristic\": \"loop\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439568}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"characteristic\", \"characteristic\": \"tight loop\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"characteristic\", \"characteristic\": \"recursive call\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"receive data on socket\": {\"meta\": {\"name\": \"receive data on socket\", \"namespace\": \"communication/socket/receive\", \"authors\": [\"moritz.raabe@mandiant.com\", \"joakim@intezer.com\", \"michael.hunhoff@mandiant.com\"], \"scope\": \"function\", \"attack\": [], \"mbc\": [{\"parts\": [\"Communication\", \"Socket Communication\", \"Receive Data\"], \"objective\": \"Communication\", \"behavior\": \"Socket Communication\", \"method\": \"Receive Data\", \"id\": \"C0001.006\"}], \"references\": [], \"examples\": [\"Practical Malware Analysis Lab 01-01.dll_:0x10001010\"], \"description\": \"\", \"lib\": false, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: receive data on socket\\n namespace: communication/socket/receive\\n authors:\\n - moritz.raabe@mandiant.com\\n - joakim@intezer.com\\n - michael.hunhoff@mandiant.com\\n scope: function\\n mbc:\\n - Communication::Socket Communication::Receive Data [C0001.006]\\n examples:\\n - Practical Malware Analysis Lab 01-01.dll_:0x10001010\\n features:\\n - or:\\n - api: ws2_32.recv\\n - api: ws2_32.recvfrom\\n - api: ws2_32.WSARecv\\n - api: ws2_32.WSARecvDisconnect\\n - api: ws2_32.WSARecvEx\\n - api: ws2_32.WSARecvFrom\\n - api: ws2_32.WSARecvMsg\\n - api: recv\\n - api: System.Net.Sockets.Socket::Receive\\n - api: System.Net.Sockets.Socket::ReceiveAsync\\n - api: System.Net.Sockets.Socket::ReceiveFrom\\n - api: System.Net.Sockets.Socket::ReceiveFromAsync\\n - api: System.Net.Sockets.Socket::ReceiveMessageFrom\\n - api: System.Net.Sockets.Socket::ReceiveMessageFromAsync\\n - api: System.Net.Sockets.Socket::BeginReceive\\n - api: System.Net.Sockets.Socket::BeginReceiveFrom\\n - api: System.Net.Sockets.Socket::BeginReceiveMessageFrom\\n - api: System.Net.Sockets.Socket::EndReceive\\n - api: System.Net.Sockets.Socket::EndReceiveFrom\\n - api: System.Net.Sockets.Socket::EndReceiveMessageFrom\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439568}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.recv\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439858}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.recvfrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSARecv\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSARecvDisconnect\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSARecvEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSARecvFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSARecvMsg\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"recv\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439858}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::Receive\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::ReceiveAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::ReceiveFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::ReceiveFromAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::ReceiveMessageFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::ReceiveMessageFromAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::BeginReceive\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::BeginReceiveFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::BeginReceiveMessageFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::EndReceive\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::EndReceiveFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::EndReceiveMessageFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"send data on socket\": {\"meta\": {\"name\": \"send data on socket\", \"namespace\": \"communication/socket/send\", \"authors\": [\"moritz.raabe@mandiant.com\", \"joakim@intezer.com\", \"anushka.virgaonkar@mandiant.com\"], \"scope\": \"function\", \"attack\": [], \"mbc\": [{\"parts\": [\"Communication\", \"Socket Communication\", \"Send Data\"], \"objective\": \"Communication\", \"behavior\": \"Socket Communication\", \"method\": \"Send Data\", \"id\": \"C0001.007\"}], \"references\": [], \"examples\": [\"Practical Malware Analysis Lab 01-01.dll_:0x10001010\"], \"description\": \"\", \"lib\": false, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: send data on socket\\n namespace: communication/socket/send\\n authors:\\n - moritz.raabe@mandiant.com\\n - joakim@intezer.com\\n - anushka.virgaonkar@mandiant.com\\n scope: function\\n mbc:\\n - Communication::Socket Communication::Send Data [C0001.007]\\n examples:\\n - Practical Malware Analysis Lab 01-01.dll_:0x10001010\\n features:\\n - or:\\n - api: ws2_32.send\\n - api: ws2_32.sendto\\n - api: ws2_32.WSASend\\n - api: ws2_32.WSASendMsg\\n - api: ws2_32.WSASendTo\\n - api: send\\n - api: System.Net.Sockets.Socket::Send\\n - api: System.Net.Sockets.Socket::SendAsync\\n - api: System.Net.Sockets.Socket::SendTo\\n - api: System.Net.Sockets.Socket::SendToAsync\\n - api: System.Net.Sockets.UdpClient::Send\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439568}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439809}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.sendto\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASend\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASendMsg\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASendTo\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439809}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::Send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::SendAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::SendTo\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::SendToAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.UdpClient::Send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"initialize Winsock library\": {\"meta\": {\"name\": \"initialize Winsock library\", \"namespace\": \"communication/socket\", \"authors\": [\"michael.hunhoff@mandiant.com\"], \"scope\": \"function\", \"attack\": [], \"mbc\": [{\"parts\": [\"Communication\", \"Socket Communication\", \"Initialize Winsock Library\"], \"objective\": \"Communication\", \"behavior\": \"Socket Communication\", \"method\": \"Initialize Winsock Library\", \"id\": \"C0001.009\"}], \"references\": [], \"examples\": [\"6A352C3E55E8AE5ED39DC1BE7FB964B1:0x10001D30\"], \"description\": \"\", \"lib\": false, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: initialize Winsock library\\n namespace: communication/socket\\n authors:\\n - michael.hunhoff@mandiant.com\\n scope: function\\n mbc:\\n - Communication::Socket Communication::Initialize Winsock Library [C0001.009]\\n examples:\\n - 6A352C3E55E8AE5ED39DC1BE7FB964B1:0x10001D30\\n features:\\n - and:\\n - api: ws2_32.WSAStartup\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439568}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSAStartup\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439678}], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"receive data\": {\"meta\": {\"name\": \"receive data\", \"namespace\": \"communication\", \"authors\": [\"william.ballenthin@mandiant.com\"], \"scope\": \"function\", \"attack\": [], \"mbc\": [{\"parts\": [\"Command and Control\", \"C2 Communication\", \"Receive Data\"], \"objective\": \"Command and Control\", \"behavior\": \"C2 Communication\", \"method\": \"Receive Data\", \"id\": \"B0030.002\"}], \"references\": [], \"examples\": [\"BFB9B5391A13D0AFD787E87AB90F14F5:0x13145D60\"], \"description\": \"all known techniques for receiving data from a potential C2 server\", \"lib\": false, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: receive data\\n namespace: communication\\n authors:\\n - william.ballenthin@mandiant.com\\n description: all known techniques for receiving data from a potential C2 server\\n scope: function\\n mbc:\\n - Command and Control::C2 Communication::Receive Data [B0030.002]\\n examples:\\n - BFB9B5391A13D0AFD787E87AB90F14F5:0x13145D60\\n features:\\n - or:\\n - match: receive data on socket\\n - match: read data from Internet\\n - match: download URL\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439568}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"receive data on socket\"}, \"type\": \"feature\"}, \"children\": [{\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.recv\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439858}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.recvfrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSARecv\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSARecvDisconnect\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSARecvEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSARecvFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSARecvMsg\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"recv\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439858}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::Receive\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::ReceiveAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::ReceiveFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::ReceiveFromAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::ReceiveMessageFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::ReceiveMessageFromAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::BeginReceive\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::BeginReceiveFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::BeginReceiveMessageFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::EndReceive\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::EndReceiveFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::EndReceiveMessageFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [{\"type\": \"absolute\", \"value\": 268439568}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"read data from Internet\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"download URL\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"send data\": {\"meta\": {\"name\": \"send data\", \"namespace\": \"communication\", \"authors\": [\"william.ballenthin@mandiant.com\", \"joakim@intezer.com\"], \"scope\": \"function\", \"attack\": [], \"mbc\": [{\"parts\": [\"Command and Control\", \"C2 Communication\", \"Send Data\"], \"objective\": \"Command and Control\", \"behavior\": \"C2 Communication\", \"method\": \"Send Data\", \"id\": \"B0030.001\"}], \"references\": [], \"examples\": [\"BFB9B5391A13D0AFD787E87AB90F14F5:0x13145D60\"], \"description\": \"all known techniques for sending data to a potential C2 server\", \"lib\": false, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: send data\\n namespace: communication\\n authors:\\n - william.ballenthin@mandiant.com\\n - joakim@intezer.com\\n description: all known techniques for sending data to a potential C2 server\\n scope: function\\n mbc:\\n - Command and Control::C2 Communication::Send Data [B0030.001]\\n examples:\\n - BFB9B5391A13D0AFD787E87AB90F14F5:0x13145D60\\n features:\\n - or:\\n - and:\\n - os: windows\\n - or:\\n - match: send HTTP request\\n - match: send data on socket\\n - match: send file via HTTP\\n - and:\\n - os: linux\\n - or: # Require network bound socket.\\n - match: create TCP socket\\n - match: create UDP socket\\n - or:\\n - match: send HTTP request\\n - match: send data on socket\\n - match: send file via HTTP\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439568}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"os\", \"os\": \"windows\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"no address\"}], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"send HTTP request\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"send data on socket\"}, \"type\": \"feature\"}, \"children\": [{\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439809}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.sendto\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASend\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASendMsg\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASendTo\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439809}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::Send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::SendAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::SendTo\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::SendToAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.UdpClient::Send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [{\"type\": \"absolute\", \"value\": 268439568}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"send file via HTTP\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"os\", \"os\": \"linux\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"create TCP socket\"}, \"type\": \"feature\"}, \"children\": [{\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"property\", \"access\": \"read\", \"property\": \"System.Net.Sockets.TcpClient::Client\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 6, \"description\": \"IPPROTO_TCP\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439692}], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 1, \"description\": \"SOCK_STREAM\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439694}], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 2, \"description\": \"AF_INET\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439696}], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.socket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439698}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASocket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"socket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439698}], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [{\"type\": \"absolute\", \"value\": 268439692}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"create UDP socket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"send HTTP request\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"send data on socket\"}, \"type\": \"feature\"}, \"children\": [{\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439809}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.sendto\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASend\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASendMsg\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASendTo\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439809}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::Send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::SendAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::SendTo\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::SendToAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.UdpClient::Send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [{\"type\": \"absolute\", \"value\": 268439568}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"send file via HTTP\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"connect TCP socket\": {\"meta\": {\"name\": \"connect TCP socket\", \"namespace\": \"communication/socket/tcp\", \"authors\": [\"moritz.raabe@mandiant.com\", \"joakim@intezer.com\"], \"scope\": \"function\", \"attack\": [], \"mbc\": [{\"parts\": [\"Communication\", \"Socket Communication\", \"Connect Socket\"], \"objective\": \"Communication\", \"behavior\": \"Socket Communication\", \"method\": \"Connect Socket\", \"id\": \"C0001.004\"}], \"references\": [], \"examples\": [\"Practical Malware Analysis Lab 01-01.dll_:0x10001010\"], \"description\": \"\", \"lib\": false, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: connect TCP socket\\n namespace: communication/socket/tcp\\n authors:\\n - moritz.raabe@mandiant.com\\n - joakim@intezer.com\\n scope: function\\n mbc:\\n - Communication::Socket Communication::Connect Socket [C0001.004]\\n examples:\\n - Practical Malware Analysis Lab 01-01.dll_:0x10001010\\n features:\\n - and:\\n - match: create TCP socket\\n - or:\\n - api: connect\\n - api: ws2_32.connect\\n - api: ws2_32.WSAConnect\\n - api: ConnectEx\\n - and:\\n - basic block:\\n # candidate for GUID: WSAID_CONNECTEX/25a207b9-ddf3-4660-8ee9-76e58c74063e\\n - and:\\n - number: 0x25A207B9\\n - number: 0x4660DDF3\\n - number: 0xE576E98E\\n - number: 0x3E06748C\\n - basic block:\\n - and:\\n - api: WSAIoctl\\n - number: 0xC8000006 = SIO_GET_EXTENSION_FUNCTION_POINTER\\n - basic block:\\n - and:\\n - api: setsockopt\\n - number: 0xFFFF = SOL_SOCKET\\n - number: 0x7010 = SO_UPDATE_CONNECT_CONTEXT\\n # socket must be bound to ConnectEx\\n # https://gist.github.com/joeyadams/4158972\\n - api: bind\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439568}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"create TCP socket\"}, \"type\": \"feature\"}, \"children\": [{\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"property\", \"access\": \"read\", \"property\": \"System.Net.Sockets.TcpClient::Client\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 6, \"description\": \"IPPROTO_TCP\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439692}], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 1, \"description\": \"SOCK_STREAM\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439694}], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 2, \"description\": \"AF_INET\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439696}], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.socket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439698}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASocket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"socket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439698}], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [{\"type\": \"absolute\", \"value\": 268439692}], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"connect\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439758}], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.connect\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439758}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSAConnect\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ConnectEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"connect TCP socket/ae22acdd40144f4eabc347889338d681\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"connect TCP socket/c7c2534615d84c1b9beafde678afeb40\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"connect TCP socket/44a4a4d414174889997c583987ef02df\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"bind\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"act as TCP client\": {\"meta\": {\"name\": \"act as TCP client\", \"namespace\": \"communication/tcp/client\", \"authors\": [\"william.ballenthin@mandiant.com\", \"michael.hunhoff@mandiant.com\"], \"scope\": \"function\", \"attack\": [], \"mbc\": [{\"parts\": [\"Communication\", \"Socket Communication\", \"TCP Client\"], \"objective\": \"Communication\", \"behavior\": \"Socket Communication\", \"method\": \"TCP Client\", \"id\": \"C0001.008\"}], \"references\": [], \"examples\": [\"Practical Malware Analysis Lab 01-01.dll_:0x10001010\"], \"description\": \"\", \"lib\": false, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: act as TCP client\\n namespace: communication/tcp/client\\n authors:\\n - william.ballenthin@mandiant.com\\n - michael.hunhoff@mandiant.com\\n scope: function\\n mbc:\\n - Communication::Socket Communication::TCP Client [C0001.008]\\n examples:\\n - Practical Malware Analysis Lab 01-01.dll_:0x10001010\\n features:\\n - or:\\n - match: connect TCP socket\\n - api: System.Net.Sockets.TcpClient::ctor\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439568}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"connect TCP socket\"}, \"type\": \"feature\"}, \"children\": [{\"success\": true, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"create TCP socket\"}, \"type\": \"feature\"}, \"children\": [{\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"property\", \"access\": \"read\", \"property\": \"System.Net.Sockets.TcpClient::Client\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 6, \"description\": \"IPPROTO_TCP\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439692}], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 1, \"description\": \"SOCK_STREAM\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439694}], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 2, \"description\": \"AF_INET\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439696}], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.socket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439698}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASocket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"socket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439698}], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [{\"type\": \"absolute\", \"value\": 268439692}], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"connect\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439758}], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.connect\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439758}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSAConnect\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ConnectEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"connect TCP socket/ae22acdd40144f4eabc347889338d681\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"connect TCP socket/c7c2534615d84c1b9beafde678afeb40\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"connect TCP socket/44a4a4d414174889997c583987ef02df\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"bind\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [{\"type\": \"absolute\", \"value\": 268439568}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.TcpClient::ctor\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}}}\n" \ No newline at end of file From b49fb7fcf94b9ae2259b657bd47c0ee250ee4373 Mon Sep 17 00:00:00 2001 From: Pratham Chauhan Date: Wed, 29 Mar 2023 16:06:20 +0530 Subject: [PATCH 23/79] Revert "introducing match strings constant for formats" This reverts commit 530e28cbc32b13d0a5a9c6d0955a86dd05439977. --- capa/features/extractors/common.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/capa/features/extractors/common.py b/capa/features/extractors/common.py index 806f895c..e9d77cee 100644 --- a/capa/features/extractors/common.py +++ b/capa/features/extractors/common.py @@ -16,10 +16,6 @@ from capa.features.address import NO_ADDRESS, Address, FileOffsetAddress logger = logging.getLogger(__name__) -#match strings for formats -MATCH_PE = b"MZ" -MATCH_ELF = b"\x7fELF" -MATCH_RESULT = b"{\"meta\":" def extract_file_strings(buf, **kwargs) -> Iterator[Tuple[String, Address]]: """ @@ -33,13 +29,13 @@ def extract_file_strings(buf, **kwargs) -> Iterator[Tuple[String, Address]]: def extract_format(buf) -> Iterator[Tuple[Feature, Address]]: - if buf.startswith(MATCH_PE): + if buf.startswith(b"MZ"): yield Format(FORMAT_PE), NO_ADDRESS - elif buf.startswith(MATCH_ELF): + elif buf.startswith(b"\x7fELF"): yield Format(FORMAT_ELF), NO_ADDRESS elif is_freeze(buf): yield Format(FORMAT_FREEZE), NO_ADDRESS - elif buf.startswith(MATCH_RESULT): + elif buf.startswith(b"{\"meta\":"): yield Format(FORMAT_RESULT), NO_ADDRESS else: # we likely end up here: @@ -51,14 +47,14 @@ def extract_format(buf) -> Iterator[Tuple[Feature, Address]]: def extract_arch(buf) -> Iterator[Tuple[Feature, Address]]: - if buf.startswith(MATCH_PE): + if buf.startswith(b"MZ"): yield from capa.features.extractors.pefile.extract_file_arch(pe=pefile.PE(data=buf)) - elif buf.startswith(MATCH_ELF): + elif buf.startswith(b"\x7fELF"): with contextlib.closing(io.BytesIO(buf)) as f: arch = capa.features.extractors.elf.detect_elf_arch(f) - elif buf.startswith(MATCH_RESULT): + elif buf.startswith(b"{\"meta\":"): arch = ARCH_ANY if arch not in capa.features.common.VALID_ARCH: @@ -83,11 +79,11 @@ def extract_arch(buf) -> Iterator[Tuple[Feature, Address]]: def extract_os(buf) -> Iterator[Tuple[Feature, Address]]: - if buf.startswith(MATCH_PE): + if buf.startswith(b"MZ"): yield OS(OS_WINDOWS), NO_ADDRESS - elif buf.startswith(MATCH_RESULT): + elif buf.startswith(b"{\"meta\":"): yield OS(OS_ANY), NO_ADDRESS - elif buf.startswith(MATCH_ELF): + elif buf.startswith(b"\x7fELF"): with contextlib.closing(io.BytesIO(buf)) as f: os = capa.features.extractors.elf.detect_elf_os(f) From 5a1009520df91b278a8ff63dab150430c12377d7 Mon Sep 17 00:00:00 2001 From: Pratham Chauhan Date: Wed, 29 Mar 2023 16:10:44 +0530 Subject: [PATCH 24/79] Revert "Revert "introducing match strings constant for formats"" This reverts commit b49fb7fcf94b9ae2259b657bd47c0ee250ee4373. --- capa/features/extractors/common.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/capa/features/extractors/common.py b/capa/features/extractors/common.py index e9d77cee..806f895c 100644 --- a/capa/features/extractors/common.py +++ b/capa/features/extractors/common.py @@ -16,6 +16,10 @@ from capa.features.address import NO_ADDRESS, Address, FileOffsetAddress logger = logging.getLogger(__name__) +#match strings for formats +MATCH_PE = b"MZ" +MATCH_ELF = b"\x7fELF" +MATCH_RESULT = b"{\"meta\":" def extract_file_strings(buf, **kwargs) -> Iterator[Tuple[String, Address]]: """ @@ -29,13 +33,13 @@ def extract_file_strings(buf, **kwargs) -> Iterator[Tuple[String, Address]]: def extract_format(buf) -> Iterator[Tuple[Feature, Address]]: - if buf.startswith(b"MZ"): + if buf.startswith(MATCH_PE): yield Format(FORMAT_PE), NO_ADDRESS - elif buf.startswith(b"\x7fELF"): + elif buf.startswith(MATCH_ELF): yield Format(FORMAT_ELF), NO_ADDRESS elif is_freeze(buf): yield Format(FORMAT_FREEZE), NO_ADDRESS - elif buf.startswith(b"{\"meta\":"): + elif buf.startswith(MATCH_RESULT): yield Format(FORMAT_RESULT), NO_ADDRESS else: # we likely end up here: @@ -47,14 +51,14 @@ def extract_format(buf) -> Iterator[Tuple[Feature, Address]]: def extract_arch(buf) -> Iterator[Tuple[Feature, Address]]: - if buf.startswith(b"MZ"): + if buf.startswith(MATCH_PE): yield from capa.features.extractors.pefile.extract_file_arch(pe=pefile.PE(data=buf)) - elif buf.startswith(b"\x7fELF"): + elif buf.startswith(MATCH_ELF): with contextlib.closing(io.BytesIO(buf)) as f: arch = capa.features.extractors.elf.detect_elf_arch(f) - elif buf.startswith(b"{\"meta\":"): + elif buf.startswith(MATCH_RESULT): arch = ARCH_ANY if arch not in capa.features.common.VALID_ARCH: @@ -79,11 +83,11 @@ def extract_arch(buf) -> Iterator[Tuple[Feature, Address]]: def extract_os(buf) -> Iterator[Tuple[Feature, Address]]: - if buf.startswith(b"MZ"): + if buf.startswith(MATCH_PE): yield OS(OS_WINDOWS), NO_ADDRESS - elif buf.startswith(b"{\"meta\":"): + elif buf.startswith(MATCH_RESULT): yield OS(OS_ANY), NO_ADDRESS - elif buf.startswith(b"\x7fELF"): + elif buf.startswith(MATCH_ELF): with contextlib.closing(io.BytesIO(buf)) as f: os = capa.features.extractors.elf.detect_elf_os(f) From abbf3db2ac13bdb8c7800a7f726a4f7ced5dc4df Mon Sep 17 00:00:00 2001 From: Pratham Chauhan Date: Wed, 29 Mar 2023 16:11:21 +0530 Subject: [PATCH 25/79] Revert "remove unused imports" This reverts commit 9e12c563bc0d17725c2b360bb837a20e121f6bd8. --- rules | 2 +- tests/data | 2 +- tests/test_result_document.py | 3 +++ tmp0xt29tvs | 1 - 4 files changed, 5 insertions(+), 3 deletions(-) delete mode 100644 tmp0xt29tvs diff --git a/rules b/rules index 4ca80233..aa2dc113 160000 --- a/rules +++ b/rules @@ -1 +1 @@ -Subproject commit 4ca802336320e9b2f1f524d5aa95ef102ad3c1e4 +Subproject commit aa2dc1137dca05215f71a48926c56345cc462173 diff --git a/tests/data b/tests/data index 3cbd7768..d19468ce 160000 --- a/tests/data +++ b/tests/data @@ -1 +1 @@ -Subproject commit 3cbd7768c27fbcc77dc46d8f7bddd16834e352f1 +Subproject commit d19468ce08c1f887626971f6ff92b9ad28c32360 diff --git a/tests/test_result_document.py b/tests/test_result_document.py index c3c47f71..ad949bf0 100644 --- a/tests/test_result_document.py +++ b/tests/test_result_document.py @@ -6,7 +6,10 @@ # 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. +from typing import Dict, Tuple +import textwrap import fixtures +from fixtures import * import capa import capa.engine as ceng diff --git a/tmp0xt29tvs b/tmp0xt29tvs deleted file mode 100644 index 62db661f..00000000 --- a/tmp0xt29tvs +++ /dev/null @@ -1 +0,0 @@ -"{\"meta\": {\"timestamp\": \"2023-03-29T09:12:40.844121\", \"version\": \"5.0.0\", \"argv\": [\"/home/ooprathamm/Comding/capa/tests/data/Practical Malware Analysis Lab 01-01.dll_\", \"-j\"], \"sample\": {\"md5\": \"290934c61de9176ad682ffdd65f0a669\", \"sha1\": \"a4b35de71ca20fe776dc72d12fb2886736f43c22\", \"sha256\": \"f50e42c8dfaab649bde0398867e930b86c2a599e8db83b8260393082268f2dba\", \"path\": \"/home/ooprathamm/Comding/capa/tests/data/Practical Malware Analysis Lab 01-01.dll_\"}, \"analysis\": {\"format\": \"pe\", \"arch\": \"i386\", \"os\": \"windows\", \"extractor\": \"VivisectFeatureExtractor\", \"rules\": [\"/home/ooprathamm/Comding/capa/rules\"], \"base_address\": {\"type\": \"absolute\", \"value\": 268435456}, \"layout\": {\"functions\": [{\"address\": {\"type\": \"absolute\", \"value\": 268439568}, \"matched_basic_blocks\": [{\"address\": {\"type\": \"absolute\", \"value\": 268439598}}, {\"address\": {\"type\": \"absolute\", \"value\": 268439692}}, {\"address\": {\"type\": \"absolute\", \"value\": 268439868}}, {\"address\": {\"type\": \"absolute\", \"value\": 268439892}}, {\"address\": {\"type\": \"absolute\", \"value\": 268439905}}, {\"address\": {\"type\": \"absolute\", \"value\": 268439929}}, {\"address\": {\"type\": \"absolute\", \"value\": 268440000}}, {\"address\": {\"type\": \"absolute\", \"value\": 268440040}}]}, {\"address\": {\"type\": \"absolute\", \"value\": 268440096}, \"matched_basic_blocks\": []}, {\"address\": {\"type\": \"absolute\", \"value\": 268440143}, \"matched_basic_blocks\": []}, {\"address\": {\"type\": \"absolute\", \"value\": 268440314}, \"matched_basic_blocks\": []}, {\"address\": {\"type\": \"absolute\", \"value\": 268440472}, \"matched_basic_blocks\": []}]}, \"feature_counts\": {\"file\": 127, \"functions\": [{\"address\": {\"type\": \"absolute\", \"value\": 268439568}, \"count\": 160}, {\"address\": {\"type\": \"absolute\", \"value\": 268440472}, \"count\": 7}]}, \"library_functions\": [{\"address\": {\"type\": \"absolute\", \"value\": 268440096}, \"name\": \"__alloca_probe\"}, {\"address\": {\"type\": \"absolute\", \"value\": 268440143}, \"name\": \"__CRT_INIT@12\"}, {\"address\": {\"type\": \"absolute\", \"value\": 268440314}, \"name\": \"__DllMainCRTStartup@12\"}]}}, \"rules\": {\"check mutex\": {\"meta\": {\"name\": \"check mutex\", \"namespace\": \"host-interaction/mutex\", \"authors\": [\"moritz.raabe@mandiant.com\", \"anushka.virgaonkar@mandiant.com\"], \"scope\": \"basic block\", \"attack\": [], \"mbc\": [{\"parts\": [\"Process\", \"Check Mutex\"], \"objective\": \"Process\", \"behavior\": \"Check Mutex\", \"method\": \"\", \"id\": \"C0043\"}], \"references\": [], \"examples\": [\"Practical Malware Analysis Lab 01-01.dll_:0x10001010\"], \"description\": \"\", \"lib\": false, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: check mutex\\n namespace: host-interaction/mutex\\n authors:\\n - moritz.raabe@mandiant.com\\n - anushka.virgaonkar@mandiant.com\\n scope: basic block\\n mbc:\\n - Process::Check Mutex [C0043]\\n examples:\\n - Practical Malware Analysis Lab 01-01.dll_:0x10001010\\n features:\\n - and:\\n - or:\\n - api: kernel32.OpenMutex\\n - match: create mutex\\n - api: System.Threading.Mutex::OpenExisting\\n - api: System.Threading.Mutex::TryOpenExisting\\n - optional:\\n - or:\\n - api: kernel32.GetLastError\\n - number: 2 = ERROR_FILE_NOT_FOUND\\n - number: 0xB7 = ERROR_ALREADY_EXISTS\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439598}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.OpenMutex\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439641}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"create mutex\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Threading.Mutex::OpenExisting\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Threading.Mutex::TryOpenExisting\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"optional\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.GetLastError\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 2, \"description\": \"ERROR_FILE_NOT_FOUND\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 183, \"description\": \"ERROR_ALREADY_EXISTS\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"create TCP socket\": {\"meta\": {\"name\": \"create TCP socket\", \"namespace\": \"communication/socket/tcp\", \"authors\": [\"william.ballenthin@mandiant.com\", \"joakim@intezer.com\", \"anushka.virgaonkar@mandiant.com\"], \"scope\": \"basic block\", \"attack\": [], \"mbc\": [{\"parts\": [\"Communication\", \"Socket Communication\", \"Create TCP Socket\"], \"objective\": \"Communication\", \"behavior\": \"Socket Communication\", \"method\": \"Create TCP Socket\", \"id\": \"C0001.011\"}], \"references\": [], \"examples\": [\"Practical Malware Analysis Lab 01-01.dll_:0x10001010\"], \"description\": \"\", \"lib\": false, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: create TCP socket\\n namespace: communication/socket/tcp\\n authors:\\n - william.ballenthin@mandiant.com\\n - joakim@intezer.com\\n - anushka.virgaonkar@mandiant.com\\n scope: basic block\\n mbc:\\n - Communication::Socket Communication::Create TCP Socket [C0001.011]\\n examples:\\n - Practical Malware Analysis Lab 01-01.dll_:0x10001010\\n features:\\n - or:\\n - and:\\n - number: 6 = IPPROTO_TCP\\n - number: 1 = SOCK_STREAM\\n - number: 2 = AF_INET\\n - or:\\n - api: ws2_32.socket\\n - api: ws2_32.WSASocket\\n - api: socket\\n - property/read: System.Net.Sockets.TcpClient::Client\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439692}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"property\", \"access\": \"read\", \"property\": \"System.Net.Sockets.TcpClient::Client\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 6, \"description\": \"IPPROTO_TCP\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439692}], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 1, \"description\": \"SOCK_STREAM\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439694}], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 2, \"description\": \"AF_INET\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439696}], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.socket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439698}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASocket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"socket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439698}], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"delay execution\": {\"meta\": {\"name\": \"delay execution\", \"authors\": [\"michael.hunhoff@mandiant.com\", \"@ramen0x3f\"], \"scope\": \"basic block\", \"attack\": [], \"mbc\": [{\"parts\": [\"Anti-Behavioral Analysis\", \"Dynamic Analysis Evasion\", \"Delayed Execution\"], \"objective\": \"Anti-Behavioral Analysis\", \"behavior\": \"Dynamic Analysis Evasion\", \"method\": \"Delayed Execution\", \"id\": \"B0003.003\"}], \"references\": [\"https://docs.microsoft.com/en-us/windows/win32/sync/wait-functions\", \"https://github.com/LordNoteworthy/al-khaser/blob/master/al-khaser/TimingAttacks/timing.cpp\"], \"examples\": [\"al-khaser_x86.exe_:0x449770\", \"B5F85C26D7AA5A1FB4AF5821B6B5AB9B:0x402FA6\"], \"description\": \"\", \"lib\": true, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: delay execution\\n authors:\\n - michael.hunhoff@mandiant.com\\n - \\\"@ramen0x3f\\\"\\n lib: true\\n scope: basic block\\n mbc:\\n - Anti-Behavioral Analysis::Dynamic Analysis Evasion::Delayed Execution [B0003.003]\\n references:\\n - https://docs.microsoft.com/en-us/windows/win32/sync/wait-functions\\n - https://github.com/LordNoteworthy/al-khaser/blob/master/al-khaser/TimingAttacks/timing.cpp\\n examples:\\n - al-khaser_x86.exe_:0x449770\\n - B5F85C26D7AA5A1FB4AF5821B6B5AB9B:0x402FA6\\n features:\\n - or:\\n - and:\\n - os: windows\\n - or:\\n - api: kernel32.Sleep\\n - api: kernel32.SleepEx\\n - api: kernel32.WaitForSingleObject\\n - api: kernel32.SignalObjectAndWait\\n - api: kernel32.WaitForSingleObjectEx\\n - api: kernel32.WaitForMultipleObjects\\n - api: kernel32.WaitForMultipleObjectsEx\\n - api: kernel32.RegisterWaitForSingleObject\\n - api: WaitOnAddress\\n - api: user32.MsgWaitForMultipleObjects\\n - api: user32.MsgWaitForMultipleObjectsEx\\n - api: NtDelayExecution\\n - api: KeWaitForSingleObject\\n - api: KeDelayExecutionThread\\n - and:\\n - os: linux\\n - or:\\n - api: sleep\\n - api: usleep\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439892}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"os\", \"os\": \"linux\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"sleep\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"usleep\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"os\", \"os\": \"windows\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"no address\"}], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.Sleep\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439897}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.SleepEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.WaitForSingleObject\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.SignalObjectAndWait\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.WaitForSingleObjectEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.WaitForMultipleObjects\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.WaitForMultipleObjectsEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.RegisterWaitForSingleObject\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"WaitOnAddress\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"user32.MsgWaitForMultipleObjects\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"user32.MsgWaitForMultipleObjectsEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"NtDelayExecution\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"KeWaitForSingleObject\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"KeDelayExecutionThread\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], [{\"type\": \"absolute\", \"value\": 268440000}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"os\", \"os\": \"linux\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"sleep\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"usleep\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"os\", \"os\": \"windows\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"no address\"}], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.Sleep\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268440005}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.SleepEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.WaitForSingleObject\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.SignalObjectAndWait\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.WaitForSingleObjectEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.WaitForMultipleObjects\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.WaitForMultipleObjectsEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.RegisterWaitForSingleObject\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"WaitOnAddress\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"user32.MsgWaitForMultipleObjects\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"user32.MsgWaitForMultipleObjectsEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"NtDelayExecution\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"KeWaitForSingleObject\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"KeDelayExecutionThread\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"create process on Windows\": {\"meta\": {\"name\": \"create process on Windows\", \"namespace\": \"host-interaction/process/create\", \"authors\": [\"moritz.raabe@mandiant.com\"], \"scope\": \"basic block\", \"attack\": [], \"mbc\": [{\"parts\": [\"Process\", \"Create Process\"], \"objective\": \"Process\", \"behavior\": \"Create Process\", \"method\": \"\", \"id\": \"C0017\"}], \"references\": [], \"examples\": [\"9324D1A8AE37A36AE560C37448C9705A:0x406DB0\", \"Practical Malware Analysis Lab 01-04.exe_:0x4011FC\", \"692f7fd6d198e804d6af98eb9e390d61:0x6000003\"], \"description\": \"\", \"lib\": false, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: create process on Windows\\n namespace: host-interaction/process/create\\n authors:\\n - moritz.raabe@mandiant.com\\n scope: basic block\\n mbc:\\n - Process::Create Process [C0017]\\n examples:\\n - 9324D1A8AE37A36AE560C37448C9705A:0x406DB0\\n - Practical Malware Analysis Lab 01-04.exe_:0x4011FC\\n - 692f7fd6d198e804d6af98eb9e390d61:0x6000003\\n features:\\n - or:\\n - api: kernel32.WinExec\\n - api: kernel32.CreateProcess\\n - api: shell32.ShellExecute\\n - api: shell32.ShellExecuteEx\\n - api: advapi32.CreateProcessAsUser\\n - api: advapi32.CreateProcessWithLogon\\n - api: advapi32.CreateProcessWithToken\\n - api: kernel32.CreateProcessInternal\\n - api: ntdll.NtCreateUserProcess\\n - api: ntdll.NtCreateProcess\\n - api: ntdll.NtCreateProcessEx\\n - api: ntdll.ZwCreateProcess\\n - api: ZwCreateProcessEx\\n - api: ntdll.ZwCreateUserProcess\\n - api: ntdll.RtlCreateUserProcess\\n - api: System.Diagnostics.Process::Start\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439929}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.WinExec\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.CreateProcess\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439983}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"shell32.ShellExecute\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"shell32.ShellExecuteEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"advapi32.CreateProcessAsUser\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"advapi32.CreateProcessWithLogon\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"advapi32.CreateProcessWithToken\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.CreateProcessInternal\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ntdll.NtCreateUserProcess\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ntdll.NtCreateProcess\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ntdll.NtCreateProcessEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ntdll.ZwCreateProcess\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ZwCreateProcessEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ntdll.ZwCreateUserProcess\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ntdll.RtlCreateUserProcess\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Diagnostics.Process::Start\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"create mutex\": {\"meta\": {\"name\": \"create mutex\", \"namespace\": \"host-interaction/mutex\", \"authors\": [\"moritz.raabe@mandiant.com\", \"michael.hunhoff@mandiant.com\"], \"scope\": \"function\", \"attack\": [], \"mbc\": [{\"parts\": [\"Process\", \"Create Mutex\"], \"objective\": \"Process\", \"behavior\": \"Create Mutex\", \"method\": \"\", \"id\": \"C0042\"}], \"references\": [], \"examples\": [\"Practical Malware Analysis Lab 01-01.dll_:0x10001010\"], \"description\": \"\", \"lib\": false, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: create mutex\\n namespace: host-interaction/mutex\\n authors:\\n - moritz.raabe@mandiant.com\\n - michael.hunhoff@mandiant.com\\n scope: function\\n mbc:\\n - Process::Create Mutex [C0042]\\n examples:\\n - Practical Malware Analysis Lab 01-01.dll_:0x10001010\\n features:\\n - or:\\n - api: kernel32.CreateMutex\\n - api: kernel32.CreateMutexEx\\n - api: System.Threading.Mutex::ctor\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439568}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.CreateMutex\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439662}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"kernel32.CreateMutexEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Threading.Mutex::ctor\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"contain loop\": {\"meta\": {\"name\": \"contain loop\", \"authors\": [\"moritz.raabe@mandiant.com\"], \"scope\": \"function\", \"attack\": [], \"mbc\": [], \"references\": [], \"examples\": [\"08AC667C65D36D6542917655571E61C8:0x406EAA\"], \"description\": \"\", \"lib\": true, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: contain loop\\n authors:\\n - moritz.raabe@mandiant.com\\n lib: true\\n scope: function\\n examples:\\n - 08AC667C65D36D6542917655571E61C8:0x406EAA\\n features:\\n - or:\\n - characteristic: loop\\n - characteristic: tight loop\\n - characteristic: recursive call\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439568}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"characteristic\", \"characteristic\": \"loop\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439568}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"characteristic\", \"characteristic\": \"tight loop\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"characteristic\", \"characteristic\": \"recursive call\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"receive data on socket\": {\"meta\": {\"name\": \"receive data on socket\", \"namespace\": \"communication/socket/receive\", \"authors\": [\"moritz.raabe@mandiant.com\", \"joakim@intezer.com\", \"michael.hunhoff@mandiant.com\"], \"scope\": \"function\", \"attack\": [], \"mbc\": [{\"parts\": [\"Communication\", \"Socket Communication\", \"Receive Data\"], \"objective\": \"Communication\", \"behavior\": \"Socket Communication\", \"method\": \"Receive Data\", \"id\": \"C0001.006\"}], \"references\": [], \"examples\": [\"Practical Malware Analysis Lab 01-01.dll_:0x10001010\"], \"description\": \"\", \"lib\": false, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: receive data on socket\\n namespace: communication/socket/receive\\n authors:\\n - moritz.raabe@mandiant.com\\n - joakim@intezer.com\\n - michael.hunhoff@mandiant.com\\n scope: function\\n mbc:\\n - Communication::Socket Communication::Receive Data [C0001.006]\\n examples:\\n - Practical Malware Analysis Lab 01-01.dll_:0x10001010\\n features:\\n - or:\\n - api: ws2_32.recv\\n - api: ws2_32.recvfrom\\n - api: ws2_32.WSARecv\\n - api: ws2_32.WSARecvDisconnect\\n - api: ws2_32.WSARecvEx\\n - api: ws2_32.WSARecvFrom\\n - api: ws2_32.WSARecvMsg\\n - api: recv\\n - api: System.Net.Sockets.Socket::Receive\\n - api: System.Net.Sockets.Socket::ReceiveAsync\\n - api: System.Net.Sockets.Socket::ReceiveFrom\\n - api: System.Net.Sockets.Socket::ReceiveFromAsync\\n - api: System.Net.Sockets.Socket::ReceiveMessageFrom\\n - api: System.Net.Sockets.Socket::ReceiveMessageFromAsync\\n - api: System.Net.Sockets.Socket::BeginReceive\\n - api: System.Net.Sockets.Socket::BeginReceiveFrom\\n - api: System.Net.Sockets.Socket::BeginReceiveMessageFrom\\n - api: System.Net.Sockets.Socket::EndReceive\\n - api: System.Net.Sockets.Socket::EndReceiveFrom\\n - api: System.Net.Sockets.Socket::EndReceiveMessageFrom\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439568}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.recv\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439858}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.recvfrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSARecv\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSARecvDisconnect\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSARecvEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSARecvFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSARecvMsg\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"recv\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439858}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::Receive\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::ReceiveAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::ReceiveFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::ReceiveFromAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::ReceiveMessageFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::ReceiveMessageFromAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::BeginReceive\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::BeginReceiveFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::BeginReceiveMessageFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::EndReceive\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::EndReceiveFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::EndReceiveMessageFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"send data on socket\": {\"meta\": {\"name\": \"send data on socket\", \"namespace\": \"communication/socket/send\", \"authors\": [\"moritz.raabe@mandiant.com\", \"joakim@intezer.com\", \"anushka.virgaonkar@mandiant.com\"], \"scope\": \"function\", \"attack\": [], \"mbc\": [{\"parts\": [\"Communication\", \"Socket Communication\", \"Send Data\"], \"objective\": \"Communication\", \"behavior\": \"Socket Communication\", \"method\": \"Send Data\", \"id\": \"C0001.007\"}], \"references\": [], \"examples\": [\"Practical Malware Analysis Lab 01-01.dll_:0x10001010\"], \"description\": \"\", \"lib\": false, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: send data on socket\\n namespace: communication/socket/send\\n authors:\\n - moritz.raabe@mandiant.com\\n - joakim@intezer.com\\n - anushka.virgaonkar@mandiant.com\\n scope: function\\n mbc:\\n - Communication::Socket Communication::Send Data [C0001.007]\\n examples:\\n - Practical Malware Analysis Lab 01-01.dll_:0x10001010\\n features:\\n - or:\\n - api: ws2_32.send\\n - api: ws2_32.sendto\\n - api: ws2_32.WSASend\\n - api: ws2_32.WSASendMsg\\n - api: ws2_32.WSASendTo\\n - api: send\\n - api: System.Net.Sockets.Socket::Send\\n - api: System.Net.Sockets.Socket::SendAsync\\n - api: System.Net.Sockets.Socket::SendTo\\n - api: System.Net.Sockets.Socket::SendToAsync\\n - api: System.Net.Sockets.UdpClient::Send\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439568}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439809}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.sendto\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASend\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASendMsg\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASendTo\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439809}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::Send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::SendAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::SendTo\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::SendToAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.UdpClient::Send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"initialize Winsock library\": {\"meta\": {\"name\": \"initialize Winsock library\", \"namespace\": \"communication/socket\", \"authors\": [\"michael.hunhoff@mandiant.com\"], \"scope\": \"function\", \"attack\": [], \"mbc\": [{\"parts\": [\"Communication\", \"Socket Communication\", \"Initialize Winsock Library\"], \"objective\": \"Communication\", \"behavior\": \"Socket Communication\", \"method\": \"Initialize Winsock Library\", \"id\": \"C0001.009\"}], \"references\": [], \"examples\": [\"6A352C3E55E8AE5ED39DC1BE7FB964B1:0x10001D30\"], \"description\": \"\", \"lib\": false, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: initialize Winsock library\\n namespace: communication/socket\\n authors:\\n - michael.hunhoff@mandiant.com\\n scope: function\\n mbc:\\n - Communication::Socket Communication::Initialize Winsock Library [C0001.009]\\n examples:\\n - 6A352C3E55E8AE5ED39DC1BE7FB964B1:0x10001D30\\n features:\\n - and:\\n - api: ws2_32.WSAStartup\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439568}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSAStartup\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439678}], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"receive data\": {\"meta\": {\"name\": \"receive data\", \"namespace\": \"communication\", \"authors\": [\"william.ballenthin@mandiant.com\"], \"scope\": \"function\", \"attack\": [], \"mbc\": [{\"parts\": [\"Command and Control\", \"C2 Communication\", \"Receive Data\"], \"objective\": \"Command and Control\", \"behavior\": \"C2 Communication\", \"method\": \"Receive Data\", \"id\": \"B0030.002\"}], \"references\": [], \"examples\": [\"BFB9B5391A13D0AFD787E87AB90F14F5:0x13145D60\"], \"description\": \"all known techniques for receiving data from a potential C2 server\", \"lib\": false, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: receive data\\n namespace: communication\\n authors:\\n - william.ballenthin@mandiant.com\\n description: all known techniques for receiving data from a potential C2 server\\n scope: function\\n mbc:\\n - Command and Control::C2 Communication::Receive Data [B0030.002]\\n examples:\\n - BFB9B5391A13D0AFD787E87AB90F14F5:0x13145D60\\n features:\\n - or:\\n - match: receive data on socket\\n - match: read data from Internet\\n - match: download URL\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439568}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"receive data on socket\"}, \"type\": \"feature\"}, \"children\": [{\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.recv\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439858}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.recvfrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSARecv\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSARecvDisconnect\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSARecvEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSARecvFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSARecvMsg\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"recv\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439858}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::Receive\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::ReceiveAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::ReceiveFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::ReceiveFromAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::ReceiveMessageFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::ReceiveMessageFromAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::BeginReceive\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::BeginReceiveFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::BeginReceiveMessageFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::EndReceive\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::EndReceiveFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::EndReceiveMessageFrom\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [{\"type\": \"absolute\", \"value\": 268439568}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"read data from Internet\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"download URL\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"send data\": {\"meta\": {\"name\": \"send data\", \"namespace\": \"communication\", \"authors\": [\"william.ballenthin@mandiant.com\", \"joakim@intezer.com\"], \"scope\": \"function\", \"attack\": [], \"mbc\": [{\"parts\": [\"Command and Control\", \"C2 Communication\", \"Send Data\"], \"objective\": \"Command and Control\", \"behavior\": \"C2 Communication\", \"method\": \"Send Data\", \"id\": \"B0030.001\"}], \"references\": [], \"examples\": [\"BFB9B5391A13D0AFD787E87AB90F14F5:0x13145D60\"], \"description\": \"all known techniques for sending data to a potential C2 server\", \"lib\": false, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: send data\\n namespace: communication\\n authors:\\n - william.ballenthin@mandiant.com\\n - joakim@intezer.com\\n description: all known techniques for sending data to a potential C2 server\\n scope: function\\n mbc:\\n - Command and Control::C2 Communication::Send Data [B0030.001]\\n examples:\\n - BFB9B5391A13D0AFD787E87AB90F14F5:0x13145D60\\n features:\\n - or:\\n - and:\\n - os: windows\\n - or:\\n - match: send HTTP request\\n - match: send data on socket\\n - match: send file via HTTP\\n - and:\\n - os: linux\\n - or: # Require network bound socket.\\n - match: create TCP socket\\n - match: create UDP socket\\n - or:\\n - match: send HTTP request\\n - match: send data on socket\\n - match: send file via HTTP\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439568}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"os\", \"os\": \"windows\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"no address\"}], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"send HTTP request\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"send data on socket\"}, \"type\": \"feature\"}, \"children\": [{\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439809}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.sendto\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASend\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASendMsg\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASendTo\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439809}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::Send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::SendAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::SendTo\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::SendToAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.UdpClient::Send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [{\"type\": \"absolute\", \"value\": 268439568}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"send file via HTTP\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"os\", \"os\": \"linux\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"create TCP socket\"}, \"type\": \"feature\"}, \"children\": [{\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"property\", \"access\": \"read\", \"property\": \"System.Net.Sockets.TcpClient::Client\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 6, \"description\": \"IPPROTO_TCP\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439692}], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 1, \"description\": \"SOCK_STREAM\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439694}], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 2, \"description\": \"AF_INET\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439696}], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.socket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439698}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASocket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"socket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439698}], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [{\"type\": \"absolute\", \"value\": 268439692}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"create UDP socket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"send HTTP request\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"send data on socket\"}, \"type\": \"feature\"}, \"children\": [{\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439809}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.sendto\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASend\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASendMsg\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASendTo\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439809}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::Send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::SendAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::SendTo\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.Socket::SendToAsync\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.UdpClient::Send\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [{\"type\": \"absolute\", \"value\": 268439568}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"send file via HTTP\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"connect TCP socket\": {\"meta\": {\"name\": \"connect TCP socket\", \"namespace\": \"communication/socket/tcp\", \"authors\": [\"moritz.raabe@mandiant.com\", \"joakim@intezer.com\"], \"scope\": \"function\", \"attack\": [], \"mbc\": [{\"parts\": [\"Communication\", \"Socket Communication\", \"Connect Socket\"], \"objective\": \"Communication\", \"behavior\": \"Socket Communication\", \"method\": \"Connect Socket\", \"id\": \"C0001.004\"}], \"references\": [], \"examples\": [\"Practical Malware Analysis Lab 01-01.dll_:0x10001010\"], \"description\": \"\", \"lib\": false, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: connect TCP socket\\n namespace: communication/socket/tcp\\n authors:\\n - moritz.raabe@mandiant.com\\n - joakim@intezer.com\\n scope: function\\n mbc:\\n - Communication::Socket Communication::Connect Socket [C0001.004]\\n examples:\\n - Practical Malware Analysis Lab 01-01.dll_:0x10001010\\n features:\\n - and:\\n - match: create TCP socket\\n - or:\\n - api: connect\\n - api: ws2_32.connect\\n - api: ws2_32.WSAConnect\\n - api: ConnectEx\\n - and:\\n - basic block:\\n # candidate for GUID: WSAID_CONNECTEX/25a207b9-ddf3-4660-8ee9-76e58c74063e\\n - and:\\n - number: 0x25A207B9\\n - number: 0x4660DDF3\\n - number: 0xE576E98E\\n - number: 0x3E06748C\\n - basic block:\\n - and:\\n - api: WSAIoctl\\n - number: 0xC8000006 = SIO_GET_EXTENSION_FUNCTION_POINTER\\n - basic block:\\n - and:\\n - api: setsockopt\\n - number: 0xFFFF = SOL_SOCKET\\n - number: 0x7010 = SO_UPDATE_CONNECT_CONTEXT\\n # socket must be bound to ConnectEx\\n # https://gist.github.com/joeyadams/4158972\\n - api: bind\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439568}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"create TCP socket\"}, \"type\": \"feature\"}, \"children\": [{\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"property\", \"access\": \"read\", \"property\": \"System.Net.Sockets.TcpClient::Client\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 6, \"description\": \"IPPROTO_TCP\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439692}], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 1, \"description\": \"SOCK_STREAM\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439694}], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 2, \"description\": \"AF_INET\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439696}], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.socket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439698}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASocket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"socket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439698}], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [{\"type\": \"absolute\", \"value\": 268439692}], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"connect\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439758}], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.connect\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439758}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSAConnect\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ConnectEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"connect TCP socket/ae22acdd40144f4eabc347889338d681\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"connect TCP socket/c7c2534615d84c1b9beafde678afeb40\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"connect TCP socket/44a4a4d414174889997c583987ef02df\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"bind\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}, \"act as TCP client\": {\"meta\": {\"name\": \"act as TCP client\", \"namespace\": \"communication/tcp/client\", \"authors\": [\"william.ballenthin@mandiant.com\", \"michael.hunhoff@mandiant.com\"], \"scope\": \"function\", \"attack\": [], \"mbc\": [{\"parts\": [\"Communication\", \"Socket Communication\", \"TCP Client\"], \"objective\": \"Communication\", \"behavior\": \"Socket Communication\", \"method\": \"TCP Client\", \"id\": \"C0001.008\"}], \"references\": [], \"examples\": [\"Practical Malware Analysis Lab 01-01.dll_:0x10001010\"], \"description\": \"\", \"lib\": false, \"is_subscope_rule\": false, \"maec\": {}}, \"source\": \"rule:\\n meta:\\n name: act as TCP client\\n namespace: communication/tcp/client\\n authors:\\n - william.ballenthin@mandiant.com\\n - michael.hunhoff@mandiant.com\\n scope: function\\n mbc:\\n - Communication::Socket Communication::TCP Client [C0001.008]\\n examples:\\n - Practical Malware Analysis Lab 01-01.dll_:0x10001010\\n features:\\n - or:\\n - match: connect TCP socket\\n - api: System.Net.Sockets.TcpClient::ctor\\n\", \"matches\": [[{\"type\": \"absolute\", \"value\": 268439568}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"connect TCP socket\"}, \"type\": \"feature\"}, \"children\": [{\"success\": true, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"create TCP socket\"}, \"type\": \"feature\"}, \"children\": [{\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"property\", \"access\": \"read\", \"property\": \"System.Net.Sockets.TcpClient::Client\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 6, \"description\": \"IPPROTO_TCP\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439692}], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 1, \"description\": \"SOCK_STREAM\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439694}], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"number\", \"number\": 2, \"description\": \"AF_INET\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439696}], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.socket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439698}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSASocket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"socket\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439698}], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [{\"type\": \"absolute\", \"value\": 268439692}], \"captures\": {}}, {\"success\": true, \"node\": {\"statement\": {\"type\": \"or\"}, \"type\": \"statement\"}, \"children\": [{\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"connect\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439758}], \"captures\": {}}, {\"success\": true, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.connect\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [{\"type\": \"absolute\", \"value\": 268439758}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ws2_32.WSAConnect\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"ConnectEx\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"statement\": {\"type\": \"and\"}, \"type\": \"statement\"}, \"children\": [{\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"connect TCP socket/ae22acdd40144f4eabc347889338d681\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"connect TCP socket/c7c2534615d84c1b9beafde678afeb40\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"match\", \"match\": \"connect TCP socket/44a4a4d414174889997c583987ef02df\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"bind\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}], \"locations\": [{\"type\": \"absolute\", \"value\": 268439568}], \"captures\": {}}, {\"success\": false, \"node\": {\"feature\": {\"type\": \"api\", \"api\": \"System.Net.Sockets.TcpClient::ctor\"}, \"type\": \"feature\"}, \"children\": [], \"locations\": [], \"captures\": {}}], \"locations\": [], \"captures\": {}}]]}}}\n" \ No newline at end of file From fe1193f3745031df40c4ec5d76534525021c4144 Mon Sep 17 00:00:00 2001 From: Pratham Chauhan Date: Wed, 29 Mar 2023 16:12:17 +0530 Subject: [PATCH 26/79] removes unused imports --- tests/test_result_document.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/test_result_document.py b/tests/test_result_document.py index ad949bf0..c3c47f71 100644 --- a/tests/test_result_document.py +++ b/tests/test_result_document.py @@ -6,10 +6,7 @@ # 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. -from typing import Dict, Tuple -import textwrap import fixtures -from fixtures import * import capa import capa.engine as ceng From fbdf92367eaa79719bf72bc25ab95eac9508b274 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 Mar 2023 12:52:59 +0000 Subject: [PATCH 27/79] build(deps): bump protobuf from 4.21.12 to 4.22.1 Bumps [protobuf](https://github.com/protocolbuffers/protobuf) from 4.21.12 to 4.22.1. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/generate_changelog.py) - [Commits](https://github.com/protocolbuffers/protobuf/commits/v4.22.1) --- updated-dependencies: - dependency-name: protobuf dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 57620185..4ff5c246 100644 --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ requirements = [ "dnfile==0.13.0", "dncil==1.0.2", "pydantic==1.10.7", - "protobuf==4.21.12", + "protobuf==4.22.1", ] # this sets __version__ From 6806b8f5a7502724608534279ea57559f88d8884 Mon Sep 17 00:00:00 2001 From: Pratham Chauhan Date: Wed, 29 Mar 2023 19:02:45 +0530 Subject: [PATCH 28/79] use pydantic.parse_file --- capa/main.py | 2 +- capa/render/result_document.py | 9 +-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/capa/main.py b/capa/main.py index cf3d68c9..c8cd189e 100644 --- a/capa/main.py +++ b/capa/main.py @@ -1125,7 +1125,7 @@ def main(argv=None): logger.debug("file limitation short circuit, won't analyze fully.") return E_FILE_LIMITATION if format_ == FORMAT_RESULT: - result_doc = capa.render.result_document.ResultDocument.parse_raw(args.sample) + result_doc = capa.render.result_document.ResultDocument.parse_file(args.sample) meta, capabilities = result_doc.to_capa(rules) elif format_ == FORMAT_FREEZE: with open(args.sample, "rb") as f: diff --git a/capa/render/result_document.py b/capa/render/result_document.py index 877595cf..791a80f0 100644 --- a/capa/render/result_document.py +++ b/capa/render/result_document.py @@ -580,14 +580,7 @@ class ResultDocument(BaseModel): ) return ResultDocument(meta=Metadata.from_capa(meta), rules=rule_matches) - - @classmethod - def parse_raw(cls, path: str): - with open(path, "rb") as f: - buf= f.read() - data = json.loads(buf) - return ResultDocument(**data) - + def to_capa(self, rules: RuleSet) -> Tuple[Dict, Dict]: meta = self.meta.to_capa() capabilities: Dict[str, List[Tuple[frz.Address, capa.features.common.Result]]] ={} From a13ce094b360377b0b616b43e756dca1a7089dea Mon Sep 17 00:00:00 2001 From: Pratham Chauhan Date: Wed, 29 Mar 2023 19:41:14 +0530 Subject: [PATCH 29/79] use rd/test json --- tests/fixtures.py | 2 ++ tests/test_result_document.py | 9 +++------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/fixtures.py b/tests/fixtures.py index 5602f096..ce7f88e8 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -216,6 +216,8 @@ def get_data_path_by_name(name): return os.path.join(CD, "data", "kernel32-64.dll_") elif name == "pma01-01": return os.path.join(CD, "data", "Practical Malware Analysis Lab 01-01.dll_") + elif name == "pma01-01-rd": + return os.path.join(CD, "data", "rd", "Practical Malware Analysis Lab 01-01.dll_.json") elif name == "pma12-04": return os.path.join(CD, "data", "Practical Malware Analysis Lab 12-04.exe_") elif name == "pma16-01": diff --git a/tests/test_result_document.py b/tests/test_result_document.py index c3c47f71..01643091 100644 --- a/tests/test_result_document.py +++ b/tests/test_result_document.py @@ -230,9 +230,6 @@ def test_basic_block_node_from_capa(): assert isinstance(node, rdoc.FeatureNode) assert isinstance(node.feature, frzf.BasicBlockFeature) -def test_json_to_rdoc (capsys, tmpdir): - path = fixtures.get_data_path_by_name("pma01-01") - assert capa.main.main([path, "-j"]) == 0 - temp_file = tmpdir.join("capa.json") - temp_file.write(capsys.readouterr().out) - assert isinstance(rdoc.ResultDocument.parse_raw(temp_file),rdoc.ResultDocument) \ No newline at end of file +def test_json_to_rdoc(): + path = fixtures.get_data_path_by_name("pma01-01-rd") + assert isinstance(rdoc.ResultDocument.parse_file(path),rdoc.ResultDocument) \ No newline at end of file From 6ed7aca5be356a2c5bccc98f596035f5087e2b35 Mon Sep 17 00:00:00 2001 From: Pratham Chauhan Date: Wed, 29 Mar 2023 19:50:07 +0530 Subject: [PATCH 30/79] remove rule param --- capa/main.py | 2 +- capa/render/result_document.py | 27 ++++++++++++++------------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/capa/main.py b/capa/main.py index c8cd189e..0cd64a1a 100644 --- a/capa/main.py +++ b/capa/main.py @@ -1126,7 +1126,7 @@ def main(argv=None): return E_FILE_LIMITATION if format_ == FORMAT_RESULT: result_doc = capa.render.result_document.ResultDocument.parse_file(args.sample) - meta, capabilities = result_doc.to_capa(rules) + meta, capabilities = result_doc.to_capa() elif format_ == FORMAT_FREEZE: with open(args.sample, "rb") as f: extractor = capa.features.freeze.load(f.read()) diff --git a/capa/render/result_document.py b/capa/render/result_document.py index 791a80f0..b883dada 100644 --- a/capa/render/result_document.py +++ b/capa/render/result_document.py @@ -581,18 +581,19 @@ class ResultDocument(BaseModel): return ResultDocument(meta=Metadata.from_capa(meta), rules=rule_matches) - def to_capa(self, rules: RuleSet) -> Tuple[Dict, Dict]: + def to_capa(self) -> Tuple[Dict, Dict]: meta = self.meta.to_capa() - capabilities: Dict[str, List[Tuple[frz.Address, capa.features.common.Result]]] ={} + capabilities: Dict[str, List[Tuple[frz.Address, capa.features.common.Result]]] = {} for rule_name, rule_match in self.rules.items(): - + # Parse the YAML source into a Rule instance + rule = capa.rules.Rule.from_yaml(rule_match.source) + # Extract the capabilities from the RuleMatches object for addr, match in rule_match.matches: - if isinstance(match.node, StatementNode): if isinstance(match.node.statement, CompoundStatement): - statement = rules[rule_name].statement + statement = rule.statement else: statement = statement_from_capa(match.node.statement) elif isinstance(match.node, FeatureNode): @@ -601,15 +602,15 @@ class ResultDocument(BaseModel): statement.matches = match.captures else: raise ValueError("Invalid node type") - + result = capa.features.common.Result( - statement=statement, - success=match.success, - locations=[frz.Address.to_capa(loc) for loc in match.locations], - children=[]) + statement=statement, + success=match.success, + locations=[frz.Address.to_capa(loc) for loc in match.locations], + children=[]) if rule_name not in capabilities: - capabilities[rule_name]=[] - capabilities[rule_name].append((frz.Address.from_capa(addr),result)) - + capabilities[rule_name] = [] + capabilities[rule_name].append((frz.Address.from_capa(addr), result)) + return meta, capabilities \ No newline at end of file From 237554d84a64a08f06a597daca0e90340ea89048 Mon Sep 17 00:00:00 2001 From: Pratham Chauhan Date: Wed, 29 Mar 2023 22:32:12 +0530 Subject: [PATCH 31/79] Fix broken logic for FORMAT_FREEZE --- capa/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/capa/main.py b/capa/main.py index 0cd64a1a..081bd1fe 100644 --- a/capa/main.py +++ b/capa/main.py @@ -1157,6 +1157,7 @@ def main(argv=None): log_unsupported_os_error() return E_INVALID_FILE_OS + if format_ != FORMAT_RESULT: meta = collect_metadata(argv, args.sample, args.rules, extractor) capabilities, counts = find_capabilities(rules, extractor, disable_progress=args.quiet) From c3fdab8ec52bd1328680029bcd87299cf85388a0 Mon Sep 17 00:00:00 2001 From: Pratham Chauhan Date: Wed, 29 Mar 2023 22:57:11 +0530 Subject: [PATCH 32/79] Add new test test_rdoc_to_capa --- tests/test_result_document.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/test_result_document.py b/tests/test_result_document.py index 01643091..ccd79d72 100644 --- a/tests/test_result_document.py +++ b/tests/test_result_document.py @@ -232,4 +232,9 @@ def test_basic_block_node_from_capa(): def test_json_to_rdoc(): path = fixtures.get_data_path_by_name("pma01-01-rd") - assert isinstance(rdoc.ResultDocument.parse_file(path),rdoc.ResultDocument) \ No newline at end of file + assert isinstance(rdoc.ResultDocument.parse_file(path),rdoc.ResultDocument) + +def test_rdoc_to_capa(): + path = fixtures.get_data_path_by_name("pma01-01-rd") + assert len(rdoc.ResultDocument.parse_file(path).to_capa()) ==2 + assert isinstance(rdoc.ResultDocument.parse_file(path).to_capa(),tuple) \ No newline at end of file From 5e8262d3c0dd6e7d5fff32cdb404d36794df2e87 Mon Sep 17 00:00:00 2001 From: Stephen Eckels Date: Wed, 29 Mar 2023 15:58:16 -0400 Subject: [PATCH 33/79] Remove dynsym from elf entirely --- capa/features/extractors/ida/helpers.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/capa/features/extractors/ida/helpers.py b/capa/features/extractors/ida/helpers.py index dbb9bd1d..a6068451 100644 --- a/capa/features/extractors/ida/helpers.py +++ b/capa/features/extractors/ida/helpers.py @@ -90,8 +90,10 @@ def get_file_imports() -> Dict[int, Tuple[str, str, int]]: if not library: continue - # IDA uses section names for the library of ELF imports, like ".dynsym" - library = library.lstrip(".") + # IDA uses section names for the library of ELF imports, like ".dynsym". + # These are not useful to us, we may need to expand this list over time (TODO: exhaust this list) + if library == ".dynsym": + library = "" def inspect_import(ea, function, ordinal): if function and function.startswith("__imp_"): From 66e374a3433278e8755f99d21e3c14b9ec3b7355 Mon Sep 17 00:00:00 2001 From: Stephen Eckels Date: Wed, 29 Mar 2023 16:01:31 -0400 Subject: [PATCH 34/79] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b17b00c5..c4ba5f3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Change Log ## master (unreleased) +- removed '.dynsym' as the library name for ELF imports. get_file_imports now only returns the API name. ### New Features - add protobuf format for result documents #1219 @williballenthin @mr-tz From 7cb4ea927334a071fbe95c27f00fe95bd540f043 Mon Sep 17 00:00:00 2001 From: Pratham Chauhan Date: Thu, 30 Mar 2023 10:35:31 +0530 Subject: [PATCH 35/79] Fix lint issues --- capa/features/extractors/common.py | 22 ++++++++++++++++++---- capa/main.py | 2 +- capa/render/result_document.py | 19 ++++++++----------- tests/test_result_document.py | 8 +++++--- 4 files changed, 32 insertions(+), 19 deletions(-) diff --git a/capa/features/extractors/common.py b/capa/features/extractors/common.py index 806f895c..8a2c7899 100644 --- a/capa/features/extractors/common.py +++ b/capa/features/extractors/common.py @@ -10,16 +10,30 @@ import capa.features import capa.features.extractors.elf import capa.features.extractors.pefile import capa.features.extractors.strings -from capa.features.common import OS, FORMAT_PE, FORMAT_ELF, OS_ANY, OS_WINDOWS, FORMAT_FREEZE, FORMAT_RESULT, ARCH_ANY, Arch, Format, String, Feature +from capa.features.common import ( + OS, + OS_ANY, + ARCH_ANY, + FORMAT_PE, + FORMAT_ELF, + OS_WINDOWS, + FORMAT_FREEZE, + FORMAT_RESULT, + Arch, + Format, + String, + Feature, +) from capa.features.freeze import is_freeze from capa.features.address import NO_ADDRESS, Address, FileOffsetAddress logger = logging.getLogger(__name__) -#match strings for formats +# match strings for formats MATCH_PE = b"MZ" MATCH_ELF = b"\x7fELF" -MATCH_RESULT = b"{\"meta\":" +MATCH_RESULT = b'{"meta":' + def extract_file_strings(buf, **kwargs) -> Iterator[Tuple[String, Address]]: """ @@ -57,7 +71,7 @@ def extract_arch(buf) -> Iterator[Tuple[Feature, Address]]: elif buf.startswith(MATCH_ELF): with contextlib.closing(io.BytesIO(buf)) as f: arch = capa.features.extractors.elf.detect_elf_arch(f) - + elif buf.startswith(MATCH_RESULT): arch = ARCH_ANY diff --git a/capa/main.py b/capa/main.py index 081bd1fe..eb3c2bee 100644 --- a/capa/main.py +++ b/capa/main.py @@ -65,7 +65,7 @@ from capa.features.common import ( FORMAT_SC64, FORMAT_DOTNET, FORMAT_FREEZE, - FORMAT_RESULT + FORMAT_RESULT, ) from capa.features.address import NO_ADDRESS, Address from capa.features.extractors.base_extractor import BBHandle, InsnHandle, FunctionHandle, FeatureExtractor diff --git a/capa/render/result_document.py b/capa/render/result_document.py index b883dada..eac58b0b 100644 --- a/capa/render/result_document.py +++ b/capa/render/result_document.py @@ -5,8 +5,8 @@ # 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. -import datetime import json +import datetime from typing import Any, Dict, List, Tuple, Union, Optional from pydantic import Field, BaseModel @@ -152,18 +152,14 @@ class Metadata(FrozenModel): }, "feature_counts": { "file": self.analysis.feature_counts.file, - "functions": { - fc.address.to_capa(): fc.count for fc in self.analysis.feature_counts.functions - }, - }, - "library_functions": { - lf.address.to_capa(): lf.name for lf in self.analysis.library_functions + "functions": {fc.address.to_capa(): fc.count for fc in self.analysis.feature_counts.functions}, }, + "library_functions": {lf.address.to_capa(): lf.name for lf in self.analysis.library_functions}, }, } return capa_meta - + class CompoundStatementType: AND = "and" @@ -580,7 +576,7 @@ class ResultDocument(BaseModel): ) return ResultDocument(meta=Metadata.from_capa(meta), rules=rule_matches) - + def to_capa(self) -> Tuple[Dict, Dict]: meta = self.meta.to_capa() capabilities: Dict[str, List[Tuple[frz.Address, capa.features.common.Result]]] = {} @@ -607,10 +603,11 @@ class ResultDocument(BaseModel): statement=statement, success=match.success, locations=[frz.Address.to_capa(loc) for loc in match.locations], - children=[]) + children=[], + ) if rule_name not in capabilities: capabilities[rule_name] = [] capabilities[rule_name].append((frz.Address.from_capa(addr), result)) - return meta, capabilities \ No newline at end of file + return meta, capabilities diff --git a/tests/test_result_document.py b/tests/test_result_document.py index ccd79d72..da45d092 100644 --- a/tests/test_result_document.py +++ b/tests/test_result_document.py @@ -230,11 +230,13 @@ def test_basic_block_node_from_capa(): assert isinstance(node, rdoc.FeatureNode) assert isinstance(node.feature, frzf.BasicBlockFeature) + def test_json_to_rdoc(): path = fixtures.get_data_path_by_name("pma01-01-rd") - assert isinstance(rdoc.ResultDocument.parse_file(path),rdoc.ResultDocument) + assert isinstance(rdoc.ResultDocument.parse_file(path), rdoc.ResultDocument) + def test_rdoc_to_capa(): path = fixtures.get_data_path_by_name("pma01-01-rd") - assert len(rdoc.ResultDocument.parse_file(path).to_capa()) ==2 - assert isinstance(rdoc.ResultDocument.parse_file(path).to_capa(),tuple) \ No newline at end of file + assert len(rdoc.ResultDocument.parse_file(path).to_capa()) == 2 + assert isinstance(rdoc.ResultDocument.parse_file(path).to_capa(), tuple) From cd0e0ce4d16d84959504ae4b1ceebd0a03734dc5 Mon Sep 17 00:00:00 2001 From: Pratham Chauhan Date: Thu, 30 Mar 2023 10:52:05 +0530 Subject: [PATCH 36/79] remove unused import --- capa/render/result_document.py | 1 - 1 file changed, 1 deletion(-) diff --git a/capa/render/result_document.py b/capa/render/result_document.py index eac58b0b..5bb646f3 100644 --- a/capa/render/result_document.py +++ b/capa/render/result_document.py @@ -5,7 +5,6 @@ # 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. -import json import datetime from typing import Any, Dict, List, Tuple, Union, Optional From 1ccd2c4d0fccdc0a72787d9c455f2a994d7c415f Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Thu, 30 Mar 2023 11:45:03 +0200 Subject: [PATCH 37/79] tests: fix proto tests on windows (#1417) closes #1416 --- tests/test_scripts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_scripts.py b/tests/test_scripts.py index fb1ce734..3b299a36 100644 --- a/tests/test_scripts.py +++ b/tests/test_scripts.py @@ -81,4 +81,4 @@ def test_proto_conversion(tmpdir): p = run_program(get_script_path("proto-to-results.py"), [pb]) assert p.returncode == 0 - assert p.stdout.startswith(b'{\n "meta": ') + assert p.stdout.startswith(b'{\n "meta": ') or p.stdout.startswith(b'{\r\n "meta": ') From 456f6e0003098eec762b69b4d210d112c3bb7581 Mon Sep 17 00:00:00 2001 From: Pratham Chauhan Date: Thu, 30 Mar 2023 16:18:52 +0530 Subject: [PATCH 38/79] fix broken arch logic --- capa/features/extractors/common.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/capa/features/extractors/common.py b/capa/features/extractors/common.py index 7ef731ec..39411bde 100644 --- a/capa/features/extractors/common.py +++ b/capa/features/extractors/common.py @@ -68,14 +68,14 @@ def extract_format(buf) -> Iterator[Tuple[Feature, Address]]: def extract_arch(buf) -> Iterator[Tuple[Feature, Address]]: if buf.startswith(MATCH_PE): yield from capa.features.extractors.pefile.extract_file_arch(pe=pefile.PE(data=buf)) + + elif buf.startswith(MATCH_RESULT): + yield Arch(ARCH_ANY), NO_ADDRESS elif buf.startswith(MATCH_ELF): with contextlib.closing(io.BytesIO(buf)) as f: arch = capa.features.extractors.elf.detect_elf_arch(f) - elif buf.startswith(MATCH_RESULT): - arch = ARCH_ANY - if arch not in capa.features.common.VALID_ARCH: logger.debug("unsupported arch: %s", arch) return From 24f4ebef2334311cb665a10843da542720a06f9e Mon Sep 17 00:00:00 2001 From: manasghandat <95558940+manasghandat@users.noreply.github.com> Date: Thu, 30 Mar 2023 22:51:07 +0530 Subject: [PATCH 39/79] Update capa/render/proto/__init__.py Co-authored-by: Willi Ballenthin --- capa/render/proto/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/capa/render/proto/__init__.py b/capa/render/proto/__init__.py index 7af7b664..f3f52a58 100644 --- a/capa/render/proto/__init__.py +++ b/capa/render/proto/__init__.py @@ -645,6 +645,7 @@ def feature_from_pb2(f: capa_pb2.FeatureNode) -> frzf.Feature: return frzf.OperandOffsetFeature( index=ff.index, operand_offset=int_from_pb2(ff.operand_offset), description=ff.description or None ) # type: ignore + # Mypy is unable to recognize `operand_offset` as an argument due to aliasing elif type_ == "basic_block": ff = f.basic_block return frzf.BasicBlockFeature(description=ff.description or None) From fac548a76ea733a3917e4791dee085b959129616 Mon Sep 17 00:00:00 2001 From: manasghandat <95558940+manasghandat@users.noreply.github.com> Date: Thu, 30 Mar 2023 22:51:17 +0530 Subject: [PATCH 40/79] Update capa/render/proto/__init__.py Co-authored-by: Willi Ballenthin --- capa/render/proto/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/capa/render/proto/__init__.py b/capa/render/proto/__init__.py index f3f52a58..66a06c82 100644 --- a/capa/render/proto/__init__.py +++ b/capa/render/proto/__init__.py @@ -614,6 +614,7 @@ def feature_from_pb2(f: capa_pb2.FeatureNode) -> frzf.Feature: elif type_ == "class_": ff = f.class_ return frzf.ClassFeature(class_=ff.class_, description=ff.description or None) # type: ignore + # Mypy is unable to recognize `class_` as an argument due to aliasing elif type_ == "namespace": ff = f.namespace return frzf.NamespaceFeature(namespace=ff.namespace, description=ff.description or None) From 3cd766630faba3a630ebfcf5c19c7934f3cf3bf1 Mon Sep 17 00:00:00 2001 From: Stephen Eckels Date: Thu, 30 Mar 2023 13:21:37 -0400 Subject: [PATCH 41/79] Update changelog --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4ba5f3a..97c32f85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,6 @@ # Change Log ## master (unreleased) -- removed '.dynsym' as the library name for ELF imports. get_file_imports now only returns the API name. ### New Features - add protobuf format for result documents #1219 @williballenthin @mr-tz @@ -38,9 +37,9 @@ - nursery/enumerate-pe-sections-in-dotnet @mr-tz - nursery/destroy-software-breakpoint-capability echernofsky@google.com - nursery/send-data-to-internet michael.hunhoff@mandiant.com -- ### Bug Fixes +- extractor: removed '.dynsym' as the library name for ELF imports. get_file_imports now only returns the API name. - extractor: fix vivisect loop detection corner case #1310 @mr-tz - match: extend OS characteristic to match OS_ANY to all supported OSes #1324 @mike-hunhoff - extractor: fix IDA and vivisect string and bytes features overlap and tests #1327 #1336 @xusheng6 From 1921961cff5d1babb098cc92e333a8de17be2710 Mon Sep 17 00:00:00 2001 From: Stephen Eckels Date: Thu, 30 Mar 2023 13:23:29 -0400 Subject: [PATCH 42/79] Update todo comment to link issue Co-authored-by: Willi Ballenthin --- capa/features/extractors/ida/helpers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/capa/features/extractors/ida/helpers.py b/capa/features/extractors/ida/helpers.py index a6068451..daec2152 100644 --- a/capa/features/extractors/ida/helpers.py +++ b/capa/features/extractors/ida/helpers.py @@ -91,7 +91,8 @@ def get_file_imports() -> Dict[int, Tuple[str, str, int]]: continue # IDA uses section names for the library of ELF imports, like ".dynsym". - # These are not useful to us, we may need to expand this list over time (TODO: exhaust this list) + # These are not useful to us, we may need to expand this list over time + # TODO: exhaust this list, see #1419 if library == ".dynsym": library = "" From d09e1c8ee2c780bfbffc4092395593c1bbaef24c Mon Sep 17 00:00:00 2001 From: manasghandat Date: Fri, 31 Mar 2023 12:29:26 +0530 Subject: [PATCH 43/79] fix linting error --- capa/features/extractors/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/capa/features/extractors/common.py b/capa/features/extractors/common.py index 39411bde..6beaa72d 100644 --- a/capa/features/extractors/common.py +++ b/capa/features/extractors/common.py @@ -68,7 +68,7 @@ def extract_format(buf) -> Iterator[Tuple[Feature, Address]]: def extract_arch(buf) -> Iterator[Tuple[Feature, Address]]: if buf.startswith(MATCH_PE): yield from capa.features.extractors.pefile.extract_file_arch(pe=pefile.PE(data=buf)) - + elif buf.startswith(MATCH_RESULT): yield Arch(ARCH_ANY), NO_ADDRESS From 7f39cb1bc38b5ea8e613550cc8ea349c113be802 Mon Sep 17 00:00:00 2001 From: Capa Bot Date: Fri, 31 Mar 2023 14:03:51 +0000 Subject: [PATCH 44/79] Sync capa rules submodule --- rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules b/rules index d0e54bb0..8635a31c 160000 --- a/rules +++ b/rules @@ -1 +1 @@ -Subproject commit d0e54bb05d8549cd3979ff1b21a22ee33c533ad6 +Subproject commit 8635a31c89c3686c979f6650268b1369f54f90e5 From 59be399dac266ed0c45d3e1bddfba033b98da4de Mon Sep 17 00:00:00 2001 From: Stephen Eckels Date: Fri, 31 Mar 2023 13:25:37 -0400 Subject: [PATCH 45/79] Revert line removal --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97c32f85..06072a17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ - nursery/enumerate-pe-sections-in-dotnet @mr-tz - nursery/destroy-software-breakpoint-capability echernofsky@google.com - nursery/send-data-to-internet michael.hunhoff@mandiant.com +- ### Bug Fixes - extractor: removed '.dynsym' as the library name for ELF imports. get_file_imports now only returns the API name. From 270350f8d13497e3ec777f1ee79103882ebbe4aa Mon Sep 17 00:00:00 2001 From: Stephen Eckels Date: Fri, 31 Mar 2023 13:26:41 -0400 Subject: [PATCH 46/79] Update CHANGELOG.md Co-authored-by: Willi Ballenthin --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 06072a17..69f3dd74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,7 +40,7 @@ - ### Bug Fixes -- extractor: removed '.dynsym' as the library name for ELF imports. get_file_imports now only returns the API name. +- extractor: removed '.dynsym' as the library name for ELF imports #1318 @stevemk14ebr - extractor: fix vivisect loop detection corner case #1310 @mr-tz - match: extend OS characteristic to match OS_ANY to all supported OSes #1324 @mike-hunhoff - extractor: fix IDA and vivisect string and bytes features overlap and tests #1327 #1336 @xusheng6 From 06c71a7f2bc7ecac84a56401c209b2f05ec35242 Mon Sep 17 00:00:00 2001 From: Capa Bot Date: Fri, 31 Mar 2023 17:40:58 +0000 Subject: [PATCH 47/79] Sync capa rules submodule --- CHANGELOG.md | 3 ++- README.md | 2 +- rules | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 733542c6..778d9042 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ ### Breaking Changes -### New Rules (24) +### New Rules (25) - persistence/scheduled-tasks/schedule-task-via-at joren485 - data-manipulation/prng/generate-random-numbers-via-rtlgenrandom william.ballenthin@mandiant.com @@ -37,6 +37,7 @@ - nursery/enumerate-pe-sections-in-dotnet @mr-tz - nursery/destroy-software-breakpoint-capability echernofsky@google.com - nursery/send-data-to-internet michael.hunhoff@mandiant.com +- nursery/compiled-with-cx_freeze @mr-tz - ### Bug Fixes diff --git a/README.md b/README.md index 2a40aaf1..a353eeb6 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/flare-capa)](https://pypi.org/project/flare-capa) [![Last release](https://img.shields.io/github/v/release/mandiant/capa)](https://github.com/mandiant/capa/releases) -[![Number of rules](https://img.shields.io/badge/rules-792-blue.svg)](https://github.com/mandiant/capa-rules) +[![Number of rules](https://img.shields.io/badge/rules-793-blue.svg)](https://github.com/mandiant/capa-rules) [![CI status](https://github.com/mandiant/capa/workflows/CI/badge.svg)](https://github.com/mandiant/capa/actions?query=workflow%3ACI+event%3Apush+branch%3Amaster) [![Downloads](https://img.shields.io/github/downloads/mandiant/capa/total)](https://github.com/mandiant/capa/releases) [![License](https://img.shields.io/badge/license-Apache--2.0-green.svg)](LICENSE.txt) diff --git a/rules b/rules index 8635a31c..ae4eb03e 160000 --- a/rules +++ b/rules @@ -1 +1 @@ -Subproject commit 8635a31c89c3686c979f6650268b1369f54f90e5 +Subproject commit ae4eb03ec2151b99b414218d6a610b56ca572634 From 1f6cd807a449fd9e95f2e8a7030554a9ef8608b1 Mon Sep 17 00:00:00 2001 From: Yacine Elhamer Date: Sun, 2 Apr 2023 17:30:26 +0100 Subject: [PATCH 48/79] Shdr dataclass: add sh_entsize member --- capa/features/extractors/elf.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/capa/features/extractors/elf.py b/capa/features/extractors/elf.py index ab79cc74..7201cc9f 100644 --- a/capa/features/extractors/elf.py +++ b/capa/features/extractors/elf.py @@ -88,6 +88,7 @@ class Shdr: offset: int size: int link: int + entsize: int buf: bytes @@ -320,12 +321,12 @@ class ELF: shent = self.shbuf[shent_offset : shent_offset + self.e_shentsize] if self.bitness == 32: - sh_name, sh_type, sh_flags, sh_addr, sh_offset, sh_size, sh_link = struct.unpack_from( - self.endian + "IIIIIII", shent, 0x0 + sh_name, sh_type, sh_flags, sh_addr, sh_offset, sh_size, sh_link, _, _, sh_entsize = struct.unpack_from( + self.endian + "IIIIIIIIII", shent, 0x0 ) elif self.bitness == 64: - sh_name, sh_type, sh_flags, sh_addr, sh_offset, sh_size, sh_link = struct.unpack_from( - self.endian + "IIQQQQI", shent, 0x0 + sh_name, sh_type, sh_flags, sh_addr, sh_offset, sh_size, sh_link, _, _, sh_entsize = struct.unpack_from( + self.endian + "IIQQQQIIQQ", shent, 0x0 ) else: raise NotImplementedError() @@ -337,7 +338,7 @@ class ELF: if len(buf) != sh_size: raise ValueError("failed to read section header content") - return Shdr(sh_name, sh_type, sh_flags, sh_addr, sh_offset, sh_size, sh_link, buf) + return Shdr(sh_name, sh_type, sh_flags, sh_addr, sh_offset, sh_size, sh_link, sh_entsize, buf) @property def section_headers(self): From bfaee2c402c30eb3a41c84b7315e37c0caa9406b Mon Sep 17 00:00:00 2001 From: Yacine Elhamer Date: Sun, 2 Apr 2023 17:34:13 +0100 Subject: [PATCH 49/79] Add a class (SYMTAB) for the symbol table --- capa/features/extractors/elf.py | 38 +++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/capa/features/extractors/elf.py b/capa/features/extractors/elf.py index 7201cc9f..9db24262 100644 --- a/capa/features/extractors/elf.py +++ b/capa/features/extractors/elf.py @@ -604,6 +604,44 @@ class SHNote: return ABITag(os, kmajor, kminor, kpatch) +class SYMTAB: + def __init__(self, endian: str, bitness: int, symtab_buf: bytes, symtab_entsize:int, symtab_sz: int, strtab_buf: bytes, strtab_sz: int) -> None: + self.symbols = [] + self.symnum = int(symtab_sz / symtab_entsize) + self.entsize = symtab_entsize + + self.strings = strtab_buf + self.strings_sz = strtab_sz + + self._parse(endian, bitness, symtab_buf) + + def _parse(self, endian: str, bitness: int, symtab_buf) -> None: + """ + return the symbol's information in + the order specified by sys/elf32.h + """ + for i in range(self.symnum): + if bitness == 32: + name, value, size, info, other, shndx = struct.unpack_from(endian+"IIIBBH", symtab_buf, i*self.entsize) + elif bitness == 64: + name, info, other, shndx, value, size = struct.unpack_from(endian+"IBBBQQ", symtab_buf, i*self.entsize) + + self.symbols.append((name, value, size, info, other, shndx)) + + def fetch_str(self, offset) -> str: + """ + fetch a symbol's name from symtab's + associated strings' section (SHT_STRTAB) + """ + for i in range(offset, self.strings_sz): + if self.strings[i] == 0: + return self.strings[offset:i].decode() + + def get_symbols(self) -> Tuple[int, int, int, int, int, int]: + for symbol in self.symbols: + yield symbol + + def guess_os_from_osabi(elf) -> Optional[OS]: return elf.ei_osabi From ef0e4bd4fdd7eb8dcd4c4222311421127005c828 Mon Sep 17 00:00:00 2001 From: Yacine Elhamer Date: Sun, 2 Apr 2023 17:54:40 +0100 Subject: [PATCH 50/79] os-guessing: Add symtab-guessing capability --- capa/features/extractors/elf.py | 34 +++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/capa/features/extractors/elf.py b/capa/features/extractors/elf.py index 9db24262..5ffdbfb4 100644 --- a/capa/features/extractors/elf.py +++ b/capa/features/extractors/elf.py @@ -769,6 +769,40 @@ def guess_os_from_needed_dependencies(elf) -> Optional[OS]: return None +def guess_os_from_symtab(elf) -> Optional[OS]: + SHT_SYMTAB = 0x2 + SHT_STRTAB = 0x3 + + for shdr in elf.section_headers: + if shdr.type == SHT_STRTAB: + strtab_buf, strtab_sz= shdr.buf, shdr.size + + elif shdr.type == SHT_SYMTAB: + symtab_buf, symtab_entsize, symtab_sz = shdr.buf, shdr.entsize, shdr.size + + if None in (strtab_buf, symtab_buf): + # executable does not contain a symbol table + # or the symbol's names are stripped + return None + + symtab = SYMTAB( + elf.endian, elf.bitness, symtab_buf, symtab_entsize, symtab_sz, strtab_buf, strtab_sz + ) + + keywords = { + OS.LINUX: ['linux', '/linux/',], + } + + for name, *_ in symtab.get_symbols(): + sym_name = symtab.fetch_str(name) + + for os, hints in keywords.items(): + if any(map(lambda x: x in sym_name, hints)): + return os + + return None + + def detect_elf_os(f) -> str: """ f: type Union[BinaryIO, IDAIO] From c798996f6e8c559458318de38340486b736987fe Mon Sep 17 00:00:00 2001 From: Yacine Elhamer Date: Sun, 2 Apr 2023 18:11:11 +0100 Subject: [PATCH 51/79] detect_elf_os(): Integrate symbol-based guessing ability --- capa/features/extractors/elf.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/capa/features/extractors/elf.py b/capa/features/extractors/elf.py index 5ffdbfb4..f456c246 100644 --- a/capa/features/extractors/elf.py +++ b/capa/features/extractors/elf.py @@ -827,6 +827,9 @@ def detect_elf_os(f) -> str: needed_dependencies_guess = guess_os_from_needed_dependencies(elf) logger.debug("guess: needed dependencies: %s", needed_dependencies_guess) + symtab_guess = guess_os_from_symtab(elf) + logger.debug("guess: pertinent symbol name: %s", symtab_guess) + ret = None if osabi_guess: @@ -847,6 +850,10 @@ def detect_elf_os(f) -> str: elif needed_dependencies_guess: ret = needed_dependencies_guess + elif symtab_guess: + ret = symtab_guess + + return ret.value if ret is not None else "unknown" From 2d1105dba9ac80b3340460425ab094dc42a05f64 Mon Sep 17 00:00:00 2001 From: Yacine Elhamer <16624109+yelhamer@users.noreply.github.com> Date: Sun, 2 Apr 2023 20:36:34 +0100 Subject: [PATCH 52/79] format: update elf.py to use isort and black format Co-authored-by: Willi Ballenthin --- capa/features/extractors/elf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/capa/features/extractors/elf.py b/capa/features/extractors/elf.py index f456c246..c3379d5d 100644 --- a/capa/features/extractors/elf.py +++ b/capa/features/extractors/elf.py @@ -787,11 +787,11 @@ def guess_os_from_symtab(elf) -> Optional[OS]: symtab = SYMTAB( elf.endian, elf.bitness, symtab_buf, symtab_entsize, symtab_sz, strtab_buf, strtab_sz - ) + ) keywords = { OS.LINUX: ['linux', '/linux/',], - } + } for name, *_ in symtab.get_symbols(): sym_name = symtab.fetch_str(name) From 8a272e92c7fab629ebbafc032ec4e24fa5362a66 Mon Sep 17 00:00:00 2001 From: Yacine Elhamer <16624109+yelhamer@users.noreply.github.com> Date: Sun, 2 Apr 2023 20:38:44 +0100 Subject: [PATCH 53/79] format: removed tabs Co-authored-by: Willi Ballenthin --- capa/features/extractors/elf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/capa/features/extractors/elf.py b/capa/features/extractors/elf.py index c3379d5d..d6f21bfc 100644 --- a/capa/features/extractors/elf.py +++ b/capa/features/extractors/elf.py @@ -782,7 +782,7 @@ def guess_os_from_symtab(elf) -> Optional[OS]: if None in (strtab_buf, symtab_buf): # executable does not contain a symbol table - # or the symbol's names are stripped + # or the symbol's names are stripped return None symtab = SYMTAB( From 367a0c483c8063622b91211f44abdb0d5abdd193 Mon Sep 17 00:00:00 2001 From: Yacine Elhamer Date: Sun, 2 Apr 2023 20:49:58 +0100 Subject: [PATCH 54/79] rename the SYMTAB class to SymTab --- capa/features/extractors/elf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/capa/features/extractors/elf.py b/capa/features/extractors/elf.py index d6f21bfc..66cc822d 100644 --- a/capa/features/extractors/elf.py +++ b/capa/features/extractors/elf.py @@ -604,7 +604,7 @@ class SHNote: return ABITag(os, kmajor, kminor, kpatch) -class SYMTAB: +class SymTab: def __init__(self, endian: str, bitness: int, symtab_buf: bytes, symtab_entsize:int, symtab_sz: int, strtab_buf: bytes, strtab_sz: int) -> None: self.symbols = [] self.symnum = int(symtab_sz / symtab_entsize) @@ -785,7 +785,7 @@ def guess_os_from_symtab(elf) -> Optional[OS]: # or the symbol's names are stripped return None - symtab = SYMTAB( + symtab = SymTab( elf.endian, elf.bitness, symtab_buf, symtab_entsize, symtab_sz, strtab_buf, strtab_sz ) From 270077bc73ac3d48adf6a978ac209242abab1c8f Mon Sep 17 00:00:00 2001 From: Yacine Elhamer Date: Sun, 2 Apr 2023 20:59:09 +0100 Subject: [PATCH 55/79] SymTab class: update get_symbols() type and add return-value comment --- capa/features/extractors/elf.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/capa/features/extractors/elf.py b/capa/features/extractors/elf.py index 66cc822d..2f153dbc 100644 --- a/capa/features/extractors/elf.py +++ b/capa/features/extractors/elf.py @@ -637,7 +637,11 @@ class SymTab: if self.strings[i] == 0: return self.strings[offset:i].decode() - def get_symbols(self) -> Tuple[int, int, int, int, int, int]: + def get_symbols(self) -> Iterator[Tuple[int, int, int, int, int, int]]: + """ + return a tuple: (name, value, size, info, other, shndx) + for each symbol contained in the symbol table + """ for symbol in self.symbols: yield symbol From 74284e9dadee85e4f6133292fffd1899f1cb2ba9 Mon Sep 17 00:00:00 2001 From: Yacine Elhamer Date: Sun, 2 Apr 2023 21:56:28 +0100 Subject: [PATCH 56/79] bugfix: potential reference to uninitialized variables --- capa/features/extractors/elf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/capa/features/extractors/elf.py b/capa/features/extractors/elf.py index 2f153dbc..ba41519c 100644 --- a/capa/features/extractors/elf.py +++ b/capa/features/extractors/elf.py @@ -776,6 +776,7 @@ def guess_os_from_needed_dependencies(elf) -> Optional[OS]: def guess_os_from_symtab(elf) -> Optional[OS]: SHT_SYMTAB = 0x2 SHT_STRTAB = 0x3 + strtab_buf = symtab_buf = None for shdr in elf.section_headers: if shdr.type == SHT_STRTAB: From b2ead45ad44b9811984280208c7379cbd0e8ad37 Mon Sep 17 00:00:00 2001 From: Yacine Elhamer Date: Sun, 2 Apr 2023 21:57:22 +0100 Subject: [PATCH 57/79] tests: Add test for sample 2bf18d --- tests/test_os_detection.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/test_os_detection.py b/tests/test_os_detection.py index bdc89686..600213b2 100644 --- a/tests/test_os_detection.py +++ b/tests/test_os_detection.py @@ -20,6 +20,7 @@ def test_elf_sh_notes(): # guess: sh notes: OS.LINUX # guess: linker: None # guess: ABI versions needed: None + # guess: symtab: None # guess: needed dependencies: None path = get_data_path_by_name("2f7f5f") with open(path, "rb") as f: @@ -32,6 +33,7 @@ def test_elf_pt_notes(): # guess: sh notes: OS.LINUX # guess: linker: OS.LINUX # guess: ABI versions needed: OS.LINUX + # guess: symtab: None # guess: needed dependencies: None path = get_data_path_by_name("7351f.elf") with open(path, "rb") as f: @@ -44,6 +46,7 @@ def test_elf_so_needed(): # guess: sh notes: OS.HURD # guess: linker: None # guess: ABI versions needed: OS.HURD + # guess: symtab: None # guess: needed dependencies: OS.HURD path = get_data_path_by_name("b5f052") with open(path, "rb") as f: @@ -56,7 +59,21 @@ def test_elf_abi_version_hurd(): # guess: sh notes: OS.HURD # guess: linker: None # guess: ABI versions needed: OS.HURD + # guess: symtab: None # guess: needed dependencies: None path = get_data_path_by_name("bf7a9c") with open(path, "rb") as f: assert capa.features.extractors.elf.detect_elf_os(f) == "hurd" + + +def test_elf_symbol_table(): + # guess: osabi: None + # guess: ph notes: None + # guess: sh notes: None + # guess: linker: None + # guess: ABI versions needed: None + # guess: symtab: OS.LINUX + # guess: needed dependencies: None + path = get_data_path_by_name("2bf18d") + with open(path, "rb") as f: + assert capa.features.extractors.elf.detect_elf_os(f) == "linux" From 386baec3c5a58440a6b829537c1d67ba44631b3f Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Mon, 3 Apr 2023 08:40:41 +0200 Subject: [PATCH 58/79] elf: hints and formatting --- capa/features/extractors/elf.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/capa/features/extractors/elf.py b/capa/features/extractors/elf.py index ba41519c..95ced885 100644 --- a/capa/features/extractors/elf.py +++ b/capa/features/extractors/elf.py @@ -605,7 +605,7 @@ class SHNote: class SymTab: - def __init__(self, endian: str, bitness: int, symtab_buf: bytes, symtab_entsize:int, symtab_sz: int, strtab_buf: bytes, strtab_sz: int) -> None: + def __init__(self, endian: str, bitness: int, symtab_buf: bytes, symtab_entsize: int, symtab_sz: int, strtab_buf: bytes, strtab_sz: int) -> None: self.symbols = [] self.symnum = int(symtab_sz / symtab_entsize) self.entsize = symtab_entsize @@ -615,7 +615,7 @@ class SymTab: self._parse(endian, bitness, symtab_buf) - def _parse(self, endian: str, bitness: int, symtab_buf) -> None: + def _parse(self, endian: str, bitness: int, symtab_buf: bytes) -> None: """ return the symbol's information in the order specified by sys/elf32.h @@ -858,7 +858,6 @@ def detect_elf_os(f) -> str: elif symtab_guess: ret = symtab_guess - return ret.value if ret is not None else "unknown" From c6b634f3aebb7628620e792ecd559b7c252d5253 Mon Sep 17 00:00:00 2001 From: Capa Bot Date: Mon, 3 Apr 2023 06:41:30 +0000 Subject: [PATCH 59/79] Sync capa-testfiles submodule --- tests/data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/data b/tests/data index 3cbd7768..8e9867c9 160000 --- a/tests/data +++ b/tests/data @@ -1 +1 @@ -Subproject commit 3cbd7768c27fbcc77dc46d8f7bddd16834e352f1 +Subproject commit 8e9867c9949dad2bda6c607b7d09e654346e38e2 From d2307804430df505da32e95f75eb36b76644cc5d Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Mon, 3 Apr 2023 13:00:02 +0200 Subject: [PATCH 60/79] pep8 --- capa/features/extractors/elf.py | 42 ++++++++++++++++--------- capa/features/extractors/ida/helpers.py | 2 +- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/capa/features/extractors/elf.py b/capa/features/extractors/elf.py index 95ced885..5c76fffd 100644 --- a/capa/features/extractors/elf.py +++ b/capa/features/extractors/elf.py @@ -605,11 +605,20 @@ class SHNote: class SymTab: - def __init__(self, endian: str, bitness: int, symtab_buf: bytes, symtab_entsize: int, symtab_sz: int, strtab_buf: bytes, strtab_sz: int) -> None: + def __init__( + self, + endian: str, + bitness: int, + symtab_buf: bytes, + symtab_entsize: int, + symtab_sz: int, + strtab_buf: bytes, + strtab_sz: int, + ) -> None: self.symbols = [] self.symnum = int(symtab_sz / symtab_entsize) self.entsize = symtab_entsize - + self.strings = strtab_buf self.strings_sz = strtab_sz @@ -617,14 +626,18 @@ class SymTab: def _parse(self, endian: str, bitness: int, symtab_buf: bytes) -> None: """ - return the symbol's information in + return the symbol's information in the order specified by sys/elf32.h """ for i in range(self.symnum): if bitness == 32: - name, value, size, info, other, shndx = struct.unpack_from(endian+"IIIBBH", symtab_buf, i*self.entsize) + name, value, size, info, other, shndx = struct.unpack_from( + endian + "IIIBBH", symtab_buf, i * self.entsize + ) elif bitness == 64: - name, info, other, shndx, value, size = struct.unpack_from(endian+"IBBBQQ", symtab_buf, i*self.entsize) + name, info, other, shndx, value, size = struct.unpack_from( + endian + "IBBBQQ", symtab_buf, i * self.entsize + ) self.symbols.append((name, value, size, info, other, shndx)) @@ -780,7 +793,7 @@ def guess_os_from_symtab(elf) -> Optional[OS]: for shdr in elf.section_headers: if shdr.type == SHT_STRTAB: - strtab_buf, strtab_sz= shdr.buf, shdr.size + strtab_buf, strtab_sz = shdr.buf, shdr.size elif shdr.type == SHT_SYMTAB: symtab_buf, symtab_entsize, symtab_sz = shdr.buf, shdr.entsize, shdr.size @@ -789,22 +802,23 @@ def guess_os_from_symtab(elf) -> Optional[OS]: # executable does not contain a symbol table # or the symbol's names are stripped return None - - symtab = SymTab( - elf.endian, elf.bitness, symtab_buf, symtab_entsize, symtab_sz, strtab_buf, strtab_sz - ) + + symtab = SymTab(elf.endian, elf.bitness, symtab_buf, symtab_entsize, symtab_sz, strtab_buf, strtab_sz) keywords = { - OS.LINUX: ['linux', '/linux/',], + OS.LINUX: [ + "linux", + "/linux/", + ], } - + for name, *_ in symtab.get_symbols(): sym_name = symtab.fetch_str(name) for os, hints in keywords.items(): if any(map(lambda x: x in sym_name, hints)): return os - + return None @@ -832,7 +846,7 @@ def detect_elf_os(f) -> str: needed_dependencies_guess = guess_os_from_needed_dependencies(elf) logger.debug("guess: needed dependencies: %s", needed_dependencies_guess) - symtab_guess = guess_os_from_symtab(elf) + symtab_guess = guess_os_from_symtab(elf) logger.debug("guess: pertinent symbol name: %s", symtab_guess) ret = None diff --git a/capa/features/extractors/ida/helpers.py b/capa/features/extractors/ida/helpers.py index daec2152..0279f6fd 100644 --- a/capa/features/extractors/ida/helpers.py +++ b/capa/features/extractors/ida/helpers.py @@ -92,7 +92,7 @@ def get_file_imports() -> Dict[int, Tuple[str, str, int]]: # IDA uses section names for the library of ELF imports, like ".dynsym". # These are not useful to us, we may need to expand this list over time - # TODO: exhaust this list, see #1419 + # TODO: exhaust this list, see #1419 if library == ".dynsym": library = "" From 59332c2e94c07419348e45e63ce04a85630868a5 Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Mon, 3 Apr 2023 13:16:03 +0200 Subject: [PATCH 61/79] tests: fixtures: add paths for new ELF test file --- tests/fixtures.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/fixtures.py b/tests/fixtures.py index f5ac7b30..04c9c53b 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -309,6 +309,8 @@ def get_data_path_by_name(name): return os.path.join(CD, "data", "bf7a9c8bdfa6d47e01ad2b056264acc3fd90cf43fe0ed8deec93ab46b47d76cb.elf_") elif name.startswith("294b8d"): return os.path.join(CD, "data", "294b8db1f2702b60fb2e42fdc50c2cee6a5046112da9a5703a548a4fa50477bc.elf_") + elif name.startswith("2bf18d"): + return os.path.join(CD, "data", "2bf18d0403677378adad9001b1243211.elf_") else: raise ValueError(f"unexpected sample fixture: {name}") @@ -367,6 +369,8 @@ def get_sample_md5_by_name(name): elif name.startswith("294b8d"): # file name is SHA256 hash return "3db3e55b16a7b1b1afb970d5e77c5d98" + elif name.startswith("2bf18d"): + return "2bf18d0403677378adad9001b1243211" else: raise ValueError(f"unexpected sample fixture: {name}") From 3f5d9c79f961457d904b302f0cc517702ab5433a Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Mon, 3 Apr 2023 13:30:02 +0200 Subject: [PATCH 62/79] elf: add type hints and Symbol dataclass --- capa/features/extractors/elf.py | 62 ++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/capa/features/extractors/elf.py b/capa/features/extractors/elf.py index 5c76fffd..5461684c 100644 --- a/capa/features/extractors/elf.py +++ b/capa/features/extractors/elf.py @@ -604,25 +604,36 @@ class SHNote: return ABITag(os, kmajor, kminor, kpatch) +@dataclass +class Symbol: + name_offset: int + value: int + size: int + info: int + other: int + shndx: int + + class SymTab: def __init__( self, endian: str, bitness: int, - symtab_buf: bytes, + symtab_buf: Optional[bytes], symtab_entsize: int, symtab_sz: int, - strtab_buf: bytes, + strtab_buf: Optional[bytes], strtab_sz: int, ) -> None: - self.symbols = [] + self.symbols: List[Symbol] = [] self.symnum = int(symtab_sz / symtab_entsize) self.entsize = symtab_entsize self.strings = strtab_buf self.strings_sz = strtab_sz - self._parse(endian, bitness, symtab_buf) + if symtab_buf: + self._parse(endian, bitness, symtab_buf) def _parse(self, endian: str, bitness: int, symtab_buf: bytes) -> None: """ @@ -631,26 +642,35 @@ class SymTab: """ for i in range(self.symnum): if bitness == 32: - name, value, size, info, other, shndx = struct.unpack_from( + name_offset, value, size, info, other, shndx = struct.unpack_from( endian + "IIIBBH", symtab_buf, i * self.entsize ) elif bitness == 64: - name, info, other, shndx, value, size = struct.unpack_from( + name_offset, info, other, shndx, value, size = struct.unpack_from( endian + "IBBBQQ", symtab_buf, i * self.entsize ) - self.symbols.append((name, value, size, info, other, shndx)) + self.symbols.append(Symbol(name_offset, value, size, info, other, shndx)) - def fetch_str(self, offset) -> str: + def get_name(self, symbol: Symbol) -> str: """ fetch a symbol's name from symtab's associated strings' section (SHT_STRTAB) """ - for i in range(offset, self.strings_sz): - if self.strings[i] == 0: - return self.strings[offset:i].decode() + if not self.strings: + raise ValueError("no strings found") - def get_symbols(self) -> Iterator[Tuple[int, int, int, int, int, int]]: + for i in range(symbol.name_offset, self.strings_sz): + if self.strings[i] == 0: + return self.strings[symbol.name_offset : i].decode("utf-8") + + from rich import print + print(symbol) + import hexdump + hexdump.hexdump(self.strings) + raise ValueError("symbol name not found") + + def get_symbols(self) -> Iterator[Symbol]: """ return a tuple: (name, value, size, info, other, shndx) for each symbol contained in the symbol table @@ -659,11 +679,11 @@ class SymTab: yield symbol -def guess_os_from_osabi(elf) -> Optional[OS]: +def guess_os_from_osabi(elf: ELF) -> Optional[OS]: return elf.ei_osabi -def guess_os_from_ph_notes(elf) -> Optional[OS]: +def guess_os_from_ph_notes(elf: ELF) -> Optional[OS]: # search for PT_NOTE sections that specify an OS # for example, on Linux there is a GNU section with minimum kernel version PT_NOTE = 0x4 @@ -702,7 +722,7 @@ def guess_os_from_ph_notes(elf) -> Optional[OS]: return None -def guess_os_from_sh_notes(elf) -> Optional[OS]: +def guess_os_from_sh_notes(elf: ELF) -> Optional[OS]: # search for notes stored in sections that aren't visible in program headers. # e.g. .note.Linux in Linux kernel modules. SHT_NOTE = 0x7 @@ -735,7 +755,7 @@ def guess_os_from_sh_notes(elf) -> Optional[OS]: return None -def guess_os_from_linker(elf) -> Optional[OS]: +def guess_os_from_linker(elf: ELF) -> Optional[OS]: # search for recognizable dynamic linkers (interpreters) # for example, on linux, we see file paths like: /lib64/ld-linux-x86-64.so.2 linker = elf.linker @@ -745,7 +765,7 @@ def guess_os_from_linker(elf) -> Optional[OS]: return None -def guess_os_from_abi_versions_needed(elf) -> Optional[OS]: +def guess_os_from_abi_versions_needed(elf: ELF) -> Optional[OS]: # then lets look for GLIBC symbol versioning requirements. # this will let us guess about linux/hurd in some cases. @@ -776,7 +796,7 @@ def guess_os_from_abi_versions_needed(elf) -> Optional[OS]: return None -def guess_os_from_needed_dependencies(elf) -> Optional[OS]: +def guess_os_from_needed_dependencies(elf: ELF) -> Optional[OS]: for needed in elf.needed: if needed.startswith("libmachuser.so"): return OS.HURD @@ -786,7 +806,7 @@ def guess_os_from_needed_dependencies(elf) -> Optional[OS]: return None -def guess_os_from_symtab(elf) -> Optional[OS]: +def guess_os_from_symtab(elf: ELF) -> Optional[OS]: SHT_SYMTAB = 0x2 SHT_STRTAB = 0x3 strtab_buf = symtab_buf = None @@ -812,8 +832,8 @@ def guess_os_from_symtab(elf) -> Optional[OS]: ], } - for name, *_ in symtab.get_symbols(): - sym_name = symtab.fetch_str(name) + for symbol in symtab.get_symbols(): + sym_name = symtab.get_name(symbol) for os, hints in keywords.items(): if any(map(lambda x: x in sym_name, hints)): From cbe30199ff2f6dad0159265c9d32d4107b293656 Mon Sep 17 00:00:00 2001 From: Capa Bot Date: Mon, 3 Apr 2023 11:31:24 +0000 Subject: [PATCH 63/79] Sync capa-testfiles submodule --- tests/data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/data b/tests/data index 8e9867c9..9b302d4b 160000 --- a/tests/data +++ b/tests/data @@ -1 +1 @@ -Subproject commit 8e9867c9949dad2bda6c607b7d09e654346e38e2 +Subproject commit 9b302d4bcfea9c87704df51311f6e170b87d13c9 From d2fc7402784d17ccbb70a33c51755347ca9bb0dd Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Mon, 3 Apr 2023 13:44:09 +0200 Subject: [PATCH 64/79] result document: mypy --- capa/render/result_document.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/capa/render/result_document.py b/capa/render/result_document.py index cba62258..2d2d10f4 100644 --- a/capa/render/result_document.py +++ b/capa/render/result_document.py @@ -581,7 +581,7 @@ class ResultDocument(FrozenModel): def to_capa(self) -> Tuple[Dict, Dict]: meta = self.meta.to_capa() - capabilities: Dict[str, List[Tuple[frz.Address, capa.features.common.Result]]] = {} + capabilities: Dict[str, List[Tuple[capa.features.address.Address, capa.features.common.Result]]] = {} for rule_name, rule_match in self.rules.items(): # Parse the YAML source into a Rule instance @@ -604,12 +604,12 @@ class ResultDocument(FrozenModel): result = capa.features.common.Result( statement=statement, success=match.success, - locations=[frz.Address.to_capa(loc) for loc in match.locations], + locations={loc.to_capa() for loc in match.locations}, children=[], ) if rule_name not in capabilities: capabilities[rule_name] = [] - capabilities[rule_name].append((frz.Address.from_capa(addr), result)) + capabilities[rule_name].append((addr.to_capa(), result)) return meta, capabilities From 30c14210edb360fba1825364ee257a2b72292bbf Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Mon, 3 Apr 2023 13:44:19 +0200 Subject: [PATCH 65/79] main: better separate logic for deserializing result/freeze/other --- capa/main.py | 77 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/capa/main.py b/capa/main.py index c033a77f..fa54c4c7 100644 --- a/capa/main.py +++ b/capa/main.py @@ -1181,46 +1181,57 @@ def main(argv=None): if not (args.verbose or args.vverbose or args.json): logger.debug("file limitation short circuit, won't analyze fully.") return E_FILE_LIMITATION + if format_ == FORMAT_RESULT: + # result document directly parses into meta, capabilities result_doc = capa.render.result_document.ResultDocument.parse_file(args.sample) meta, capabilities = result_doc.to_capa() - elif format_ == FORMAT_FREEZE: - with open(args.sample, "rb") as f: - extractor = capa.features.freeze.load(f.read()) + else: - try: - if format_ == FORMAT_PE: - sig_paths = get_signatures(args.signatures) - else: - sig_paths = [] - logger.debug("skipping library code matching: only have native PE signatures") - except IOError as e: - logger.error("%s", str(e)) - return E_INVALID_SIG + # all other formats we must create an extractor + # and use that to extract meta and capabilities - should_save_workspace = os.environ.get("CAPA_SAVE_WORKSPACE") not in ("0", "no", "NO", "n", None) + if format_ == FORMAT_FREEZE: + # freeze format deserializes directly into an extractor + with open(args.sample, "rb") as f: + extractor = capa.features.freeze.load(f.read()) + else: + # all other formats we must create an extractor, + # such as viv, binary ninja, etc. workspaces + # and use those for extracting. - try: - extractor = get_extractor( - args.sample, - format_, - args.os, - args.backend, - sig_paths, - should_save_workspace, - disable_progress=args.quiet, - ) - except UnsupportedFormatError: - log_unsupported_format_error() - return E_INVALID_FILE_TYPE - except UnsupportedArchError: - log_unsupported_arch_error() - return E_INVALID_FILE_ARCH - except UnsupportedOSError: - log_unsupported_os_error() - return E_INVALID_FILE_OS + try: + if format_ == FORMAT_PE: + sig_paths = get_signatures(args.signatures) + else: + sig_paths = [] + logger.debug("skipping library code matching: only have native PE signatures") + except IOError as e: + logger.error("%s", str(e)) + return E_INVALID_SIG + + should_save_workspace = os.environ.get("CAPA_SAVE_WORKSPACE") not in ("0", "no", "NO", "n", None) + + try: + extractor = get_extractor( + args.sample, + format_, + args.os, + args.backend, + sig_paths, + should_save_workspace, + disable_progress=args.quiet, + ) + except UnsupportedFormatError: + log_unsupported_format_error() + return E_INVALID_FILE_TYPE + except UnsupportedArchError: + log_unsupported_arch_error() + return E_INVALID_FILE_ARCH + except UnsupportedOSError: + log_unsupported_os_error() + return E_INVALID_FILE_OS - if format_ != FORMAT_RESULT: meta = collect_metadata(argv, args.sample, args.format, args.os, args.rules, extractor) capabilities, counts = find_capabilities(rules, extractor, disable_progress=args.quiet) From 28e85aa548f1d036cb8e632b17db3e65727fe4b0 Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Mon, 3 Apr 2023 13:48:30 +0200 Subject: [PATCH 66/79] main: mypy --- capa/main.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/capa/main.py b/capa/main.py index fa54c4c7..75979c09 100644 --- a/capa/main.py +++ b/capa/main.py @@ -1182,6 +1182,11 @@ def main(argv=None): logger.debug("file limitation short circuit, won't analyze fully.") return E_FILE_LIMITATION + # TODO: #1411 use a real type, not a dict here. + meta: Dict[str, Any] + capabilities: MatchResults + counts: Dict[str, Any] + if format_ == FORMAT_RESULT: # result document directly parses into meta, capabilities result_doc = capa.render.result_document.ResultDocument.parse_file(args.sample) From 43128404be8def54fb0335147a339ed074918249 Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Mon, 3 Apr 2023 15:04:00 +0200 Subject: [PATCH 67/79] elf: remove old debugging code --- capa/features/extractors/elf.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/capa/features/extractors/elf.py b/capa/features/extractors/elf.py index 5461684c..188ad388 100644 --- a/capa/features/extractors/elf.py +++ b/capa/features/extractors/elf.py @@ -664,10 +664,6 @@ class SymTab: if self.strings[i] == 0: return self.strings[symbol.name_offset : i].decode("utf-8") - from rich import print - print(symbol) - import hexdump - hexdump.hexdump(self.strings) raise ValueError("symbol name not found") def get_symbols(self) -> Iterator[Symbol]: From b09e3e69f2af9ec305ee107698f4ca076c5221dc Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Mon, 3 Apr 2023 15:04:15 +0200 Subject: [PATCH 68/79] wip: result document: deserialize into capa object instances --- capa/render/result_document.py | 117 ++++++++++++++++++++++++++------- 1 file changed, 92 insertions(+), 25 deletions(-) diff --git a/capa/render/result_document.py b/capa/render/result_document.py index 2d2d10f4..2b627cc7 100644 --- a/capa/render/result_document.py +++ b/capa/render/result_document.py @@ -6,6 +6,7 @@ # 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. import datetime +import collections from typing import Any, Dict, List, Tuple, Union, Optional from pydantic import Field, BaseModel @@ -262,6 +263,55 @@ def node_from_capa(node: Union[capa.engine.Statement, capa.engine.Feature]) -> N assert_never(node) +def node_to_capa( + node: Node, children: List[Union[capa.engine.Statement, capa.engine.Feature]] +) -> Union[capa.engine.Statement, capa.engine.Feature]: + if isinstance(node, StatementNode): + if isinstance(node.statement, CompoundStatement): + if node.statement.type == CompoundStatementType.AND: + return capa.engine.And(description=node.statement.description, children=children) + + elif node.statement.type == CompoundStatementType.OR: + return capa.engine.Or(description=node.statement.description, children=children) + + elif node.statement.type == CompoundStatementType.NOT: + return capa.engine.Not(description=node.statement.description, child=children[0]) + + elif node.statement.type == CompoundStatementType.OPTIONAL: + return capa.engine.Some(description=node.statement.description, count=0, children=children) + + else: + assert_never(node.statement.type) + + elif isinstance(node.statement, SomeStatement): + return capa.engine.Some( + description=node.statement.description, count=node.statement.count, children=children + ) + + elif isinstance(node.statement, RangeStatement): + return capa.engine.Range( + description=node.statement.description, + min=node.statement.min, + max=node.statement.max, + child=node.statement.child.to_capa(), + ) + + elif isinstance(node.statement, SubscopeStatement): + raise NotImplementedError("deserializing subscope statements are not supported") + return capa.engine.Subscope( + description=node.statement.description, scope=node.statement.scope, child=children[0] + ) + + else: + assert_never(node.statement) + + elif isinstance(node, FeatureNode): + return node.feature.to_capa() + + else: + assert_never(node) + + class Match(FrozenModel): """ args: @@ -394,6 +444,42 @@ class Match(FrozenModel): captures={capture: tuple(captures[capture]) for capture in captures}, ) + def to_capa(self, rules: RuleSet) -> capa.engine.Result: + children = [child.to_capa(rules) for child in self.children] + statement = node_to_capa(self.node, [child.statement for child in children]) + + if isinstance(self.node, FeatureNode): + feature = self.node.feature + + if isinstance(feature, (frzf.SubstringFeature, frzf.RegexFeature)): + matches = {capture: {loc.to_capa() for loc in locs} for capture, locs in self.captures.items()} + + if isinstance(feature, frzf.SubstringFeature): + assert isinstance(statement, capa.features.common.Substring) + statement = capa.features.common._MatchedSubstring(statement, matches) + elif isinstance(feature, frzf.RegexFeature): + assert isinstance(statement, capa.features.common.Regex) + statement = capa.features.common._MatchedRegex(statement, matches) + else: + assert_never(feature) + + if ( + isinstance(self.node, FeatureNode) + and isinstance(self.node.feature, frzf.MatchFeature) + # only add subtree on success, + # because there won't be results for the other rule on failure. + and self.success + ): + # TODO: work is needed fixup subscope matches here. + raise NotImplementedError("deserializing subscope matches are not yet supported") + + return capa.features.common.Result( + success=self.success, + statement=statement, + locations={loc.to_capa() for loc in self.locations}, + children=children, + ) + def parse_parts_id(s: str): id_ = "" @@ -581,35 +667,16 @@ class ResultDocument(FrozenModel): def to_capa(self) -> Tuple[Dict, Dict]: meta = self.meta.to_capa() - capabilities: Dict[str, List[Tuple[capa.features.address.Address, capa.features.common.Result]]] = {} + capabilities: Dict[ + str, List[Tuple[capa.features.address.Address, capa.features.common.Result]] + ] = collections.defaultdict(list) + + rules = capa.rules.RuleSet([capa.rules.Rule.from_yaml(rule_match.source) for rule_match in self.rules.values()]) for rule_name, rule_match in self.rules.items(): - # Parse the YAML source into a Rule instance - rule = capa.rules.Rule.from_yaml(rule_match.source) - - # Extract the capabilities from the RuleMatches object for addr, match in rule_match.matches: - if isinstance(match.node, StatementNode): - if isinstance(match.node.statement, CompoundStatement): - statement = rule.statement - else: - statement = statement_from_capa(match.node.statement) - elif isinstance(match.node, FeatureNode): - statement = match.node.feature.to_capa() - if isinstance(statement, (capa.features.common.String, capa.features.common.Regex)): - statement.matches = match.captures - else: - raise ValueError("Invalid node type") + result: capa.engine.Result = match.to_capa(rules) - result = capa.features.common.Result( - statement=statement, - success=match.success, - locations={loc.to_capa() for loc in match.locations}, - children=[], - ) - - if rule_name not in capabilities: - capabilities[rule_name] = [] capabilities[rule_name].append((addr.to_capa(), result)) return meta, capabilities From bc8df09be5cf70bb5cd6c6cd8cd8a2b54e640acd Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Mon, 3 Apr 2023 15:27:48 +0200 Subject: [PATCH 69/79] result document: more deserialization --- capa/render/result_document.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/capa/render/result_document.py b/capa/render/result_document.py index 2b627cc7..6254367d 100644 --- a/capa/render/result_document.py +++ b/capa/render/result_document.py @@ -444,8 +444,8 @@ class Match(FrozenModel): captures={capture: tuple(captures[capture]) for capture in captures}, ) - def to_capa(self, rules: RuleSet) -> capa.engine.Result: - children = [child.to_capa(rules) for child in self.children] + def to_capa(self, rules_by_name: Dict[str, capa.rules.Rule]) -> capa.engine.Result: + children = [child.to_capa(rules_by_name) for child in self.children] statement = node_to_capa(self.node, [child.statement for child in children]) if isinstance(self.node, FeatureNode): @@ -463,6 +463,12 @@ class Match(FrozenModel): else: assert_never(feature) + # i'm not sure if we need to fixup match and subscope entries here. + # children contains a single tree of results, corresponding to the logic of the matched rule. + # self.node.feature.match contains the name of the rule that was matched. + # so its all available to reconstruct. but im not sure where this would get used yet. + # probably need to look at the vverbose render emitting result document results. + if ( isinstance(self.node, FeatureNode) and isinstance(self.node.feature, frzf.MatchFeature) @@ -671,11 +677,12 @@ class ResultDocument(FrozenModel): str, List[Tuple[capa.features.address.Address, capa.features.common.Result]] ] = collections.defaultdict(list) - rules = capa.rules.RuleSet([capa.rules.Rule.from_yaml(rule_match.source) for rule_match in self.rules.values()]) + # this doesn't quite work because we don't have the rule source for rules that aren't matched. + rules_by_name = {rule_name: capa.rules.Rule.from_yaml(rule_match.source) for rule_name, rule_match in self.rules.items()} for rule_name, rule_match in self.rules.items(): for addr, match in rule_match.matches: - result: capa.engine.Result = match.to_capa(rules) + result: capa.engine.Result = match.to_capa(rules_by_name) capabilities[rule_name].append((addr.to_capa(), result)) From a64a88981f9685e8055af67385591a51828905b1 Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Mon, 3 Apr 2023 15:35:20 +0200 Subject: [PATCH 70/79] tests: add another test demonstrating rd format output --- tests/test_main.py | 9 +++++++++ tests/test_result_document.py | 8 ++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/tests/test_main.py b/tests/test_main.py index d515c104..d17e6e64 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -467,3 +467,12 @@ def test_main_dotnet4(_039a6_dotnetfile_extractor): # tests successful execution and one rendering path = _039a6_dotnetfile_extractor.path assert capa.main.main([path, "-vv"]) == 0 + + +def test_main_rd(): + path = fixtures.get_data_path_by_name("pma01-01-rd") + assert capa.main.main([path, "-vv"]) == 0 + assert capa.main.main([path, "-v"]) == 0 + assert capa.main.main([path, "-j"]) == 0 + assert capa.main.main([path, "-q"]) == 0 + assert capa.main.main([path]) == 0 diff --git a/tests/test_result_document.py b/tests/test_result_document.py index c329c255..bd074c6b 100644 --- a/tests/test_result_document.py +++ b/tests/test_result_document.py @@ -278,5 +278,9 @@ def test_json_to_rdoc(): def test_rdoc_to_capa(): path = fixtures.get_data_path_by_name("pma01-01-rd") - assert len(rdoc.ResultDocument.parse_file(path).to_capa()) == 2 - assert isinstance(rdoc.ResultDocument.parse_file(path).to_capa(), tuple) + + rd = rdoc.ResultDocument.parse_file(path) + + meta, capabilites = rd.to_capa() + assert isinstance(meta, dict) + assert isinstance(capabilites, dict) From e240372a9075beba143f93fc65f477375c4db94c Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Mon, 3 Apr 2023 15:37:46 +0200 Subject: [PATCH 71/79] result document: document subscope/match handling --- capa/render/result_document.py | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/capa/render/result_document.py b/capa/render/result_document.py index 6254367d..cef49d12 100644 --- a/capa/render/result_document.py +++ b/capa/render/result_document.py @@ -297,7 +297,6 @@ def node_to_capa( ) elif isinstance(node.statement, SubscopeStatement): - raise NotImplementedError("deserializing subscope statements are not supported") return capa.engine.Subscope( description=node.statement.description, scope=node.statement.scope, child=children[0] ) @@ -463,21 +462,12 @@ class Match(FrozenModel): else: assert_never(feature) - # i'm not sure if we need to fixup match and subscope entries here. + # apparently we don't have to fixup match and subscope entries here. + # at least, default, verbose, and vverbose renderers seem to work well without any special handling here. + # # children contains a single tree of results, corresponding to the logic of the matched rule. # self.node.feature.match contains the name of the rule that was matched. - # so its all available to reconstruct. but im not sure where this would get used yet. - # probably need to look at the vverbose render emitting result document results. - - if ( - isinstance(self.node, FeatureNode) - and isinstance(self.node.feature, frzf.MatchFeature) - # only add subtree on success, - # because there won't be results for the other rule on failure. - and self.success - ): - # TODO: work is needed fixup subscope matches here. - raise NotImplementedError("deserializing subscope matches are not yet supported") + # so its all available to reconstruct, if necessary. return capa.features.common.Result( success=self.success, @@ -678,7 +668,9 @@ class ResultDocument(FrozenModel): ] = collections.defaultdict(list) # this doesn't quite work because we don't have the rule source for rules that aren't matched. - rules_by_name = {rule_name: capa.rules.Rule.from_yaml(rule_match.source) for rule_name, rule_match in self.rules.items()} + rules_by_name = { + rule_name: capa.rules.Rule.from_yaml(rule_match.source) for rule_name, rule_match in self.rules.items() + } for rule_name, rule_match in self.rules.items(): for addr, match in rule_match.matches: From 5e0d6176a17e19a0df96bb72eec806038547c1de Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Mon, 3 Apr 2023 16:09:14 +0200 Subject: [PATCH 72/79] elf: parse associated strtab for symtab --- capa/features/extractors/elf.py | 65 +++++++++++++++++---------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/capa/features/extractors/elf.py b/capa/features/extractors/elf.py index 188ad388..fb93b75e 100644 --- a/capa/features/extractors/elf.py +++ b/capa/features/extractors/elf.py @@ -503,6 +503,23 @@ class ELF: yield read_cstr(strtab, d_val) + @property + def symtab(self) -> Optional[Tuple[Shdr, Shdr]]: + """ + fetch the Shdr for the symtab and the associated strtab. + """ + SHT_SYMTAB = 0x2 + for shdr in self.section_headers: + if shdr.type != SHT_SYMTAB: + continue + + # the linked section contains strings referenced by the symtab structures. + strtab_shdr = self.parse_section_header(shdr.link) + + return shdr, strtab_shdr + + return None + @dataclass class ABITag: @@ -619,35 +636,29 @@ class SymTab: self, endian: str, bitness: int, - symtab_buf: Optional[bytes], - symtab_entsize: int, - symtab_sz: int, - strtab_buf: Optional[bytes], - strtab_sz: int, + symtab: Shdr, + strtab: Shdr, ) -> None: self.symbols: List[Symbol] = [] - self.symnum = int(symtab_sz / symtab_entsize) - self.entsize = symtab_entsize - self.strings = strtab_buf - self.strings_sz = strtab_sz + self.symtab = symtab + self.strtab = strtab - if symtab_buf: - self._parse(endian, bitness, symtab_buf) + self._parse(endian, bitness, symtab.buf) def _parse(self, endian: str, bitness: int, symtab_buf: bytes) -> None: """ return the symbol's information in the order specified by sys/elf32.h """ - for i in range(self.symnum): + for i in range(int(len(self.symtab.buf) / self.symtab.entsize)): if bitness == 32: name_offset, value, size, info, other, shndx = struct.unpack_from( - endian + "IIIBBH", symtab_buf, i * self.entsize + endian + "IIIBBH", symtab_buf, i * self.symtab.entsize ) elif bitness == 64: name_offset, info, other, shndx, value, size = struct.unpack_from( - endian + "IBBBQQ", symtab_buf, i * self.entsize + endian + "IBBBQQ", symtab_buf, i * self.symtab.entsize ) self.symbols.append(Symbol(name_offset, value, size, info, other, shndx)) @@ -657,12 +668,12 @@ class SymTab: fetch a symbol's name from symtab's associated strings' section (SHT_STRTAB) """ - if not self.strings: + if not self.strtab: raise ValueError("no strings found") - for i in range(symbol.name_offset, self.strings_sz): - if self.strings[i] == 0: - return self.strings[symbol.name_offset : i].decode("utf-8") + for i in range(symbol.name_offset, self.strtab.size): + if self.strtab.buf[i] == 0: + return self.strtab.buf[symbol.name_offset : i].decode("utf-8") raise ValueError("symbol name not found") @@ -803,23 +814,14 @@ def guess_os_from_needed_dependencies(elf: ELF) -> Optional[OS]: def guess_os_from_symtab(elf: ELF) -> Optional[OS]: - SHT_SYMTAB = 0x2 - SHT_STRTAB = 0x3 - strtab_buf = symtab_buf = None - - for shdr in elf.section_headers: - if shdr.type == SHT_STRTAB: - strtab_buf, strtab_sz = shdr.buf, shdr.size - - elif shdr.type == SHT_SYMTAB: - symtab_buf, symtab_entsize, symtab_sz = shdr.buf, shdr.entsize, shdr.size - - if None in (strtab_buf, symtab_buf): + shdrs = elf.symtab + if not shdrs: # executable does not contain a symbol table # or the symbol's names are stripped return None - symtab = SymTab(elf.endian, elf.bitness, symtab_buf, symtab_entsize, symtab_sz, strtab_buf, strtab_sz) + symtab_shdr, strtab_shdr = shdrs + symtab = SymTab(elf.endian, elf.bitness, symtab_shdr, strtab_shdr) keywords = { OS.LINUX: [ @@ -829,6 +831,7 @@ def guess_os_from_symtab(elf: ELF) -> Optional[OS]: } for symbol in symtab.get_symbols(): + print(symbol) sym_name = symtab.get_name(symbol) for os, hints in keywords.items(): From efcc2e0dd47405fbf4734f641e02471f4b01fcd9 Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Mon, 3 Apr 2023 16:13:28 +0200 Subject: [PATCH 73/79] elf: remove old print statement --- capa/features/extractors/elf.py | 1 - 1 file changed, 1 deletion(-) diff --git a/capa/features/extractors/elf.py b/capa/features/extractors/elf.py index fb93b75e..e0dc596c 100644 --- a/capa/features/extractors/elf.py +++ b/capa/features/extractors/elf.py @@ -831,7 +831,6 @@ def guess_os_from_symtab(elf: ELF) -> Optional[OS]: } for symbol in symtab.get_symbols(): - print(symbol) sym_name = symtab.get_name(symbol) for os, hints in keywords.items(): From d4b83e3f8a03946a1df5ce4e6a2d34dae11d771e Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Mon, 3 Apr 2023 17:39:43 +0200 Subject: [PATCH 74/79] ci: pyinstaller: update to use ubuntu 20.04 for building linux executables --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b294eaf4..23820335 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,7 +15,7 @@ jobs: fail-fast: true matrix: include: - - os: ubuntu-18.04 + - os: ubuntu-20.04 # use old linux so that the shared library versioning is more portable artifact_name: capa asset_name: linux From 545e1982571a6a190eab32aecf0cf49624b7aa8f Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Mon, 3 Apr 2023 17:54:41 +0200 Subject: [PATCH 75/79] ci: bump more ubuntu images --- .github/workflows/build.yml | 7 ++----- .github/workflows/tests.yml | 2 ++ 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 23820335..acd7d807 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -36,7 +36,7 @@ jobs: uses: actions/setup-python@d27e3f3d7c64b4bbf8e4abfb9b63b83e846e0435 # v4.5.0 with: python-version: 3.8 - - if: matrix.os == 'ubuntu-18.04' + - if: matrix.os == 'ubuntu-20.04' run: sudo apt-get install -y libyaml-dev - name: Upgrade pip, setuptools run: python -m pip install --upgrade pip setuptools @@ -65,10 +65,7 @@ jobs: matrix: include: # OSs not already tested above - - os: ubuntu-18.04 - artifact_name: capa - asset_name: linux - - os: ubuntu-20.04 + - os: ubuntu-22.04 artifact_name: capa asset_name: linux - os: windows-2022 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e9701c9e..0bb62c0e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -74,6 +74,8 @@ jobs: python-version: "3.8" - os: ubuntu-20.04 python-version: "3.9" + - os: ubuntu-20.04 + python-version: "3.10" steps: - name: Checkout capa with submodules uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 From 0002b05418a90f2a526af435e743c001dae2ac8f Mon Sep 17 00:00:00 2001 From: Capa Bot Date: Mon, 3 Apr 2023 17:08:37 +0000 Subject: [PATCH 76/79] Sync capa rules submodule --- CHANGELOG.md | 3 ++- README.md | 2 +- rules | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7d6ff5e..31254ffb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ ### Breaking Changes -### New Rules (25) +### New Rules (26) - persistence/scheduled-tasks/schedule-task-via-at joren485 - data-manipulation/prng/generate-random-numbers-via-rtlgenrandom william.ballenthin@mandiant.com @@ -38,6 +38,7 @@ - nursery/destroy-software-breakpoint-capability echernofsky@google.com - nursery/send-data-to-internet michael.hunhoff@mandiant.com - nursery/compiled-with-cx_freeze @mr-tz +- nursery/contain-a-thread-local-storage-tls-section-in-dotnet michael.hunhoff@mandiant.com - ### Bug Fixes diff --git a/README.md b/README.md index a353eeb6..0778cc2b 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/flare-capa)](https://pypi.org/project/flare-capa) [![Last release](https://img.shields.io/github/v/release/mandiant/capa)](https://github.com/mandiant/capa/releases) -[![Number of rules](https://img.shields.io/badge/rules-793-blue.svg)](https://github.com/mandiant/capa-rules) +[![Number of rules](https://img.shields.io/badge/rules-794-blue.svg)](https://github.com/mandiant/capa-rules) [![CI status](https://github.com/mandiant/capa/workflows/CI/badge.svg)](https://github.com/mandiant/capa/actions?query=workflow%3ACI+event%3Apush+branch%3Amaster) [![Downloads](https://img.shields.io/github/downloads/mandiant/capa/total)](https://github.com/mandiant/capa/releases) [![License](https://img.shields.io/badge/license-Apache--2.0-green.svg)](LICENSE.txt) diff --git a/rules b/rules index ae4eb03e..a10ccf3f 160000 --- a/rules +++ b/rules @@ -1 +1 @@ -Subproject commit ae4eb03ec2151b99b414218d6a610b56ca572634 +Subproject commit a10ccf3fd8d2d3b83a36a1f7b3cd08be4b7434f6 From 43f3f31d69a0b9bca56b208e96e9e2bf31cabf19 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Apr 2023 07:39:46 +0000 Subject: [PATCH 77/79] build(deps-dev): bump types-protobuf from 4.22.0.0 to 4.22.0.1 Bumps [types-protobuf](https://github.com/python/typeshed) from 4.22.0.0 to 4.22.0.1. - [Release notes](https://github.com/python/typeshed/releases) - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-protobuf dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 4ff5c246..19202e93 100644 --- a/setup.py +++ b/setup.py @@ -89,7 +89,7 @@ setuptools.setup( "types-termcolor==1.1.4", "types-psutil==5.8.23", "types_requests==2.28.1", - "types-protobuf==4.22.0.0", + "types-protobuf==4.22.0.1", ], "build": [ "pyinstaller==5.9.0", From 04ca770545b2b02bfd0433cb3c289d3af8b04968 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Apr 2023 07:40:03 +0000 Subject: [PATCH 78/79] build(deps-dev): bump black from 23.1.0 to 23.3.0 Bumps [black](https://github.com/psf/black) from 23.1.0 to 23.3.0. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/compare/23.1.0...23.3.0) --- updated-dependencies: - dependency-name: black dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 4ff5c246..82d070d0 100644 --- a/setup.py +++ b/setup.py @@ -74,7 +74,7 @@ setuptools.setup( "pytest-instafail==0.4.2", "pytest-cov==4.0.0", "pycodestyle==2.10.0", - "black==23.1.0", + "black==23.3.0", "isort==5.11.4", "mypy==1.1.1", "psutil==5.9.2", From fe6117e87abac32206a9a54081a39d0313d5ee8d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Apr 2023 07:40:27 +0000 Subject: [PATCH 79/79] build(deps-dev): bump pytest-instafail from 0.4.2 to 0.5.0 Bumps [pytest-instafail](https://github.com/pytest-dev/pytest-instafail) from 0.4.2 to 0.5.0. - [Release notes](https://github.com/pytest-dev/pytest-instafail/releases) - [Changelog](https://github.com/pytest-dev/pytest-instafail/blob/master/CHANGES.rst) - [Commits](https://github.com/pytest-dev/pytest-instafail/compare/v0.4.2...v0.5.0) --- updated-dependencies: - dependency-name: pytest-instafail dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 4ff5c246..0c342549 100644 --- a/setup.py +++ b/setup.py @@ -71,7 +71,7 @@ setuptools.setup( "dev": [ "pytest==7.1.3", "pytest-sugar==0.9.4", - "pytest-instafail==0.4.2", + "pytest-instafail==0.5.0", "pytest-cov==4.0.0", "pycodestyle==2.10.0", "black==23.1.0",