diff --git a/capa/features/extractors/base_extractor.py b/capa/features/extractors/base_extractor.py index 67607458..93115ca4 100644 --- a/capa/features/extractors/base_extractor.py +++ b/capa/features/extractors/base_extractor.py @@ -116,8 +116,6 @@ class StaticFeatureExtractor: # this base class doesn't know what to do with that info, though. # super().__init__() - # all extractors must be able to provide a sample's hashes - self.sample_hashes: SampleHashes @abc.abstractmethod def get_base_address(self) -> Union[AbsoluteVirtualAddress, capa.features.address._NoAddress]: @@ -134,7 +132,7 @@ class StaticFeatureExtractor: """ fetch the hashes for the sample contained within the extractor. """ - return self.sample_hashes + raise NotImplementedError() @abc.abstractmethod def extract_global_features(self) -> Iterator[Tuple[Feature, Address]]: @@ -350,14 +348,12 @@ class DynamicFeatureExtractor: # this base class doesn't know what to do with that info, though. # super().__init__() - # all extractors must be able to provide a samples hashes - self.sample_hashes: SampleHashes def get_sample_hashes(self) -> SampleHashes: """ fetch the hashes for the sample contained within the extractor. """ - return self.sample_hashes + raise NotImplementedError() @abc.abstractmethod def extract_global_features(self) -> Iterator[Tuple[Feature, Address]]: diff --git a/capa/features/extractors/binja/extractor.py b/capa/features/extractors/binja/extractor.py index 76ee4097..9f63aebb 100644 --- a/capa/features/extractors/binja/extractor.py +++ b/capa/features/extractors/binja/extractor.py @@ -40,6 +40,9 @@ class BinjaFeatureExtractor(StaticFeatureExtractor): def get_base_address(self): return AbsoluteVirtualAddress(self.bv.start) + def get_sample_hashes(self) -> SampleHashes: + return self.sample_hashes + def extract_global_features(self): yield from self.global_features diff --git a/capa/features/extractors/cape/extractor.py b/capa/features/extractors/cape/extractor.py index 2e91c7db..881802d4 100644 --- a/capa/features/extractors/cape/extractor.py +++ b/capa/features/extractors/cape/extractor.py @@ -40,6 +40,9 @@ class CapeExtractor(DynamicFeatureExtractor): # value according to the PE header, the actual trace may use a different imagebase return AbsoluteVirtualAddress(self.static["pe"]["imagebase"]) + def get_sample_hashes(self) -> SampleHashes: + return self.sample_hashes + def extract_global_features(self) -> Iterator[Tuple[Feature, Address]]: yield from self.global_features diff --git a/capa/features/extractors/ida/extractor.py b/capa/features/extractors/ida/extractor.py index 7ac8ec4d..99ffe02c 100644 --- a/capa/features/extractors/ida/extractor.py +++ b/capa/features/extractors/ida/extractor.py @@ -42,6 +42,12 @@ class IdaFeatureExtractor(StaticFeatureExtractor): def get_base_address(self): return AbsoluteVirtualAddress(idaapi.get_imagebase()) + def get_sample_hashes(self) -> SampleHashes: + return self.sample_hashes + + def get_sample_hashes(self) -> SampleHashes: + return self.sample_hashes + def extract_global_features(self): yield from self.global_features diff --git a/capa/features/extractors/pefile.py b/capa/features/extractors/pefile.py index 17808e9a..e7913440 100644 --- a/capa/features/extractors/pefile.py +++ b/capa/features/extractors/pefile.py @@ -195,6 +195,9 @@ class PefileFeatureExtractor(StaticFeatureExtractor): def get_base_address(self): return AbsoluteVirtualAddress(self.pe.OPTIONAL_HEADER.ImageBase) + def get_sample_hashes(self) -> SampleHashes: + return self.sample_hashes + def extract_global_features(self): buf = Path(self.path).read_bytes() diff --git a/capa/features/extractors/viv/extractor.py b/capa/features/extractors/viv/extractor.py index fde0f7cc..a4f9c748 100644 --- a/capa/features/extractors/viv/extractor.py +++ b/capa/features/extractors/viv/extractor.py @@ -49,6 +49,9 @@ class VivisectFeatureExtractor(StaticFeatureExtractor): # assume there is only one file loaded into the vw return AbsoluteVirtualAddress(list(self.vw.filemeta.values())[0]["imagebase"]) + def get_sample_hashes(self) -> SampleHashes: + return self.sample_hashes + def extract_global_features(self): yield from self.global_features