Venet Osmani

81 papers A* 2C 1Journal 42Unranked 35
YearRankTypeTitle / Venue / Authors
2025 J jnl
CoRR
Nazia Nafis, Inaki Esnaola, Alvaro Martinez-Perez, Maria-Cruz Villa-Uriol, Venet Osmani
2025 J jnl
PLoS Comput. Biol.
Raffaele Marchesi, Nicolo Micheletti, Nicholas I-Hsien Kuo, Sebastiano Barbieri, Giuseppe Jurman, Venet Osmani
2025 J jnl
CoRR
Pawel Pukowski, Venet Osmani
2025 J jnl
CoRR
Md. Naimul Islam Suvon, Shuo Zhou, Prasun C. Tripathi, Wenrui Fan, Samer Alabed, Bishesh Khanal, Venet Osmani, Andrew J. Swift, Chen Chen, Haiping Lu
2024 J jnl
CoRR
Wenrui Fan, Mohammod Naimul Islam Suvon, Shuo Zhou, Xianyuan Liu, Samer Alabed, Venet Osmani, Andrew J. Swift, Chen Chen, Haiping Lu
2024 conf
MICCAI (1)
Mohammod Naimul Islam Suvon, Prasun C. Tripathi, Wenrui Fan, Shuo Zhou, Xianyuan Liu, Samer Alabed, Venet Osmani, Andrew J. Swift, Chen Chen, Haiping Lu
2024 J jnl
CoRR
Md. Naimul Islam Suvon, Prasun C. Tripathi, Wenrui Fan, Shuo Zhou, Xianyuan Liu, Samer Alabed, Venet Osmani, Andrew J. Swift, Chen Chen, Haiping Lu
2023 J jnl
Artif. Intell. Medicine
Seyedmostafa Sheikhalishahi, Anirban Bhattacharyya, Leo Anthony Celi, Venet Osmani
2023 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
André M. Carrington, Douglas G. Manuel, Paul W. Fieguth, Tim Ramsay, Venet Osmani, Bernhard Wernly, Carol Bennett, Steven Hawken, Olivia Magwood, Yusuf Sheikh, Matthew McInnes, Andreas Holzinger
2022 J jnl
BMC Medical Informatics Decis. Mak.
Marco Chierici, Nicolae Puica, Matteo Pozzi, Antonello Capistrano, Marcello Dorian Donzella, Antonio Colangelo, Venet Osmani, Giuseppe Jurman
2022 J jnl
CoRR
Raffaele Marchesi, Nicolo Micheletti, Giuseppe Jurman, Venet Osmani
2022 J jnl
Inf. Process. Manag.
Sergio Muñoz, Carlos Angel Iglesias, Oscar Mayora, Venet Osmani
2021 J jnl
CoRR
André M. Carrington, Douglas G. Manuel, Paul W. Fieguth, Tim Ramsay, Venet Osmani, Bernhard Wernly, Carol Bennett, Steven Hawken, Matthew McInnes, Olivia Magwood, Yusuf Sheikh, Andreas Holzinger
2021 J jnl
BMC Medical Informatics Decis. Mak.
Behrooz Mamandipoor, Fernando Frutos-Vivar, Oscar Peñuelas, Richard Rezar, Konstantinos Raymondos, Alfonso Muriel, Bin Du, Arnaud W. Thille, Fernando Rios, Marco González, Lorenzo del-Sorbo, María Del Carmen Marín, Bruno Valle Pinheiro, Marco Antonio Soares, Nicolas Nin, Salvatore M. Maggiore, Andrew Bersten, Malte Kelm, Raphael Romano Bruno, Pravin Amin, Nahit Cakar, Gee Young Suh, Fekri Abroug, Manuel Jibaja, Dimitros Matamis, Amine Ali Zeggwagh, Yuda Sutherasan, Antonio Anzueto, Bernhard Wernly, Andrés Esteban, Christian Jung, Venet Osmani
2021 J jnl
Int. J. Medical Informatics
Bernhard Wernly, Behrooz Mamandipoor, Philipp Baldia, Christian Jung, Venet Osmani
2021 conf
UbiComp/ISWC Adjunct
Junos Lukan, Larissa Bolliger, Els Clays, Oscar Mayora, Venet Osmani, Mitja Lustrek
2021 J jnl
CoRR
Behrooz Mamandipoor, Wesley Yeung, Louis Agha-Mir-Salim, David J. Stone, Venet Osmani, Leo Anthony Celi
2021 J jnl
IEEE Trans. Mob. Comput.
Alban Maxhuni, Pablo Hernandez-Leal, Eduardo F. Morales, Luis Enrique Sucar, Venet Osmani, Oscar Mayora
2020 conf
MIE
Behrooz Mamandipoor, Mahshid Majd, Monica Moz, Venet Osmani
2020 conf
PervasiveHealth
Aleksandr Talitckii, Anna Anikina, Ekaterina Kovalenko, Oscar Mayora, Venet Osmani, Olga Zimniakova, Maxim Semenov, Ekaterina Bril, Dmitry V. Dylov, Andrey Somov
2019 J jnl
CoRR
Seyedmostafa Sheikhalishahi, Vevake Balaraman, Venet Osmani
2019 J jnl
CoRR
Behrooz Mamandipoor, Mahshid Majd, Monica Moz, Venet Osmani
2019 J jnl
J. Ambient Intell. Humaniz. Comput.
Elias Ruiz, Venet Osmani, Luis Enrique Sucar, Oscar Mayora
2019 J jnl
CoRR
Seyedmostafa Sheikhalishahi, Riccardo Miotto, Joel T. Dudley, Alberto Lavelli, Fabio Rinaldi, Venet Osmani
2018 conf
PervasiveHealth
Venet Osmani, Li Li, Matteo Danieletto, Benjamin S. Glicksberg, Joel Dudley, Oscar Mayora
2018 ed.
PervasiveHealth
Noga Minsky, Venet Osmani
2018 J jnl
CoRR
Venet Osmani, Li Li, Matteo Danieletto, Benjamin S. Glicksberg, Joel Dudley, Oscar Mayora
2018 J jnl
CoRR
Raihana Ferdous, Venet Osmani, Oscar Mayora
2017 conf
PervasiveHealth
Venet Osmani, Stefano Forti, Oscar Mayora, Diego Conforti
2017 J jnl
CoRR
Venet Osmani, Stefano Forti, Oscar Mayora, Diego Conforti
2017 conf
PervasiveHealth
Venet Osmani, Stefano Forti, Oscar Mayora, Diego Conforti
2016 J jnl
IEEE J. Biomed. Health Informatics
Enrique Garcia-Ceja, Venet Osmani, Oscar Mayora
2016 J jnl
Pervasive Mob. Comput.
Alban Maxhuni, Angélica Muñoz-Meléndez, Venet Osmani, Humberto Perez, Oscar Mayora, Eduardo F. Morales
2016 J jnl
J. Biomed. Informatics
Alban Maxhuni, Pablo Hernandez-Leal, Luis Enrique Sucar, Venet Osmani, Eduardo F. Morales, Oscar Mayora
2015 J jnl
CoRR
Enrique Garcia-Ceja, Venet Osmani, Oscar Mayora
2015 J jnl
Pers. Ubiquitous Comput.
Franz Gravenhorst, Venet Osmani, Bert Arnrich, Amir Muaremi
2015 conf
EMBC
Raihana Ferdous, Venet Osmani, Jessica Beltrán-Márquez, Oscar Mayora
2015 J jnl
Pers. Ubiquitous Comput.
Franz Gravenhorst, Amir Muaremi, Jakob E. Bardram, Agnes Grünerbl, Oscar Mayora, Gabriel Wurzer, Mads Frost, Venet Osmani, Bert Arnrich, Paul Lukowicz, Gerhard Tröster
2015 conf
PervasiveHealth
Raihana Ferdous, Venet Osmani, Oscar Mayora
2015 J jnl
IEEE J. Biomed. Health Informatics
Agnes Grünerbl, Amir Muaremi, Venet Osmani, Gernot Bahle, Stefan Ohler, Gerhard Tröster, Oscar Mayora, Christian Haring, Paul Lukowicz
2015 J jnl
CoRR
Venet Osmani, Agnes Grünerbl, Gernot Bahle, Christian Haring, Paul Lukowicz, Oscar Mayora
2015 J jnl
IEEE Pervasive Comput.
Venet Osmani
2015 conf
AmIHEALTH
Pablo Hernandez-Leal, Alban Maxhuni, Luis Enrique Sucar, Venet Osmani, Eduardo F. Morales, Oscar Mayora
2015 J jnl
EAI Endorsed Trans. Pervasive Health Technol.
Asimina Kiourti, Venet Osmani
2014 J jnl
J. Ambient Intell. Humaniz. Comput.
Venet Osmani, Iacopo Carreras, Aleksandar Matic, Piret Saar
2014 conf
MobiHealth
Matthia Sabatelli, Venet Osmani, Oscar Mayora, Agnes Grünerbl, Paul Lukowicz
2014 conf
AmI
Enrique Garcia-Ceja, Venet Osmani, Alban Maxhuni, Oscar Mayora
2014 conf
ICCASA
Oscar Mayora, Venet Osmani
2014 J jnl
Int. J. Handheld Comput. Res.
Oscar Mayora, Mads Frost, Bert Arnrich, Franz Gravenhorst, Agnes Grünerbl, Amir Muaremi, Venet Osmani, Alessandro Puiatti, Nina Reichwaldt, Corinna Scharnweber, Gerhard Tröster
2014 conf
UbiComp Adjunct
Aleksandar Matic, Venet Osmani, Oscar Mayora-Ibarra
2014 conf
PETRA
Jorge Alvarez-Lozano, Venet Osmani, Oscar Mayora-Ibarra, Mads Frost, Jakob E. Bardram, Maria Faurholt-Jepsen, Lars Vedel Kessing
2014 conf
AH
Agnes Grünerbl, Venet Osmani, Gernot Bahle, José C. Carrasco-Jiménez, Stefan Oehler, Oscar Mayora, Christian Haring, Paul Lukowicz
2013 J jnl
CoRR
Andrei Popleteev, Venet Osmani, Oscar Mayora
2013 J jnl
Pers. Ubiquitous Comput.
Bert Arnrich, Venet Osmani, Jakob E. Bardram
2013 C conf
MoMM
Venet Osmani, Alban Maxhuni, Agnes Grünerbl, Paul Lukowicz, Christian Haring, Oscar Mayora
2013 conf
PervasiveHealth
Mary Czerwinski, Oscar Mayora, Paul Lukowicz, Andrew Campbell, Venet Osmani
2013 J jnl
IEEE Commun. Mag.
Aleksandar Matic, Venet Osmani, Oscar Mayora
2013 conf
UbiComp (Adjunct Publication)
Aleksandar Matic, Alban Maxhuni, Venet Osmani, Oscar Mayora
2012 conf
HEALTHINF
Aleksandar Matic, Venet Osmani, Andrei Popleteev, Oscar Mayora-Ibarra
2012 J jnl
Mob. Networks Appl.
Aleksandar Matic, Venet Osmani, Oscar Mayora-Ibarra
2012 conf
PerCom Workshops
Iacopo Carreras, Aleksandar Matic, Piret Saar, Venet Osmani
2012 A* conf
PerCom
Andrei Popleteev, Venet Osmani, Oscar Mayora
2012 conf
PervasiveHealth
Andrei Popleteev, Venet Osmani, Rosa Maimone, Silvia Gabrielli, Oscar Mayora
2012 conf
PervasiveHealth
Aleksandar Matic, Venet Osmani, Alban Maxhuni, Oscar Mayora
2012 conf
EMBC
Aleksandar Matic, Venet Osmani, Oscar Mayora
2011 conf
PervasiveHealth
Alban Maxhuni, Aleksandar Matic, Venet Osmani, Oscar Mayora-Ibarra
2011 conf
CONTEXT
Andrei Popleteev, Venet Osmani, Oscar Mayora, Aleksandar Matic
2011 conf
AMBI-SYS
Aleksandar Matic, Venet Osmani, Oscar Mayora
2011 conf
CONTEXT
Aleksandar Matic, Venet Osmani, Andrei Popleteev, Oscar Mayora-Ibarra
2010 conf
PervasiveHealth
Aleksandar Matic, Priyal Mehta, James M. Rehg, Venet Osmani, Oscar Mayora
2010 J jnl
Pervasive Mob. Comput.
Aleksandar Matic, Andrei Popleteev, Venet Osmani, Oscar Mayora-Ibarra
2010 J jnl
Int. J. Handheld Comput. Res.
Andrei Papliatseyeu, Venet Osmani, Oscar Mayora
2010 A* conf
PerCom
Aleksandar Matic, Andrei Papliatseyeu, Venet Osmani, Oscar Mayora-Ibarra
2010 conf
UbiComp (Adjunct Papers)
Bert Arnrich, Venet Osmani, Giuseppe Riva, Jakob E. Bardram
2009 conf
MOBILWARE
Andrei Papliatseyeu, Niko Kotilainen, Oscar Mayora, Venet Osmani
2009 conf
PervasiveHealth
Venet Osmani, Daqing Zhang, Sasitharan Balasubramaniam
2009 conf
PervasiveHealth
Aleksandar Matic, Venet Osmani
2008 J jnl
J. Netw. Comput. Appl.
Venet Osmani, Sasitharan Balasubramaniam, Dmitri Botvich
2007 conf
VTC Fall
Venet Osmani, Sasitharan Balasubramaniam, Dmitri Botvich
2007 conf
BODYNETS
Venet Osmani, Sasitharan Balasubramaniam, Dmitri Botvich
2006 conf
MMNS
Venet Osmani, Sasitharan Balasubramaniam, Tao Gu
redb/extractors/pe_extractors/pe_features.py
← Index redb/extractors/pe_extractors/pe_features.py python
import base64
import inspect
import json
from pprint import pprint
import re

