Repository: mandiant/capa
File: capa/features/extractors/base_extractor.py (Python)

Code before:
    a sample must implement the sibling extractor, StaticFeatureExtractor.

    Features are grouped mainly into threads that alongside their meta-features are also grouped into
    processes (that also have their own features). Other scopes (such as function and file) may also apply
    for a specific sandbox.

    This class is not instantiated directly; it is the base class for other implementations.
    """

    @abc.abstractmethod
    def get_base_address(self) -> Union[AbsoluteVirtualAddress, capa.features.address._NoAddress]:
        """
        fetch the preferred load address at which the sample was analyzed.
        """
        raise NotImplementedError()

    @abc.abstractmethod
    def extract_global_features(self) -> Iterator[Tuple[Feature, Address]]:
        """
        extract features found at every scope ("global").

        example::

            extractor = VivisectFeatureExtractor(vw, path)
            for feature, va in extractor.get_global_features():
                print('0x%x: %s', va, feature)

        yields:
          Tuple[Feature, Address]: feature and its location
        """
        raise NotImplementedError()

    @abc.abstractmethod
    def extract_file_features(self) -> Iterator[Tuple[Feature, Address]]:
        """
        extract file-scope features.

        example::

            extractor = VivisectFeatureExtractor(vw, path)
            for feature, va in extractor.get_file_features():
                print('0x%x: %s', va, feature)

        yields:
          Tuple[Feature, Address]: feature and its location
        """
        raise NotImplementedError()

    @abc.abstractmethod
    def get_processes(self) -> Iterator[ProcessHandle]:
        """

Review comment (refactor):
```suggestion
            extractor = CapeFeatureExtractor.from_report(json.loads(buf))
            for feature, addr in extractor.get_global_features():
                print(addr, feature)
```

Code after:
    a sample must implement the sibling extractor, StaticFeatureExtractor.

    Features are grouped mainly into threads that alongside their meta-features are also grouped into
    processes (that also have their own features). Other scopes (such as function and file) may also apply
    for a specific sandbox.

    This class is not instantiated directly; it is the base class for other implementations.
    """

    @abc.abstractmethod
    def extract_global_features(self) -> Iterator[Tuple[Feature, Address]]:
        """
        extract features found at every scope ("global").

        example::

            extractor = CapeFeatureExtractor.from_report(json.loads(buf))
            for feature, addr in extractor.get_global_features():
                print(addr, feature)

        yields:
          Tuple[Feature, Address]: feature and its location
        """
        raise NotImplementedError()

    @abc.abstractmethod
    def extract_file_features(self) -> Iterator[Tuple[Feature, Address]]:
        """
        extract file-scope features.

        example::

            extractor = CapeFeatureExtractor.from_report(json.loads(buf))
            for feature, addr in extractor.get_file_features():
                print(addr, feature)

        yields:
          Tuple[Feature, Address]: feature and its location
        """
        raise NotImplementedError()

    @abc.abstractmethod
    def get_processes(self) -> Iterator[ProcessHandle]:
        """
        Enumerate processes in the trace.
        """
        raise NotImplementedError()

    @abc.abstractmethod
    def extract_process_features(self, ph: ProcessHandle) -> Iterator[Tuple[Feature, Address]]:
        """