Hadj Batatia

57 papers A 1B 7C 3Misc 6Journal 18Unranked 22
YearRankTypeTitle / Venue / Authors
2025 J jnl
CoRR
Veronica Marsico, Antonio Quintero-Rincón, Hadj Batatia
2025 J jnl
CoRR
Antonio Quintero-Rincón, Nicolas Masino, Veronica Marsico, Hadj Batatia
2025 J jnl
CoRR
Kayvan Karim, Hani Ragab Hassen, Hadj Batatia
2025 J jnl
CoRR
Nripesh Niketan, Hadj Batatia
2021 conf
CIFSD
Antonio Quintero-Rincón, Hadj Batatia
2020 C conf
ICOST
Sana Zorgui, Siwar Chaabene, Bassem Bouaziz, Hadj Batatia, Lotfi Chaâri
2020 B conf
IJCNN
Antonio Quintero-Rincón, Carlos D'Giano, Hadj Batatia
2020 J jnl
Comput.
Antonio Quintero-Rincón, Valeria Muro, Carlos D'Giano, Jorge Prendes, Hadj Batatia
2020 J jnl
IET Image Process.
Adel Kamli, Rachida Saouli, Hadj Batatia, Mostefa Bennaceur, Imane Youkana
2019 J jnl
CoRR
Antonio Quintero-Rincón, Valeria Muro, Carlos D'Giano, Jorge Prendes, Hadj Batatia
2018 conf
EUSIPCO
Lotfi Chaâri, Jean-Yves Tourneret, Hadj Batatia
2017 conf
EUSIPCO
Lotfi Chaâri, Jean-Yves Tourneret, Hadj Batatia
2017 conf
EUSIPCO
Abdelghafour Halimi, Hadj Batatia, Jimmy le Digabel, Gwendal Josse, Jean-Yves Tourneret
2017 J jnl
NeuroImage
Facundo Costa, Hadj Batatia, Thomas Oberlin, Carlos D'Giano, Jean-Yves Tourneret
2017 Misc conf
ICASSP
Yuri Mejia, Henry Arguello, Facundo Costa, Jean-Yves Tourneret, Hadj Batatia
2017 conf
CAMSAP
Abdelghafour Halimi, Hadj Batatia, Jimmy le Digabel, Gwendal Josse, Jean-Yves Tourneret
2016 J jnl
IEEE Trans. Signal Process.
Lotfi Chaâri, Jean-Yves Tourneret, Caroline Chaux, Hadj Batatia
2016 conf
SSP
Facundo Costa, Hadj Batatia, Thomas Oberlin, Jean-Yves Tourneret
2016 conf
ISBI
Andrea Laruelo, Lotfi Chaâri, Soléakhéna Ken, Jean-Yves Tourneret, Hadj Batatia, Anne Laprie
2016 conf
IVMSP
Antonio Quintero-Rincón, Jorge Prendes, Marcelo Pereyra, Hadj Batatia, Marcelo R. Risk
2015 conf
CAMSAP
Facundo Costa, Hadj Batatia, Thomas Oberlin, Jean-Yves Tourneret
2015 J jnl
IEEE Trans. Image Process.
Marcelo Pereyra, Hadj Batatia, Steve McLaughlin
2015 J jnl
IEEE Trans. Biomed. Eng.
Facundo Costa, Hadj Batatia, Lotfi Chaâri, Jean-Yves Tourneret
2014 Misc conf
ICASSP
Lotfi Chaâri, Hadj Batatia, Nicolas Dobigeon, Jean-Yves Tourneret
2014 conf
EUSIPCO
Zacharie Irace, Hadj Batatia
2014 J jnl
IEEE Signal Process. Lett.
Marcelo Pereyra, Nicolas Dobigeon, Hadj Batatia, Jean-Yves Tourneret
2013 J jnl
IEEE Trans. Image Process.
Marcelo Pereyra, Nicolas Dobigeon, Hadj Batatia, Jean-Yves Tourneret
2013 J jnl
IEEE J. Sel. Top. Signal Process.
Marcelo Pereyra, Hadj Batatia, Steve McLaughlin
2013 conf
CAMSAP
Marcelo Pereyra, Hadj Batatia, Steve McLaughlin
2013 conf
EMBC
Andrea Laruelo, Lotfi Chaâri, Hadj Batatia, Soléakhéna Ken, Benjamin Rowland, Anne Laprie, Jean-Yves Tourneret
2013 conf
EUSIPCO
Zacharie Irace, Hadj Batatia
2013 conf
EUSIPCO
Lotfi Chaâri, Jean-Yves Tourneret, Hadj Batatia
2012 conf
ISBI
Meriem Djeddi, Zehor Ouksili, Hadj Batatia
2012 J jnl
IEEE Trans. Medical Imaging
Marcelo Pereyra, Nicolas Dobigeon, Hadj Batatia, Jean-Yves Tourneret
2011 Misc conf
ICASSP
Marcelo Pereyra, Nicolas Dobigeon, Hadj Batatia, Jean-Yves Tourneret
2011 conf
EUSIPCO
Marcelo Pereyra, Nicolas Dobigeon, Hadj Batatia, Jean-Yves Tourneret
2010 B conf
ICIP
Zehor Ouksili, Hadj Batatia
2010 B conf
ICIP
Meriem Djeddi, Abdeldjalil Ouahabi, Hadj Batatia, Adrian Basarab, Denis Kouame
2010 J jnl
Pattern Recognit. Lett.
Clovis Tauber, Hadj Batatia, Alain Ayache
2010 B conf
ICIP
Ali Mcheik, Hadj Batatia
2009 J jnl
J. Signal Process. Syst.
Clovis Tauber, Hadj Batatia, Alain Ayache
2008 conf
VISAPP (1)
Ali Mcheik, Clovis Tauber, Hadj Batatia, Jérôme George, Jean-Michel Lagarde
2007 conf
ISBI
Zehor Ouksili, Clovis Tauber, Julia Nalis, Hadj Batatia, Olivier Caselles, Frederic Courbon
2007 conf
EC-TEL (Posters)
Christophe Piombo, Hadj Batatia, Pascal Dayre, Alain Ayache
2007 B conf
Image Processing
Zehor Ouksili, Clovis Tauber, Julia Nalis, Hadj Batatia, Olivier Caselles, Frederic Courbon
2005 conf
ICIP (2)
Clovis Tauber, Hadj Batatia, Alain Ayache
2005 Misc conf
MVA
Clovis Tauber, Hadj Batatia, Alain Ayache
2005 C conf
IADIS AC
Pascal Dayre, Hadj Batatia
2004 B conf
ICIP
Clovis Tauber, Hadj Batatia, Alain Ayache
2003 B conf
ICALT
Christophe Piombo, Hadj Batatia, Alain Ayache
2003 conf
ICASSP (2)
Donglai Xu, Rui Gao, Hadj Batatia
2003 A conf
ICME
Donglai Xu, Rui Gao, Hadj Batatia
2002 C conf
ICCE
Hadj Batatia, Alain Ayache, Hannu Markkanen
1999 Misc conf
PDPTA
Donglai Xu, Hadj Batatia, Reza Sotudeh
1999 Misc conf
PDPTA
Martin Maierhofer, Christopher Bailey, Hadj Batatia, Reza Sotudeh
1999 J jnl
IEEE Trans. Consumer Electron.
Hadj Batatia, Donglai Xu
1998 conf
EUROMICRO
Michael Weeks, Hadj Batatia, Reza Sotudeh
redb/extractors/macho_extractors/macho_similarity_hashes.py
← Index redb/extractors/macho_extractors/macho_similarity_hashes.py python
import inspect
from datetime import datetime, timezone
from typing import Any