import pefile

from redb.ext.rich_header import get_rich_idVersion
from redb.extractors.enum import Tag
from redb.extractors.pe_extractor import PEExtractor
from redb.extractors.pe_extractors.pe_dotnet import PEDotNetExtractor
from redb.models.dataclasses import PE
from datetime import datetime, timezone
from typing import Any


class PEFeaturesExtractor(PEExtractor):

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

    def _extract_type(self):
        self.log.debug(inspect.currentframe().f_code.co_name)
        if self.pe.is_dll():
            return "DLL"
        elif self.pe.is_driver():
            return "DRIVER"
        elif self.pe.is_exe():
            return "EXE"

    def _extract_architecture(self):
        self.log.debug(inspect.currentframe().f_code.co_name)
        mt = {"0x14c": "x86", "0x0200": "Itanium", "0x8664": "x64"}
        machine_value = self.pe.FILE_HEADER.Machine
        if isinstance(machine_value, int):
            return mt.get(str(hex(machine_value)), "")
        return str(machine_value) + " => Not x86/64 or Itanium"

    def _extract_rich_header(self):
        """Extract the Rich header from the PE file

        to decode it back from base64, use:
        rh_tmp = json.loads(rh_b64_string)
        rh_decoded = {}
        for k in rh_tmp:
            if isinstance(rh_tmp[k], str):
                rh_decoded[k] = base64.b64decode(rh_tmp[k])
            else:
                rh_decoded[k] = rh_tmp[k]
        """
        self.log.debug(inspect.currentframe().f_code.co_name)
        rh = self.pe.parse_rich_header()
        rich_header_b64 = {}
        rich_header_infos = []
        if rh:
            for key in rh:
                if isinstance(rh[key], bytes):
                    rich_header_b64[key] = base64.b64encode(rh[key]).decode("utf-8")
                else:
                    rich_header_b64[key] = rh[key]
            rich_header_infos = self._get_rich_header_infos(rh)
        return json.dumps(rich_header_b64) if rich_header_b64 else None, "\n".join(
            item for item in rich_header_infos
        ) if rich_header_infos else None

    def _get_rich_header_infos(self, rh):
        """Parse Rich header information from the PE Rich Header dump"""
        self.log.debug(inspect.currentframe().f_code.co_name)

        rich_header_infos = []
        try:
            # Get list of @Comp.IDs and counts from Rich header
            # Elements in rich_fields at even indices are @Comp.IDs
            # Elements in rich_fields at odd indices are counts
            # example:                  'values': [8681481,
            #                             1,
            #                             9795593,
            #                             1]
            rich_fields = rh.get("values", [])
            if len(rich_fields) % 2 != 0:
                self.log.info(f"rich header extraction stopped for {self.hash.sha256}")
                return None

            comp_id = None
            for i in rich_fields:
                if rich_fields.index(i) % 2 == 0:
                    # even -> save value
                    comp_id = get_rich_idVersion(i)
                else:
                    # odd -> add to list
                    if comp_id:
                        rich_header_infos.append(f"{comp_id} count={i}")
                        comp_id = None
        except Exception as e:
            self.log.error(
                f"Extract rich header error {self.hash.sha256} Exception: {e}"
            )
        return rich_header_infos

    def _extract_version_info(self):
        """Extract the VS_VERSIONINFO field in a PE file

        Returns:
        vsinfo: a list of "key:value" strings from VS_INFORMATION content.
               None if no VS_INFORMATION content is present.
        """
        self.log.debug(inspect.currentframe().f_code.co_name)
        version_info = []
        try:
            if hasattr(self.pe, "VS_VERSIONINFO") and hasattr(self.pe, "FileInfo"):
                for finfo in self.pe.FileInfo:
                    for entry in finfo:
                        if hasattr(entry, "StringTable"):
                            for st_entry in entry.StringTable:
                                for key, str_entry in list(st_entry.entries.items()):
                                    version_info.append(f"{key.decode()}:{str_entry.decode()}")
        except Exception as e:
            self.log.error(
                f"Extract VersionInfo error {self.hash.sha256}  Exception: {e}"
            )
        return version_info if version_info else None

    def _extract_exports(self):
        """
        Returns:
        export_library_name: a str representing the name of the export library.
                            An empty string if no export library is present.
        exp_symbols_list: a list of function names exported as per DIRECTORY_ENTRY_EXPORT.symbols
                            An empty list if no export library is present.
        export_timestamp: a timestamp representing the time of the export.
        """
        self.log.debug(inspect.currentframe().f_code.co_name)
        export_symbols_list = []
        export_library_name = ""
        export_library_name_raw = ""
        export_timestamp = None
        try:
            if hasattr(self.pe, "DIRECTORY_ENTRY_EXPORT"):
                export_timestamp = self.pe.DIRECTORY_ENTRY_EXPORT.struct.TimeDateStamp
                export_directory = self.pe.DIRECTORY_ENTRY_EXPORT
                export_library_name_rva = export_directory.struct.Name
                try:
                    export_library_name = self.remove_non_utf8(
                        self.pe.get_string_at_rva(export_library_name_rva)
                    ).decode()
                    export_library_name_raw = self.pe.get_string_at_rva(
                        export_library_name_rva
                    ).__str__()
                except Exception as e:
                    self.log.error(
                        f"Error while getting export library name {self.pe.get_string_at_rva(export_library_name_rva)} for file: {self.hash.sha256} {e}"
                    )
                    export_library_name = "REDB_ERROR"
                if hasattr(self.pe.DIRECTORY_ENTRY_EXPORT, "symbols"):
                    for exp in self.pe.DIRECTORY_ENTRY_EXPORT.symbols:
                        export_symbols_list.append(
                            exp.name.decode() if exp.name else None
                        )
        except Exception as e:
            self.log.error(f"Extract exports error {self.hash.sha256} Exception: {e}")

        return (
            export_library_name if export_library_name else None,
            export_library_name_raw if export_library_name_raw else None,
            export_symbols_list if export_symbols_list else None,
            export_timestamp if export_timestamp else None,
        )

    def _extract_dbg_info(self):
        """Extract debug information from PE if present

        At the moment this function parses only the DEBUG_ENTRY Structure where Type
        field == 1, i.e. IMAGE_DEBUG_TYPE_CODEVIEW, where the pdb is eventually present.

        Returns:
        debug_entry: the dump of pe.DIRECTORY_ENTRY_DEBUG.struct only for the type 1
                    "IMAGE_DEBUG_TYPE_CODEVIEW". "None" if not present.
        debug_time: a int representing the epoch timestamp as present in the
                    DIRECTORY_ENTRY_DEBUG. "None" if not present.
        pdb_info: a str with the pdb path. "None" if not present.
        """
        self.log.debug(inspect.currentframe().f_code.co_name)
        dbg_timestamp = None
        dbg_timestamp_utc = ""
        dbg_pdb_info = ""
        dbg_pdb_info_raw = ""
        dbg_struct = ""
        try:
            if hasattr(self.pe, "DIRECTORY_ENTRY_DEBUG"):
                for debug_entry in self.pe.DIRECTORY_ENTRY_DEBUG:
                    if (
                        debug_entry.struct.Type
                        == pefile.DEBUG_TYPE["IMAGE_DEBUG_TYPE_CODEVIEW"]
                    ):
                        dbg_timestamp = debug_entry.struct.TimeDateStamp
                        dbg_timestamp_utc = datetime.fromtimestamp(
                            dbg_timestamp, timezone.utc
                        ).strftime("%Y-%m-%d %H:%M:%S")
                        # dbg_struct = base64.b64encode(debug_entry.entry).decode()
                        dbg_struct = debug_entry.entry.__str__()
                        if hasattr(debug_entry.entry, "PdbFileName"):
                            dbg_pdb_info = self.remove_non_utf8(
                                debug_entry.entry.PdbFileName.rstrip(b"\x00")
                            ).decode()
                            dbg_pdb_info_raw = debug_entry.entry.PdbFileName.rstrip(
                                b"\x00"
                            ).__str__()
                            # if dbg_pdb_info:
                            #     dbg_pdb_info = dbg_pdb_info.rstrip(b"\x00")
                            #     dbg_pdb_info = dbg_pdb_info.decode()

        except Exception as e:
            self.log.error(f"Extract DBG info error {self.hash.sha256} Exception: {e}")
        return (
            dbg_timestamp if dbg_timestamp else None,
            dbg_timestamp_utc if dbg_timestamp_utc else None,
            dbg_pdb_info if dbg_pdb_info else None,
            dbg_pdb_info_raw if dbg_pdb_info_raw else None,
            dbg_struct if dbg_struct else None,
        )

    def _extract_tls_info(self):
        """Check for the presence of Thread Local Storage and related extract
        callback addresses.

        Taken from the original version of PEScanner, as the python3 porting
        "ext_pescanner" does not have it.

        Returns:
        pe.DIRECTORY_ENTRY_TLS.struct: a pefile.Structure type containing the dump
                    of the TLS structure and content. "None" is no TLS is present.
        callbacks: a list containing the TLS callbacks addresse. Empty list if no
                    address is found, "None" is no TLS is present.
        """
        self.log.debug(inspect.currentframe().f_code.co_name)
        callbacks = []
        tls_dir_struct = ""
        try:
            if (
                hasattr(self.pe, "DIRECTORY_ENTRY_TLS")
                and self.pe.DIRECTORY_ENTRY_TLS
                and self.pe.DIRECTORY_ENTRY_TLS.struct
                and self.pe.DIRECTORY_ENTRY_TLS.struct.AddressOfCallBacks
            ):
                # tls_dir_struct = base64.b64encode(self.pe.DIRECTORY_ENTRY_TLS.struct).decode()
                tls_dir_struct = self.pe.DIRECTORY_ENTRY_TLS.struct.__str__()
                callback_array_rva = (
                    self.pe.DIRECTORY_ENTRY_TLS.struct.AddressOfCallBacks
                    - self.pe.OPTIONAL_HEADER.ImageBase
                )
                # Originally it was while True
                # todo while can't be used cause risky
                # what maximum range makes sense to add here?
                for idx in range(10000):
                    func = self.pe.get_dword_from_data(
                        self.pe.get_data(callback_array_rva + 4 * idx, 4), 0
                    )
                    if func == 0:
                        break
                    callbacks.append(func)
        except Exception as e:
            self.log.error(f"Extract TLS error {self.hash.sha256} Exception: {e}")
        return callbacks if callbacks else None, tls_dir_struct if tls_dir_struct else None

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

    def extract(self):
        try:
            self.log.debug(inspect.currentframe().f_code.co_name)
            (
                export_library_name,
                export_library_name_raw,
                export_symbols_list,
                export_timestamp,
            ) = self._extract_exports()
            (
                dbg_timestamp,
                dbg_timestamp_utc,
                dbg_pdb_info,
                dbg_pdb_info_raw,
                dbg_struct,
            ) = self._extract_dbg_info()
            tls_callbacks, tls_struct = self._extract_tls_info()
            rich_header_dump, rich_header_parsed = self._extract_rich_header()

            is_dotnet = self._check_dotnet()

            number_of_resources = 0
            number_of_imports = 0
            if hasattr(self.pe, "DIRECTORY_ENTRY_RESOURCE"):
                number_of_resources = len(self.pe.DIRECTORY_ENTRY_RESOURCE.entries)
            if hasattr(self.pe, "DIRECTORY_ENTRY_IMPORT"):
                number_of_imports = len(self.pe.DIRECTORY_ENTRY_IMPORT)

            self.pe_features = PE(
                type=self._extract_type(),
                magic=hex(self.pe.OPTIONAL_HEADER.Magic),
                entry_point=hex(self.pe.OPTIONAL_HEADER.AddressOfEntryPoint),
                major_linker_version=self.pe.OPTIONAL_HEADER.MajorLinkerVersion,
                minor_linker_version=self.pe.OPTIONAL_HEADER.MinorLinkerVersion,
                target_machine=self.pe.FILE_HEADER.Machine,
                architecture=self._extract_architecture(),
                compilation_time=self.pe.FILE_HEADER.TimeDateStamp,
                compilation_time_utc=datetime.fromtimestamp(
                    self.pe.FILE_HEADER.TimeDateStamp, timezone.utc
                ).strftime("%Y-%m-%d %H:%M:%S"),
                rich_header_dump=rich_header_dump,
                rich_header_parsed=rich_header_parsed,
                dos_header=self.pe.DOS_HEADER.__str__(),
                nt_header=self.pe.NT_HEADERS.__str__(),
                optional_header=self.pe.OPTIONAL_HEADER.__str__(),
                file_header=self.pe.FILE_HEADER.__str__(),
                version_info=self._extract_version_info(),
                export_library_name=export_library_name,
                export_library_name_raw=export_library_name_raw,
                export_symbols_list=export_symbols_list,
                export_timestamp=export_timestamp,
                is_dotnet=is_dotnet,
                dbg_timestamp=dbg_timestamp,
                dbg_timestamp_utc=dbg_timestamp_utc,
                dbg_pdb_info=dbg_pdb_info,
                dbg_pdb_info_raw=dbg_pdb_info_raw,
                dbg_struct=dbg_struct,
                tls_callbacks=tls_callbacks,
                tls_struct=tls_struct,
                is_signed=self._is_signed(),
                has_overlay=self._has_overlay(),
                number_of_sections=len(self.pe.sections),
                number_of_imports=number_of_imports,
                number_of_exports=(
                    len(export_symbols_list) if export_symbols_list else 0
                ),
                number_of_resources=number_of_resources,
            )
            return self.pe_features
        except Exception as e:
            self.log.error(f"Error extracting PE features {self.hash.sha256}: {e}")
            return None

    def prepare_export_data(self, exporter_type: str) -> Any:
        self.log.debug(inspect.currentframe().f_code.co_name)
        if exporter_type == "ElasticsearchExporter":
            return self.pe_features
        elif exporter_type == "ClickHouseExporter":
            try:
                pe_dump = self.pe.dump_dict()   
                # Convert PE headers directly to JSON
                dos_header_raw = json.dumps(pe_dump['DOS_HEADER'])
                nt_header_raw = json.dumps(pe_dump['NT_HEADERS'])
                optional_header_raw = json.dumps(pe_dump['OPTIONAL_HEADER'])
                file_header_raw = json.dumps(pe_dump['FILE_HEADER'])

                # Convert magic and entry_point from hex strings to integers
                magic_raw = int(self.pe_features.magic, 16) if isinstance(self.pe_features.magic, str) else self.pe_features.magic
                entry_point = int(self.pe_features.entry_point, 16) if isinstance(self.pe_features.entry_point, str) else self.pe_features.entry_point

                # Convert target_machine to string if it's an integer
                target_machine = str(self.pe_features.target_machine) if isinstance(self.pe_features.target_machine, int) else self.pe_features.target_machine

                # debug struct
                dbg_struct_raw = {}
                if self.pe_features.dbg_struct:
                    if hasattr(self.pe, "DIRECTORY_ENTRY_DEBUG"):
                        for debug_entry in self.pe.DIRECTORY_ENTRY_DEBUG:
                            if (
                                debug_entry.struct.Type
                                == pefile.DEBUG_TYPE["IMAGE_DEBUG_TYPE_CODEVIEW"]
                            ):
                                dbg_struct_raw = json.dumps(debug_entry.struct.__dict__)

                # tls struct
                tls_struct_raw = {}
                if self.pe_features.tls_struct:
                    if (
                        hasattr(self.pe, "DIRECTORY_ENTRY_TLS")
                        and self.pe.DIRECTORY_ENTRY_TLS
                        and self.pe.DIRECTORY_ENTRY_TLS.struct
                        and self.pe.DIRECTORY_ENTRY_TLS.struct.AddressOfCallBacks
                    ):
                        tls_struct_raw = json.dumps(self.pe.DIRECTORY_ENTRY_TLS.struct.__dict__)

                # Ensure arrays are properly initialized
                rich_header_parsed = []
                if self.pe_features.rich_header_parsed:
                    if isinstance(self.pe_features.rich_header_parsed, str):
                        rich_header_parsed = [x for x in self.pe_features.rich_header_parsed.split("\n") if x]
                    elif isinstance(self.pe_features.rich_header_parsed, list):
                        rich_header_parsed = self.pe_features.rich_header_parsed

                version_info = self.pe_features.version_info if self.pe_features.version_info else []
                version_info_raw = {}
                if version_info:
                    for finfo in self.pe.FileInfo:
                        for entry in finfo:
                            if hasattr(entry, "StringTable"):
                                for st_entry in entry.StringTable:
                                    for key, str_entry in list(st_entry.entries.items()):
                                        version_info_raw[key.decode()] = str_entry.decode()
                version_info_raw = json.dumps(version_info_raw) if version_info_raw else "{}"

                export_symbols_list = self.pe_features.export_symbols_list if self.pe_features.export_symbols_list else []
                tls_callbacks = self.pe_features.tls_callbacks if self.pe_features.tls_callbacks else []

                # Prepare data array
                data = [[
                    self.sha256,
                    self.md5,
                    self.sha1,
                    self.pe_features.dos_header,
                    dos_header_raw,
                    self.pe_features.nt_header,
                    nt_header_raw,
                    self.pe_features.optional_header,
                    optional_header_raw,
                    self.pe_features.file_header,
                    file_header_raw,
                    magic_raw,
                    entry_point,
                    self.pe_features.major_linker_version,
                    self.pe_features.minor_linker_version,
                    target_machine,
                    self.pe_features.architecture,
                    self.pe_features.compilation_time,
                    1 if self.pe_features.is_dotnet else 0,
                    1 if self.pe_features.is_signed else 0,
                    1 if self.pe_features.has_overlay else 0,
                    self.pe_features.number_of_sections,
                    self.pe_features.number_of_imports,
                    self.pe_features.number_of_exports,
                    self.pe_features.number_of_resources,
                    self.pe_features.type,
                    self.pe_features.dbg_struct,
                    dbg_struct_raw,
                    self.pe_features.dbg_timestamp,
                    self.pe_features.dbg_pdb_info,
                    self.pe_features.dbg_pdb_info_raw,
                    self.pe_features.tls_struct,
                    tls_struct_raw,
                    self.pe_features.export_timestamp,
                    self.pe_features.export_library_name,
                    self.pe_features.export_library_name_raw,
                    self.pe_features.rich_header_dump if self.pe_features.rich_header_dump else "{}",
                    rich_header_parsed,
                    version_info,
                    version_info_raw,
                    export_symbols_list,
                    tls_callbacks,
                    datetime.now(timezone.utc)
                ]]

                column_names = [
                    'sha256', 'md5', 'sha1',
                    'dos_header', 'dos_header_raw', 'nt_header', 'nt_header_raw', 'optional_header', 'optional_header_raw', 'file_header', 'file_header_raw',
                    'magic_raw', 'entry_point',
                    'major_linker_version', 'minor_linker_version',
                    'target_machine', 'architecture',
                    'compilation_time',
                    'is_dotnet', 'is_signed', 'has_overlay',
                    'number_of_sections', 'number_of_imports', 'number_of_exports', 'number_of_resources',
                    'type',
                    'dbg_struct', 'dbg_struct_raw', 'dbg_timestamp', 'dbg_pdb_info', 'dbg_pdb_info_raw',
                    'tls_struct', 'tls_struct_raw', 'export_timestamp', 'export_library_name', 'export_library_name_raw',
                    'rich_header_dump', 'rich_header_parsed', 'version_info', 'version_info_raw',
                    'export_symbols_list', 'tls_callbacks',
                    'analysis_date'
                ]

                column_type_names = [
                    'FixedString(64)', 'FixedString(32)', 'FixedString(40)',
                    'String', 'JSON', 'String', 'JSON', 'String', 'JSON', 'String', 'JSON',
                    'UInt16', 'UInt32',
                    'UInt8', 'UInt8',
                    'LowCardinality(String)', 'Enum8(\'x86\' = 1, \'Itanium\' = 2, \'x64\' = 3)',
                    'UInt64',
                    'UInt8', 'UInt8', 'UInt8',
                    'UInt16', 'UInt16', 'UInt16', 'UInt16',
                    'Enum8(\'DLL\' = 1, \'EXE\' = 2, \'DRIVER\' = 3)',
                    'Nullable(String)', 'JSON', 'Nullable(UInt64)', 'Nullable(String)', 'Nullable(String)',
                    'Nullable(String)', 'JSON', 'Nullable(UInt64)', 'Nullable(String)', 'Nullable(String)',
                    'JSON', 'Array(Nullable(String))', 'Array(Nullable(String))', 'JSON',
                    'Array(Nullable(String))', 'Array(Nullable(UInt64))',
                    'DateTime64(3, \'UTC\')'
                ]

                if not data:
                    return None

                return (data, column_names, column_type_names)
            except Exception as e:
                self.log.error(f"Error preparing export data: {e}")
                raise

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