Nadim Obeid

52 papers A 1C 7Journal 36Unranked 6
YearRankTypeTitle / Venue / Authors
2026 J jnl
IEEE Access
Hebah I. Abu Kaf, Khair Eddin Sabri, Nadim Obeid
2025 J jnl
IEEE Access
Duha Al-Darras, Bashar Al-Shboul, Nadim Obeid, Rima Mashal
2025 J jnl
Clust. Comput.
Amjad Hudaib, Nadim Obeid, Amjad Albashayreh, Hebah Mosleh, Yahya M. Tashtoush, Georgi V. Hristov
2025 conf
ICIT
Duha Al-Darras, Bashar Al-Shboul, Nadim Obeid
2024 J jnl
Inf.
May Alsaidi, Nadim Obeid, Nailah Al-Madi, Hazem Hiary, Ibrahim Aljarah
2023 J jnl
Informatica (Slovenia)
Wala'a M. AlOmari, Khair Eddin Sabri, Nadim Obeid
2023 J jnl
Comput.
Ahmad Alqatawna, Bilal Abu-Salih, Nadim Obeid, Muder Almiani
2022 J jnl
Multim. Tools Appl.
Sawsan Almahmoud, Bassam Hammo, Bashar Al-Shboul, Nadim Obeid
2021 J jnl
CoRR
Ahmad Hammoudeh, Sara Tedmori, Nadim Obeid
2021 J jnl
IEEE Access
Mais Haj Qasem, Nadim Obeid, Amjad Hudaib, Mohammed Amin Almaiah, Ali Al-Zahrani, Ahmad Al-Khasawneh
2021 J jnl
Inf. Syst.
Bushra Alhijawi, Ghazi Al-Naymat, Nadim Obeid, Arafat Awajan
2020 J jnl
CoRR
Mohammad Fasha, Bassam Hammo, Nadim Obeid, Jabir Widian
2020 J jnl
Int. J. Mach. Learn. Cybern.
Mohammed Eshtay, Hossam Faris, Nadim Obeid
2020 J jnl
Int. J. Commun. Networks Inf. Secur.
Mahmoud Rajallah Asassfeh, Nadim Obeid, Wesam Almobaideen
2020 J jnl
Comput. Biol. Chem.
Hasan Rawashdeh, Shatha Awawdeh, Fatima Shannag, Esraa Henawi, Hossam Faris, Nadim Obeid, Jon Hyett
2020 J jnl
IEEE Access
Sherin Hijazi, Nadim Obeid, Khair Eddin Sabri
2019 J jnl
Int. J. Emerg. Technol. Learn.
Rizik M. H. Al-Sayyed, Wadi' Hijawi, Anwar M. Bashiti, Ibrahim Aljarah, Nadim Obeid, Omar Y. A. Al-Adwan
2019 J jnl
Int. J. Comput. Sci. Eng.
Duaa Elsarraj, Maha Al Qisi, Ali Rodan, Nadim Obeid, Ahmad Abdel-Aziz Sharieh, Hossam Faris
2019 conf
ISSPIT
Sanna Abu Sini, Bassam H. Hammo, Nadim Obeid
2019 J jnl
Int. J. Mach. Learn. Cybern.
Mohammed Eshtay, Hossam Faris, Nadim Obeid
2019 C conf
DATA
Safaa Hriez, Nadim Obeid, Arafat Awajan
2019 C conf
IEA/AIE
Mariam Obeid, Zeinab Obeid, Asma Moubaiddin, Nadim Obeid
2018 J jnl
Appl. Intell.
Asma Moubaiddin, Imad Salah, Nadim Obeid
2018 J jnl
Expert Syst. Appl.
Mohammed Eshtay, Hossam Faris, Nadim Obeid
2018 C conf
IEA/AIE
Asma Mobaiddin, Nadim Obeid
2018 C conf
AICCSA
Samar Al-Saqqa, Nadim Obeid, Arafat Awajan
2018 J jnl
Appl. Soft Comput.
Jaber Alwidian, Bassam H. Hammo, Nadim Obeid
2016 J jnl
Appl. Intell.
Khair Eddin Sabri, Nadim Obeid
2016 J jnl
Int. J. Speech Technol.
Bassam Hammo, Nadim Obeid, Israa Huzayyen
2015 J jnl
Computación y Sistemas
Asma Moubaiddin, Ola Shalbak, Bassam Hammo, Nadim Obeid
2014 J jnl
Computación y Sistemas
Bassam Hammo, Asma Moubaiddin, Nadim Obeid, Tuffaha Abeer
2013 J jnl
Knowl. Inf. Syst.
Asma Moubaiddin, Nadim Obeid
2012 conf
ICCCI (2)
Mahran Al-Zyoud, Imad Salah, Nadim Obeid
2011 conf
ACIIDS Posters
Samih Al-Areqi, Amjad Hudaib, Nadim Obeid
2010 J jnl
Knowl. Inf. Syst.
Nadim Obeid, Raj B. K. N. Rao
2010 ch.
Smart Information and Knowledge Management
Nadim Obeid, Asma Moubaiddin
2009 C conf
ISDA
Nadim Obeid, Asma Moubaiddin
2009 J jnl
Appl. Intell.
Asma Moubaiddin, Nadim Obeid
2008 ch.
New Challenges in Applied Intelligence Technologies
Asma Moubaiddin, Nadim Obeid
2007 conf
ICEIS (5)
Asma Moubaiddin, Nadim Obeid
2005 J jnl
Appl. Intell.
Nadim Obeid
2001 J jnl
Appl. Intell.
Nadim Obeid
2001 J jnl
Comput. Artif. Intell.
Nadim Obeid
2000 J jnl
Knowl. Inf. Syst.
Nadim Obeid
1996 C conf
IEA/AIE
Nadim Obeid
1996 J jnl
Appl. Intell.
Nadim Obeid
1996 J jnl
Comput. Artif. Intell.
Nadim Obeid
1994 C conf
ISI
Nadim Obeid
1992 J jnl
Appl. Intell.
Nadim Obeid
1991 A conf
EACL
Anne N. De Roeck, Richard Ball, Keith Brown, Chris Fox, Marjolein Groefsema, Nadim Obeid, Raymond Turner
1991 J jnl
Artif. Intell. Rev.
Nadim Obeid, Raymond Turner
1989 conf
IEA/AIE (2)
Nadim Obeid
tests/integration/test_pe_extractors.py
← Index tests/integration/test_pe_extractors.py python
"""
Integration tests for PE-specific extractors.
"""
import pytest
from unittest.mock import Mock, patch, MagicMock

