Rafael Berkvens

102 papers A 2B 5C 8Misc 2Journal 52Unranked 31
YearRankTypeTitle / Venue / Authors
2026 conf
CCNC
Nabeel Nisar Bhat, Maksim Karnaukh, Jakob Struye, Rafael Berkvens, Jeroen Famaey
2026 J jnl
IEEE Access
Ruben Nietvelt, Dennis Joosens, Maarten Weyn, Rafael Berkvens
2026 A conf
MMSys
Javad Sameri, Nabeel Nisar Bhat, Filip De Turck, Rafael Berkvens, Jeroen Famaey, Maria Torres Vega
2026 J jnl
IEEE Open J. Commun. Soc.
Nabeel Nisar Bhat, Siddhartha Kumar, Mohammad Hossein Moghaddam, Jakob Struye, Jesus Omar Lacruz, Jacopo Pegoraro, Joerg Widmer, Rafael Berkvens, Jeroen Famaey
2025 J jnl
IEEE Commun. Mag.
Hamed Farhadi, Bitan Banerjee, Rafael Berkvens, Nabeel Nisar Bhat, Emmanuelle Bodji, Dilin Dampahalage, Eslam Eldeeb, Jeroen Famaey, Gerhard P. Fettweis, Jaeseong Jeong, Dani Korpi, Siddhartha Kumar, Yann Lebrun, Rodolphe Legouable, José Miguel Mateos-Ramos, Nurul Huda Mahmood, Mohammad Hossein Moghaddam, Ahmad Nimr, Nandana Rajatheva, Nuwanthika Rajapaksha, Athanasios Stavridis, Tommy Svensson, Han Yu, Leif Wilhelmsson, Henk Wymeersch
2025 J jnl
CoRR
Nabeel Nisar Bhat, Maksim Karnaukh, Jakob Struye, Rafael Berkvens, Jeroen Famaey
2025 J jnl
IEEE Open J. Commun. Soc.
Henk Wymeersch, Nuutti Tervo, Stefan Wänstedt, Sharief Saleh, Joerg Ahlendorf, Özgür Umut Akgül, Vasileios Tsekenis, Sokratis Barmpounakis, Liping Bai, Martin Beale, Rafael Berkvens, Nabeel Nisar Bhat, Hui Chen, Shrayan Das, Claude Desset, Antonio de la Oliva, Prajnamaya Dass, Jeroen Famaey, Hamed Farhadi, Gerhard P. Fettweis, Yu Ge, Hao Guo, Rreze Halili, Katsuyuki Haneda, Abdur Rahman Mohamed Ismail, Akshay Jain, Sylvaine Kerboeuf, Musa Furkan Keskin, Emad Ibrahim, Bilal Khan, Siddhartha Kumar, Stefan Köpsell, Apostolos Kousaridas, Pekka Kyösti, Simon Lindberg, Mohammad Hossein Moghaddam, Ahmad Nimr, Victor Pettersson, Aarno Pärssinen, Basuki Priyanto, Athanasios Stavridis, Tommy Svensson, Sonika Ujjwal
2025 J jnl
CoRR
Henk Wymeersch, Nuutti Tervo, Stefan Wänstedt, Sharief Saleh, Joerg Ahlendorf, Özgür Umut Akgül, Vasileios Tsekenis, Sokratis Barmpounakis, Liping Bai, Martin Beale, Rafael Berkvens, Nabeel Nisar Bhat, Hui Chen, Shrayan Das, Claude Desset, Antonio de la Oliva, Prajnamaya Dass, Jeroen Famaey, Hamed Farhadi, Gerhard P. Fettweis, Yu Ge, Hao Guo, Rreze Halili, Katsuyuki Haneda, Abdur Rahman Mohamed Ismail, Akshay Jain, Sylvaine Kerboeuf, Musa Furkan Keskin, Emad Ibrahim, Bilal Khan, Siddhartha Kumar, Stefan Köpsell, Apostolos Kousaridas, Pekka Kyösti, Simon Lindberg, Mohammad Hossein Moghaddam, Ahmad Nimr, Victor Pettersson, Aarno Pärssinen, Basuki Priyanto, Athanasios Stavridis, Tommy Svensson, Sonika Ujjwal
2025 J jnl
Data
Robin Janssens, Rafael Berkvens, Ben Bellekens
2025 conf
GoodIT
Thayheng Nhem, Maarten Weyn, Michaël Peeters, Rafael Berkvens
2025 B conf
PIMRC
Thayheng Nhem, Maarten Weyn, Michaël Peeters, Rafael Berkvens
2025 conf
JC&S
Thayheng Nhem, Maarten Weyn, Michaël Peeters, Rafael Berkvens
2025 B conf
WCNC
Thayheng Nhem, Fabian Denoodt, Maarten Weyn, Michaël Peeters, José Oramas, Rafael Berkvens
2025 J jnl
IEEE Access
Jorg Wieme, Ruben Nietvelt, Dries Van Leemput, Maarten Weyn, Pieter Crombez, Rafael Berkvens, Eli De Poorter, Jeroen Hoebeke
2025 J jnl
IEEE Trans. Affect. Comput.
Mohammad Hasan Rahmani, Rafael Berkvens, Maarten Weyn
2025 J jnl
IEEE Open J. Commun. Soc.
Italo Atzeni, Gustavo Rodrigues de Lima Tejerina, Rafael Berkvens, Hui Chen, Jean-Marc Conrat, Mar Francis D. De Guzman, Claude Desset, Meik Dörpinghaus, Hamed Farhadi, Gerhard P. Fettweis, Florian Gast, Hardy Halbauer, Rreze Halili, Katsuyuki Haneda, Ilkka Harjula, Bruno Jahan, Ramin Khayatzadeh, Pekka Kyösti, Rodolphe Legouable, Arto Lehti, Dileepa Marasinghe, Le-Hang Nguyen, Sharief Saleh, Kaan Senparlak, Nuutti Tervo, Oskari Tervo, Henk Wymeersch, Bo Xu, Peize Zhang
2025 J jnl
IEEE Access
Dennis Joosens, Abdil Kaya, Ruben Nietvelt, Maarten Weyn, Rafael Berkvens
2025 J jnl
CoRR
Nabeel Nisar Bhat, Maksim Karnaukh, Stein Vandenbroeke, Wouter Lemoine, Jakob Struye, Jesus Omar Lacruz, Siddhartha Kumar, Mohammad Hossein Moghaddam, Joerg Widmer, Rafael Berkvens, Jeroen Famaey
2024 B conf
PIMRC
Wout Van Uytsel, Thomas Janssen, Maarten Weyn, Rafael Berkvens
2024 conf
JC&S
Nabeel Nisar Bhat, Rafael Berkvens, Jeroen Famaey
2024 J jnl
CoRR
Nabeel Nisar Bhat, Rafael Berkvens, Jeroen Famaey
2024 conf
ANTS
Thayheng Nhem, Maarten Weyn, Michaël Peeters, Rafael Berkvens
2024 J jnl
IEEE Commun. Lett.
Jalal Jalali, Ata Khalili, Hina Tabassum, Rafael Berkvens, Jeroen Famaey, Walid Saad
2024 conf
6GNet
Seppe Van de Poel, Priyesh Pappinisseri Puluckul, Rafael Berkvens, Ritesh Kumar Singh
2024 ed.
ICL-GNSS
Jari Nurmi, Rafael Berkvens, Thomas Janssen, Rreze Halili, Eli De Poorter, Aleksandr Ometov
2024 conf
JC&S
Henk Wymeersch, Sharief Saleh, Ahmad Nimr, Rreze Halili, Rafael Berkvens, Mohammad Hossein Moghaddam, José Miguel Mateos-Ramos, Athanasios Stavridis, Stefan Wänstedt, Sokratis Barmpounakis, Basuki Priyanto, Martin Beale, Jaap van de Beek, Zi Ye, Marvin Manalastas, Apostolos Kousaridas, Gerhard P. Fettweis
2024 J jnl
CoRR
Henk Wymeersch, Sharief Saleh, Ahmad Nimr, Rreze Halili, Rafael Berkvens, Mohammad Hossein Moghaddam, José Miguel Mateos-Ramos, Athanasios Stavridis, Stefan Wänstedt, Sokratis Barmpounakis, Basuki Priyanto, Martin Beale, Jaap van de Beek, Zi Ye, Marvin Manalastas, Apostolos Kousaridas, Gerhard P. Fettweis
2024 J jnl
CoRR
Mohammad Hasan Rahmani, Rafael Berkvens, Maarten Weyn
2023 J jnl
IEEE Internet Things J.
Thomas Janssen, Axel Koppert, Rafael Berkvens, Maarten Weyn
2023 conf
ACIIW
Mohammad Hasan Rahmani, Rafael Berkvens, Maarten Weyn
2023 conf
ICC Workshops
Dennis Joosens, Abdil Kaya, Maarten Weyn, Rafael Berkvens
2023 C conf
WoWMoM
Nabeel Nisar Bhat, Rafael Berkvens, Jeroen Famaey
2023 J jnl
CoRR
Nabeel Nisar Bhat, Rafael Berkvens, Jeroen Famaey
2023 J jnl
IEEE Trans. Veh. Technol.
Jalal Jalali, Ata Khalili, Atefeh Rezaei, Rafael Berkvens, Maarten Weyn, Jeroen Famaey
2023 C conf
IPIN
Ben Van Herbruggen, Stijn Luchie, Rafael Berkvens, Jaron Fontaine, Eli De Poorter
2023 conf
VTC Fall
Jalal Jalali, Ata Khalili, Rafael Berkvens, Jeroen Famaey
2023 conf
PerCom Workshops
Mohammad Hasan Rahmani, Maarten Weyn, Rafael Berkvens
2023 conf
ImmerCom
Nabeel Nisar Bhat, Javad Sameri, Jakob Struye, Maria Torres Vega, Rafael Berkvens, Jeroen Famaey
2023 J jnl
IEEE Trans. Veh. Technol.
Rreze Halili, Faqir Zarrar Yousaf, Nina Slamnik-Krijestorac, Girma M. Yilma, Marco Liebsch, Rafael Berkvens, Maarten Weyn
2023 conf
GLOBECOM (Workshops)
Jalal Jalali, Filip Lemic, Hina Tabassum, Rafael Berkvens, Jeroen Famaey
2022 J jnl
Sensors
Abdil Kaya, Brecht De Beelde, Wout Joseph, Maarten Weyn, Rafael Berkvens
2022 J jnl
Sensors
Ritesh Kumar Singh, Mohammad Hasan Rahmani, Maarten Weyn, Rafael Berkvens
2022 J jnl
IEEE Internet Things Mag.
Michiel Aernouts, Thomas Janssen, Rafael Berkvens, Maarten Weyn
2022 conf
ICL-GNSS (Work in Progress)
Joaquín Torres-Sospedra, Michiel Aernouts, Adriano J. C. Moreira, Rafael Berkvens
2022 conf
3PGCIC
Robin Janssens, Rafael Berkvens, Peter Hellinckx, Stijn Denis
2022 J jnl
ACM Comput. Surv.
Matteo Ridolfi, Abdil Kaya, Rafael Berkvens, Maarten Weyn, Wout Joseph, Eli De Poorter
2022 J jnl
Sensors
Rreze Halili, Noori BniLam, Marwan Yusuf, Emmeric Tanghe, Wout Joseph, Maarten Weyn, Rafael Berkvens
2021 conf
VTC Fall
Jalal Jalali, Abdil Kaya, Maarten Weyn, Rafael Berkvens
2021 J jnl
IEEE Access
Ritesh Kumar Singh, Rafael Berkvens, Maarten Weyn
2021 J jnl
IEEE Access
Noori BniLam, Dennis Joosens, Rafael Berkvens, Jan Steckel, Maarten Weyn
2021 J jnl
IEEE Trans. Instrum. Meas.
Germán Martín Mendoza-Silva, Joaquín Torres-Sospedra, Francesco Potortì, Adriano J. C. Moreira, Stefan Knauth, Rafael Berkvens, Joaquín Huerta
2021 J jnl
Sensors
Mohammad Hasan Rahmani, Rafael Berkvens, Maarten Weyn
2021 J jnl
Sensors
Rreze Halili, Maarten Weyn, Rafael Berkvens
2021 J jnl
IEEE Access
Carlos H. M. de Lima, Didier Belot, Rafael Berkvens, André Bourdoux, Davide Dardari, Maxime Guillaud, Minna Isomursu, Elena Simona Lohan, Yang Miao, André Noll Barreto, Muhammad Reza Kahar Aziz, Jani Saloranta, Tachporn Sanguanpuak, Hadi Sarieddeen, Gonzalo Seco-Granados, Jaakko Suutala, Tommy Svensson, Mikko Valkama, Barend van Liempd, Henk Wymeersch
2021 conf
IPIN-WiP
Roald de Brouwer, Joaquín Torres-Sospedra, Sergio Trilles-Oliver, Rafael Berkvens
2021 J jnl
IEEE Syst. J.
Stijn Denis, Ben Bellekens, Maarten Weyn, Rafael Berkvens
2021 Misc conf
COMSNETS
Abdil Kaya, Maarten Weyn, Rafael Berkvens
2020 J jnl
CoRR
André Bourdoux, André Noll Barreto, Barend van Liempd, Carlos H. M. de Lima, Davide Dardari, Didier Belot, Elena Simona Lohan, Gonzalo Seco-Granados, Hadi Sarieddeen, Henk Wymeersch, Jaakko Suutala, Jani Saloranta, Maxime Guillaud, Minna Isomursu, Mikko Valkama, Muhammad Reza Kahar Aziz, Rafael Berkvens, Tachporn Sanguanpuak, Tommy Svensson, Yang Miao
2020 J jnl
Sensors
Michiel Aernouts, Filip Lemic, Bart Moons, Jeroen Famaey, Jeroen Hoebeke, Maarten Weyn, Rafael Berkvens
2020 conf
ICL-GNSS
Thomas Janssen, Maarten Weyn, Rafael Berkvens
2020 J jnl
Internet Things
Thomas Janssen, Rafael Berkvens, Maarten Weyn
2020 conf
PLANS
Michiel Aernouts, Noori BniLam, Nico Podevijn, David Plets, Wout Joseph, Rafael Berkvens, Maarten Weyn
2020 conf
PLANS
Nico Podevijn, Jens Trogh, Michiel Aernouts, Rafael Berkvens, Luc Martens, Maarten Weyn, Wout Joseph, David Plets
2020 J jnl
Sensors
Thomas Janssen, Noori BniLam, Michiel Aernouts, Rafael Berkvens, Maarten Weyn
2020 J jnl
Sensors
Ritesh Kumar Singh, Priyesh Pappinisseri Puluckul, Rafael Berkvens, Maarten Weyn
2020 Misc conf
COMSNETS
Ritesh Kumar Singh, Rafael Berkvens, Maarten Weyn
2020 J jnl
IEEE Trans. Veh. Technol.
Marwan Yusuf, Emmeric Tanghe, Pierre Laly, Frédéric Challita, Bart Lannoo, Rreze Halili, Rafael Berkvens, Maarten Weyn, Luc Martens, Davy Paul Gaillot, Martine Lienard, Wout Joseph
2020 J jnl
Sensors
Stijn Denis, Ben Bellekens, Abdil Kaya, Rafael Berkvens, Maarten Weyn
2020 J jnl
Data
Abdil Kaya, Stijn Denis, Ben Bellekens, Maarten Weyn, Rafael Berkvens
2020 J jnl
Sensors
Ritesh Kumar Singh, Michiel Aernouts, Mats De Meyer, Maarten Weyn, Rafael Berkvens
2020 B conf
LCN
Rreze Halili, Faqir Zarrar Yousaf, Nina Slamnik-Krijestorac, Girma M. Yilma, Marco Liebsch, Erik de Britto e Silva, Seilendria A. Hadiwardoyo, Rafael Berkvens, Maarten Weyn
2020 J jnl
Sensors
Thomas Janssen, Noori BniLam, Michiel Aernouts, Rafael Berkvens, Maarten Weyn
2020 J jnl
Sensors
Nico Podevijn, Jens Trogh, Michiel Aernouts, Rafael Berkvens, Luc Martens, Maarten Weyn, Wout Joseph, David Plets
2020 J jnl
Sensors
Thomas Janssen, Rafael Berkvens, Maarten Weyn
2020 J jnl
Internet Things
Ritesh Kumar Singh, Rafael Berkvens, Maarten Weyn
2020 J jnl
Internet Things
Michiel Aernouts, Noori BniLam, Rafael Berkvens, Maarten Weyn
2019 J jnl
Sensors
Stijn Denis, Rafael Berkvens, Maarten Weyn
2019 conf
3PGCIC
Thomas Janssen, Rafael Berkvens, Maarten Weyn
2019 conf
IPIN (Short Papers/Work-in-Progress Papers)
Nico Podevijn, David Plets, Michiel Aernouts, Rafael Berkvens, Luc Martens, Maarten Weyn, Wout Joseph
2019 conf
3PGCIC
Rreze Halili, Maarten Weyn, Rafael Berkvens
2019 J jnl
IEEE Access
Filip Lemic, Vlado Handziski, Michiel Aernouts, Thomas Janssen, Rafael Berkvens, Adam Wolisz, Jeroen Famaey
2019 conf
3PGCIC
Michiel Aernouts, Noori BniLam, Rafael Berkvens, Maarten Weyn
2019 conf
3PGCIC
Ritesh Kumar Singh, Rafael Berkvens, Maarten Weyn
2018 conf
WPNC
Michiel Aernouts, Ben Bellekens, Rafael Berkvens, Maarten Weyn
2018 conf
ICL-GNSS
Rafael Berkvens, Frederik Smolders, Ben Bellekens, Michiel Aernouts, Maarten Weyn
2018 conf
3PGCIC
Rafael Berkvens, Ivan Herrera Olivares, Siegfried Mercelis, Lucinda Kirkpatrick, Maarten Weyn
2018 J jnl
IEEE Commun. Mag.
Jeroen Famaey, Rafael Berkvens, Glenn Ergeerts, Eli De Poorter, Floris Van Den Abeele, Tomas Bolckmans, Jeroen Hoebeke, Maarten Weyn
2018 B conf
PIMRC
Stijn Denis, Rafael Berkvens, Ben Bellekens, Maarten Weyn
2018 C conf
IPIN
Thomas Janssen, Michiel Aernouts, Rafael Berkvens, Maarten Weyn
2018 J jnl
Data
Michiel Aernouts, Rafael Berkvens, Koen Van Vlaenderen, Maarten Weyn
2017 J jnl
J. Ambient Intell. Smart Environ.
Joaquín Torres-Sospedra, Adriano J. C. Moreira, Stefan Knauth, Rafael Berkvens, Raúl Montoliu, Oscar Belmonte, Sergio Trilles, Maria João Nicolau, Filipe Meneses, António Costa, Athanasios Koukofikis, Maarten Weyn, Herbert Peremans
2017 C conf
IPIN
Stijn Denis, Rafael Berkvens, Glenn Ergeerts, Maarten Weyn
2017 C conf
IPIN
Rafael Berkvens, Ben Bellekens, Maarten Weyn
2017
Rafael Berkvens
2017 conf
3PGCIC
Rens Baeyens, Rafael Berkvens, Walter Daems, Jean-Pierre Baeyens, Maggy Goossens, Maarten Weyn
2016 C conf
IPIN
Stijn Denis, Rafael Berkvens, Glenn Ergeerts, Ben Bellekens, Maarten Weyn
2016 J jnl
Sensors
Rafael Berkvens, Herbert Peremans, Maarten Weyn
2016 C conf
IPIN
Rafael Berkvens, Maarten Weyn, Herbert Peremans
2015 conf
CSCN
Maarten Weyn, Glenn Ergeerts, Rafael Berkvens, Bartosz Wojciechowski, Yordan Tabakov
2015 conf
3PGCIC
Bart Praats, Rafael Berkvens, Glenn Ergeerts, Maarten Weyn
2015 C conf
IPIN
Rafael Berkvens, Maarten Weyn, Herbert Peremans
2014 A conf
IROS
Rafael Berkvens, Adam Jacobson, Michael Milford, Herbert Peremans, Maarten Weyn
redb/extractors/macho_extractors/macho_features.py
← Index redb/extractors/macho_extractors/macho_features.py python
import inspect
import json
from datetime import datetime, timezone
from typing import Any