from redb.extractors.enum import Tag
from redb.extractors.macho_extractor import MachOExtractor


class MachOSimilarityHashExtractor(MachOExtractor):
    """Extract Mach-O similarity hashes using machofile API.

    Similarity hashes are MD5 fingerprints of sorted, deduplicated binary components:
    - dylib_hash: MD5 of dynamic library names
    - import_hash: MD5 of imported function names
    - export_hash: MD5 of exported symbol names
    - entitlement_hash: MD5 of entitlement names and array values
    - symhash: MD5 of external undefined symbols

    For FAT binaries:
    - Inserts one row per architecture slice with per-slice hashes
    - Inserts one row for the FAT container with combined hashes

    For single-arch binaries:
    - Inserts one row with that architecture's hashes

    Note: parent_sha256 and architecture relationships are tracked in redb_basic_properties,
    not duplicated here. Use JOIN with redb_basic_properties when needed.
    """

    def __init__(
        self,
        filepath,
        log,
        exporters=None,
        index_prefix=None,
        elastic_index=None,
        known_benign=False,
        known_malicious=False,
        macho=None,
    ):
        super().__init__(
            filepath,
            log,
            exporters,
            index_prefix,
            elastic_index,
            known_benign,
            known_malicious,
            macho,
        )
        self.elastic_index = self.index_prefix + "-macho_hashes"
        self.log.debug(inspect.currentframe().f_code.co_name)

    def tag(self):
        return Tag.MACHO_HASHES.value

    def _extract_similarity_hashes(self, arch_name=None):
        """Extract similarity hashes for a specific architecture."""
        self.log.debug(inspect.currentframe().f_code.co_name)

        if not self.macho:
            return None

        try:
            similarity_hashes = self.macho.get_similarity_hashes(arch=arch_name)
            return similarity_hashes if similarity_hashes else None
        except Exception as e:
            self.log.error(f"Error extracting similarity hashes for arch {arch_name}: {e}")
            return None

    def extract(self):
        self.log.debug(inspect.currentframe().f_code.co_name)
        try:
            if not self.macho:
                return None

            architectures = self.macho.get_architectures()
            if not architectures:
                return None

            if len(architectures) > 1:
                # FAT binary - return combined hashes + per-arch hashes
                results = []

                # First add combined hashes for the FAT container
                all_hashes = self.macho.get_similarity_hashes()
                combined_hashes = all_hashes.get('combined', {}) if all_hashes else {}
                if combined_hashes:
                    combined_hashes['arch_identifier'] = 'fat'
                    results.append(combined_hashes)

                # Then add per-arch hashes
                for arch_name in architectures:
                    hashes = self._extract_similarity_hashes(arch_name)
                    if hashes:
                        hashes['arch_identifier'] = arch_name
                        results.append(hashes)
                return results
            else:
                # Single architecture - return single result
                return self._extract_similarity_hashes(architectures[0])
        except Exception as e:
            self.log.error(f"Error extracting similarity hashes: {e}")
            return None

    def prepare_export_data(self, exporter_type: str) -> Any:
        if exporter_type == "ElasticsearchExporter":
            return self.extract()
        elif exporter_type == "ClickHouseExporter":
            if not self.macho:
                return None

            try:
                architectures = self.macho.get_architectures()
                is_fat = len(architectures) > 1
            except Exception as e:
                self.log.error(f"Could not get architectures: {e}")
                return None

            data = []
            current_time = datetime.now(timezone.utc)

            # For FAT binaries, first insert a row for the container with combined hashes
            if is_fat:
                all_hashes = self.macho.get_similarity_hashes()  # Without arch returns all including 'combined'
                combined_hashes = all_hashes.get('combined', {}) if all_hashes else {}
                if combined_hashes:
                    data.append([
                        self.sha256,                                    # sha256 (FAT container)
                        combined_hashes.get('dylib_hash'),              # dylib_hash
                        combined_hashes.get('import_hash'),             # import_hash
                        combined_hashes.get('export_hash'),             # export_hash
                        combined_hashes.get('entitlement_hash'),        # entitlement_hash
                        combined_hashes.get('symhash'),                 # symhash
                        current_time,                                   # analysis_date
                    ])

            # Insert rows for each architecture slice
            for arch_name in architectures:
                # Get architecture-specific sha256
                try:
                    arch_general_info = self.macho.get_general_info(arch=arch_name)
                    arch_sha256 = arch_general_info.get('SHA256', self.sha256)
                except Exception as e:
                    self.log.warning(f"Could not get arch-specific sha256 for {arch_name}: {e}")
                    arch_sha256 = self.sha256

                # Get similarity hashes for this architecture
                similarity_hashes = self._extract_similarity_hashes(arch_name)
                if not similarity_hashes:
                    continue

                data.append([
                    arch_sha256,                                    # sha256 (arch-specific)
                    similarity_hashes.get('dylib_hash'),            # dylib_hash
                    similarity_hashes.get('import_hash'),           # import_hash
                    similarity_hashes.get('export_hash'),           # export_hash
                    similarity_hashes.get('entitlement_hash'),      # entitlement_hash
                    similarity_hashes.get('symhash'),               # symhash
                    current_time,                                   # analysis_date
                ])

            if not data:
                return None

            column_names = [
                'sha256',
                'macho_dylib_hash', 'macho_import_hash', 'macho_export_hash',
                'macho_entitlement_hash', 'macho_symhash',
                'analysis_date'
            ]

            column_type_names = [
                'FixedString(64)',
                'Nullable(FixedString(32))', 'Nullable(FixedString(32))', 'Nullable(FixedString(32))',
                'Nullable(FixedString(32))', 'Nullable(FixedString(32))',
                'DateTime64(3, \'UTC\')'
            ]

            return (data, column_names, column_type_names)

        return None

    def get_clickhouse_table(self) -> str:
        return "redb_hashes"