pytestmark = [pytest.mark.integration, pytest.mark.pe]


# ============================================================================
# PEFeaturesExtractor Tests
# ============================================================================

class TestPEFeaturesExtractor:
    """Tests for PEFeaturesExtractor class."""

    def test_extract_valid_pe(self, pe_binary_path, mock_logger):
        """Test extracting features from valid PE file."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor
        from redb.models.dataclasses import PE

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEFeaturesExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            assert result is not None
            assert isinstance(result, PE)

    def test_extract_pe_type(self, pe_binary_path, mock_logger):
        """Test PE type detection (DLL, EXE, DRIVER)."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEFeaturesExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            assert result.type in ["DLL", "EXE", "DRIVER"]

    def test_extract_architecture(self, pe_binary_path, mock_logger):
        """Test architecture detection."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEFeaturesExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # Architecture should be detected
            assert result.architecture is not None

    def test_extract_entry_point(self, pe_binary_path, mock_logger):
        """Test entry point extraction."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEFeaturesExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # Entry point should be a hex string
            assert result.entry_point.startswith("0x")

    def test_extract_compilation_time(self, pe_binary_path, mock_logger):
        """Test compilation time extraction."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEFeaturesExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # Compilation time should be an integer timestamp
            assert isinstance(result.compilation_time, int)
            assert result.compilation_time_utc is not None

    def test_extract_dotnet_detection(self, pe_binary_path, mock_logger):
        """Test .NET detection."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEFeaturesExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # Should be True for the test .NET binary
            assert isinstance(result.is_dotnet, bool)
            assert result.is_dotnet is True  # Test file is .NET

    def test_extract_headers(self, pe_binary_path, mock_logger):
        """Test header extraction."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEFeaturesExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            assert result.dos_header is not None
            assert result.nt_header is not None
            assert result.file_header is not None
            assert result.optional_header is not None

    def test_extract_counts(self, pe_binary_path, mock_logger):
        """Test section/import/export counts."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEFeaturesExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            assert isinstance(result.number_of_sections, int)
            assert isinstance(result.number_of_imports, int)
            assert isinstance(result.number_of_exports, int)
            assert isinstance(result.number_of_resources, int)

    def test_extract_rich_header(self, pe_binary_path, mock_logger):
        """Test Rich header extraction."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEFeaturesExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # Rich header may or may not be present
            # If present, should be JSON string
            if result.rich_header_dump is not None:
                assert isinstance(result.rich_header_dump, str)

    def test_extract_version_info(self, pe_binary_path, mock_logger):
        """Test version info extraction."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEFeaturesExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # Version info may or may not be present
            if result.version_info is not None:
                assert isinstance(result.version_info, list)


# ============================================================================
# PEImportExtractor Tests
# ============================================================================