from redb.extractors.enum import Tag
from redb.extractors.macho_extractor import MachOExtractor
from redb.models.dataclasses import MachO


class MachOFeaturesExtractor(MachOExtractor):

    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_features"
        self.log.debug(inspect.currentframe().f_code.co_name)

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

    def _extract_macho_features_for_arch(self, arch_name):
        """Extract basic MachO features for a specific architecture."""
        self.log.debug(inspect.currentframe().f_code.co_name)

        if not self.macho:
            return None

        try:
            # Get general info using new API
            general_info = self.macho.get_general_info()
            if not general_info:
                return None

            # Get header info for this specific architecture
            header_raw = self.macho.get_macho_header(arch=arch_name)
            header_formatted = self.macho.get_macho_header(arch=arch_name, formatted=True)

            if not header_raw or not header_formatted:
                return None

            # Get entry point using new API
            entry_point = None
            try:
                entry_point_info = self.macho.get_entry_point(arch=arch_name)
                if entry_point_info:
                    if isinstance(entry_point_info, dict):
                        entry_point = entry_point_info.get('entryoff') or entry_point_info.get('entry_address')
                    else:
                        entry_point = entry_point_info
            except Exception as e:
                self.log.debug(f"No entry point found: {e}")

            # Get UUID using new API
            uuid = None
            try:
                uuid_info = self.macho.get_uuid(arch=arch_name)
                if uuid_info:
                    uuid = str(uuid_info)
            except Exception as e:
                self.log.debug(f"No UUID found: {e}")

            # Get version info using new API with formatting
            version_info = None
            version_info_str = None
            try:
                version_info = self.macho.get_version_info(arch=arch_name)
                version_info_str = self.macho.get_version_info(arch=arch_name, formatted=True)
            except Exception as e:
                self.log.debug(f"No version info found: {e}")

            # Get segments using new API
            segments = self.macho.get_segments(arch=arch_name)
            number_of_segments = len(segments) if segments else 0

            # Get dylib info using new API
            dylib_names = self.macho.get_dylib_names(arch=arch_name)
            number_of_dylibs = len(dylib_names) if dylib_names else 0

            # Count imports using new API
            imported_functions = self.macho.get_imported_functions(arch=arch_name)
            number_of_imports = sum(len(funcs) for funcs in imported_functions.values()) if imported_functions else 0

            # Count exports using new API
            exported_symbols = self.macho.get_exported_symbols(arch=arch_name)
            number_of_exports = sum(len(symbols) for symbols in exported_symbols.values()) if exported_symbols else 0

            # Get unique load command types using new API
            load_commands_set = self.macho.get_load_commands_set(arch=arch_name, formatted=True)
            if isinstance(load_commands_set, set):
                load_commands_set = sorted(list(load_commands_set))

            # Get architectures for listing purposes
            architectures = self.macho.get_architectures()

            # Determine binary properties
            is_64bit = header_raw.get('magic') in [0xFEEDFACF, 0xCFFAEDFE]  # MH_MAGIC_64, MH_CIGAM_64
            is_signed = self._is_signed()
            
            # Create MachO dataclass
            macho_features = MachO(
                # Raw values from new API
                magic=header_raw.get('magic', 0),
                cputype=header_raw.get('cputype', 0),
                cpusubtype=header_raw.get('cpusubtype', 0),
                filetype=header_raw.get('filetype', 0),
                ncmds=header_raw.get('ncmds', 0),
                sizeofcmds=header_raw.get('sizeofcmds', 0),
                flags=header_raw.get('flags', 0),
                architecture=header_raw.get('cputype', 0),  # Use cputype as architecture
                architectures=[arch_info.get('cputype', 0) for arch_info in [self.macho.get_macho_header(arch=arch) for arch in architectures] if arch_info],
                # Human-readable values from formatted API
                magic_str=header_formatted.get('magic', ''),
                cputype_str=header_formatted.get('cputype', ''),
                cpusubtype_str=header_formatted.get('cpusubtype', ''),
                filetype_str=header_formatted.get('filetype', ''),
                flags_str=header_formatted.get('flags', '').split(', ') if header_formatted.get('flags') else [],
                architecture_str=header_formatted.get('cputype', ''),
                architectures_str=[arch_info.get('cputype', '') for arch_info in [self.macho.get_macho_header(arch=arch, formatted=True) for arch in architectures] if arch_info],
                # Additional properties
                is_64bit=is_64bit,
                is_signed=is_signed,
                number_of_load_commands=header_raw.get('ncmds', 0),
                load_commands_set=load_commands_set,
                number_of_segments=number_of_segments,
                number_of_dylibs=number_of_dylibs,
                number_of_imports=number_of_imports,
                number_of_exports=number_of_exports,
                entry_point=entry_point,
                uuid=uuid,
                version_info=version_info,
                version_info_str=version_info_str
            )
            
            return macho_features
            
        except Exception as e:
            self.log.error(f"Error extracting MachO features: {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

            # For FAT binaries, return features for all architectures
            # For single arch, return just the single result
            if len(architectures) > 1:
                # FAT binary - return list of features for each architecture
                results = []
                for arch_name in architectures:
                    features = self._extract_macho_features_for_arch(arch_name)
                    if features:
                        # Add architecture identifier to the result
                        if hasattr(features, '__dict__'):
                            # If it's a dataclass, we can access its dict
                            features.arch_identifier = arch_name
                        results.append(features)
                return results
            else:
                # Single architecture - return single result
                return self._extract_macho_features_for_arch(architectures[0])
        except Exception as e:
            self.log.error(f"Error extracting MachO features: {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

            # Get architectures (macho is already parsed in __init__)
            try:
                architectures = self.macho.get_architectures()
            except Exception as e:
                self.log.error(f"Could not get architectures: {e}")
                return None

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

            # Loop through each architecture (1 for single, multiple for FAT)
            for arch_name in architectures:
                # Extract features for this specific architecture
                macho_features = self._extract_macho_features_for_arch(arch_name)
                if not macho_features:
                    continue

                # 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 hash for {arch_name}: {e}")
                    arch_sha256 = self.sha256

                # Architecture field (kept in features table for ORDER BY)
                architecture = macho_features.cputype    # Raw CPU type value

                data.append([
                    arch_sha256,                          # sha256 (architecture-specific)
                    architecture,                         # architecture (raw CPU type)
                    # Raw values
                    macho_features.magic,                 # magic
                    macho_features.cputype,               # cputype
                    macho_features.cpusubtype,            # cpusubtype
                    macho_features.filetype,              # filetype
                    macho_features.ncmds,                 # ncmds
                    macho_features.sizeofcmds,            # sizeofcmds
                    macho_features.flags,                 # flags
                    # Human-readable values
                    macho_features.magic_str,             # magic_str
                    macho_features.cputype_str,           # cputype_str
                    macho_features.cpusubtype_str,        # cpusubtype_str
                    macho_features.filetype_str,          # filetype_str
                    macho_features.flags_str,             # flags_str
                    # Other fields
                    macho_features.is_64bit,              # is_64bit
                    macho_features.is_signed,             # is_signed
                    macho_features.entry_point if macho_features.entry_point else None,           # entry_point
                    macho_features.uuid if macho_features.uuid else None,  # uuid
                    json.dumps(macho_features.version_info) if macho_features.version_info else "{}",  # version_info
                    json.dumps(macho_features.version_info_str) if macho_features.version_info_str else "{}",  # version_info_str
                    macho_features.load_commands_set,     # load_commands_set
                    macho_features.number_of_segments,    # number_of_segments
                    macho_features.number_of_dylibs,      # number_of_dylibs
                    macho_features.number_of_imports,     # number_of_imports
                    macho_features.number_of_exports,     # number_of_exports
                    current_time,                         # analysis_date
                ])

            column_names = [
                'sha256', 'architecture',
                # Raw values
                'magic', 'cputype', 'cpusubtype', 'filetype', 'ncmds', 'sizeofcmds', 'flags',
                # Human-readable values
                'magic_str', 'cputype_str', 'cpusubtype_str', 'filetype_str', 'flags_str',
                # Other fields
                'is_64bit', 'is_signed',
                'entry_point', 'uuid', 'version_info', 'version_info_str', 'load_commands_set',
                'number_of_segments', 'number_of_dylibs', 'number_of_imports', 'number_of_exports',
                'analysis_date'
            ]

            if not data:
                return None

            column_type_names = [
                'FixedString(64)', 'Nullable(UInt32)',
                # Raw values
                'UInt32', 'UInt32', 'UInt32', 'UInt32', 'UInt32', 'UInt32', 'UInt32',
                # Human-readable values
                'LowCardinality(String)', 'LowCardinality(String)', 'LowCardinality(String)', 'LowCardinality(String)', 'Array(LowCardinality(String))',
                # Other fields
                'UInt8', 'UInt8',
                'Nullable(UInt64)', 'Nullable(String)', 'JSON', 'JSON', 'Array(Nullable(String))',
                'UInt32', 'UInt32', 'UInt32', 'UInt32', 'DateTime64(3, \'UTC\')'
            ]

            return (data, column_names, column_type_names)
        
        return None

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