class TestPEImportExtractor:
    """Tests for PEImportExtractor class."""

    def test_extract_imports(self, pe_binary_path, mock_logger):
        """Test import extraction."""
        from redb.extractors.pe_extractors.pe_imports import PEImportExtractor
        from redb.models.dataclasses import PEImport

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEImportExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            if result is not None:
                assert isinstance(result, PEImport)
                assert isinstance(result.pe_imports_total, int)

    def test_extract_import_libraries(self, pe_binary_path, mock_logger):
        """Test import library extraction."""
        from redb.extractors.pe_extractors.pe_imports import PEImportExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEImportExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            if result is not None and result.pe_import_libraryName is not None:
                assert isinstance(result.pe_import_libraryName, list)

    def test_extract_import_functions(self, pe_binary_path, mock_logger):
        """Test import function extraction."""
        from redb.extractors.pe_extractors.pe_imports import PEImportExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEImportExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            if result is not None and result.pe_import_functions is not None:
                assert isinstance(result.pe_import_functions, list)

    def test_prepare_export_clickhouse(self, pe_binary_path, mock_logger):
        """Test ClickHouse export preparation."""
        from redb.extractors.pe_extractors.pe_imports import PEImportExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEImportExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.prepare_export_data("ClickHouseExporter")

            if result is not None:
                data, column_names, column_type_names = result
                assert 'library_name' in column_names
                assert 'function_name' in column_names


# ============================================================================
# PESectionExtractor Tests
# ============================================================================

class TestPESectionExtractor:
    """Tests for PESectionExtractor class."""

    def test_extract_sections(self, pe_binary_path, mock_logger):
        """Test section extraction."""
        from redb.extractors.pe_extractors.pe_sections import PESectionExtractor
        from redb.models.dataclasses import PESection

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PESectionExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            assert result is not None
            assert isinstance(result, list)
            assert len(result) > 0
            assert isinstance(result[0], PESection)

    def test_section_properties(self, pe_binary_path, mock_logger):
        """Test section property extraction."""
        from redb.extractors.pe_extractors.pe_sections import PESectionExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PESectionExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            if result is not None and len(result) > 0:
                section = result[0]
                assert section.section_name is not None
                assert section.section_entropy >= 0
                assert section.section_sha256 is not None
                assert section.section_md5 is not None
                assert section.section_size >= 0

    def test_section_entropy_range(self, pe_binary_path, mock_logger):
        """Test that section entropy is in valid range."""
        from redb.extractors.pe_extractors.pe_sections import PESectionExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PESectionExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            if result is not None:
                for section in result:
                    assert 0 <= section.section_entropy <= 8

    def test_prepare_export_clickhouse(self, pe_binary_path, mock_logger):
        """Test ClickHouse export preparation."""
        from redb.extractors.pe_extractors.pe_sections import PESectionExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PESectionExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.prepare_export_data("ClickHouseExporter")

            if result is not None:
                data, column_names, column_type_names = result
                assert 'section_name' in column_names
                assert 'section_entropy' in column_names
                assert 'section_sha256' in column_names


# ============================================================================
# PEResourceExtractor Tests
# ============================================================================

class TestPEResourceExtractor:
    """Tests for PEResourceExtractor class."""

    def test_extract_resources(self, pe_binary_path, mock_logger):
        """Test resource extraction."""
        from redb.extractors.pe_extractors.pe_resources import PEResourceExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEResourceExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # May be None if no resources
            if result is not None:
                assert isinstance(result, list)

    def test_resource_properties(self, pe_binary_path, mock_logger):
        """Test resource property extraction."""
        from redb.extractors.pe_extractors.pe_resources import PEResourceExtractor
        from redb.models.dataclasses import PEResource

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEResourceExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            if result is not None and len(result) > 0:
                resource = result[0]
                assert isinstance(resource, PEResource)
                assert resource.resource_type is not None


# ============================================================================
# PEOverlayExtractor Tests
# ============================================================================

class TestPEOverlayExtractor:
    """Tests for PEOverlayExtractor class."""

    def test_extract_overlay(self, pe_binary_path, mock_logger):
        """Test overlay extraction."""
        from redb.extractors.pe_extractors.pe_overlay import PEOverlayExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEOverlayExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # May be None if no overlay
            # If present, should have overlay properties
            if result is not None:
                assert hasattr(result, 'overlay_size')

    def test_has_overlay_check(self, pe_binary_path, mock_logger):
        """Test overlay detection."""
        from redb.extractors.pe_extractors.pe_overlay import PEOverlayExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEOverlayExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            has_overlay = extractor._has_overlay()
            assert isinstance(has_overlay, bool)


# ============================================================================
# PESignatureExtractor Tests
# ============================================================================

class TestPESignatureExtractor:
    """Tests for PESignatureExtractor class."""

    def test_extract_signature(self, pe_binary_path, mock_logger):
        """Test signature extraction."""
        from redb.extractors.pe_extractors.pe_signature import PESignatureExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PESignatureExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # May be None if not signed
            # Result type depends on implementation

    def test_is_signed_check(self, pe_binary_path, mock_logger):
        """Test signature detection."""
        from redb.extractors.pe_extractors.pe_signature import PESignatureExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PESignatureExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            is_signed = extractor._is_signed()
            assert isinstance(is_signed, bool)


# ============================================================================
# PEDotNetExtractor Tests
# ============================================================================

class TestPEDotNetExtractor:
    """Tests for PEDotNetExtractor class."""

    def test_extract_dotnet(self, pe_binary_path, mock_logger):
        """Test .NET metadata extraction."""
        from redb.extractors.pe_extractors.pe_dotnet import PEDotNetExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEDotNetExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # The test file is a .NET binary
            if extractor._check_dotnet():
                assert result is not None

    def test_check_dotnet(self, pe_binary_path, mock_logger):
        """Test .NET detection."""
        from redb.extractors.pe_extractors.pe_dotnet import PEDotNetExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEDotNetExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            is_dotnet = extractor._check_dotnet()
            assert isinstance(is_dotnet, bool)
            # Test file should be .NET
            assert is_dotnet is True


# ============================================================================
# PEInconsistencyTestsExtractor Tests
# ============================================================================

class TestPEInconsistencyTestsExtractor:
    """Tests for PEInconsistencyTestsExtractor class."""

    def test_extract_inconsistency_tests(self, pe_binary_path, mock_logger):
        """Test inconsistency tests extraction."""
        from redb.extractors.pe_extractors.pe_inconsistency_tests import PEInconstistencyTestsExtractor as PEInconsistencyTestsExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEInconsistencyTestsExtractor(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # extract() returns True if tests were performed, False otherwise
            # The actual test results are stored in extractor.pe_inconsistency_tests
            # and extractor.dotnet_inconsistency_tests
            assert result in (True, False)

            if result:
                # Check that test results were stored
                assert extractor.pe_inconsistency_tests is not None or extractor.dotnet_inconsistency_tests is not None


# ============================================================================
# PEExtraFindings Tests
# ============================================================================

class TestPEExtraFindings:
    """Tests for PEExtraFindings class."""

    def test_extract_extra_findings(self, pe_binary_path, mock_logger):
        """Test extra findings extraction."""
        from redb.extractors.pe_extractors.pe_extra_findings import PEExtraFindings

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            extractor = PEExtraFindings(pe_binary_path, mock_logger)

            if extractor.pe is None:
                pytest.skip("PE parsing failed")

            result = extractor.extract()

            # May return None or list of findings
            if result is not None:
                assert isinstance(result, list)


# ============================================================================
# Integration Tests
# ============================================================================

class TestPEExtractorIntegration:
    """Integration tests for PE extractors."""

    def test_all_extractors_same_pe_object(self, pe_binary_path, mock_logger, pe_object):
        """Test that extractors can share the same PE object."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor
        from redb.extractors.pe_extractors.pe_imports import PEImportExtractor
        from redb.extractors.pe_extractors.pe_sections import PESectionExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            # Create extractors sharing the same PE object
            features_ext = PEFeaturesExtractor(pe_binary_path, mock_logger, pe=pe_object)
            imports_ext = PEImportExtractor(pe_binary_path, mock_logger, pe=pe_object)
            sections_ext = PESectionExtractor(pe_binary_path, mock_logger, pe=pe_object)

            # All should use the same PE object
            assert features_ext.pe is pe_object
            assert imports_ext.pe is pe_object
            assert sections_ext.pe is pe_object

            # All should extract successfully
            features_result = features_ext.extract()
            imports_result = imports_ext.extract()
            sections_result = sections_ext.extract()

            assert features_result is not None
            # imports and sections may be None if not present

    def test_hash_consistency_across_extractors(self, pe_binary_path, mock_logger):
        """Test that hashes are consistent across all extractors."""
        from redb.extractors.pe_extractors.pe_features import PEFeaturesExtractor
        from redb.extractors.pe_extractors.pe_imports import PEImportExtractor

        with patch('redb.settings.ELASTIC_BINARIES_COLLECTION', 'test'):
            features_ext = PEFeaturesExtractor(pe_binary_path, mock_logger)
            imports_ext = PEImportExtractor(pe_binary_path, mock_logger)

            # Hashes should be the same
            assert features_ext.sha256 == imports_ext.sha256
            assert features_ext.md5 == imports_ext.md5
            assert features_ext.sha1 == imports_ext.sha1