Ioana Banicescu

94 papers A 11B 2C 20Misc 3Journal 30Unranked 25
YearRankTypeTitle / Venue / Authors
2025 J jnl
ACM Comput. Surv.
Ioana Banicescu, Trisha Chakraborty, Seth Gilbert, Maxwell Young
2024 J jnl
CoRR
Ioana Banicescu, Trisha Chakraborty, Seth Gilbert, Maxwell Young
2024 J jnl
CoRR
Jesse Ables, Nathaniel Childers, William Anderson, Sudip Mittal, Shahram Rahimi, Ioana Banicescu, Maria Seale
2024 conf
CIC
Jesse Ables, Thomas Kirby, William Anderson, Sudip Mittal, Shahram Rahimi, Ioana Banicescu, Maria Seale, Thomas Arnold, Joseph Jabour
2023 J jnl
CoRR
Jesse Ables, Thomas Kirby, Sudip Mittal, Ioana Banicescu, Shahram Rahimi, William Anderson, Maria Seale
2023 B conf
COMPSAC
Patrick Day, Stefano Iannucci, Ioana Banicescu
2022 conf
SSCI
Jesse Ables, Thomas Kirby, William Anderson, Sudip Mittal, Shahram Rahimi, Ioana Banicescu, Maria Seale
2022 J jnl
CoRR
Jesse Ables, Thomas Kirby, William Anderson, Sudip Mittal, Shahram Rahimi, Ioana Banicescu, Maria Seale
2022 J jnl
CoRR
William Anderson, Kaneesha Moore, Jesse Ables, Sudip Mittal, Shahram Rahimi, Ioana Banicescu, Maria Seale
2022 J jnl
IEEE Access
Subash Neupane, Jesse Ables, William Anderson, Sudip Mittal, Shahram Rahimi, Ioana Banicescu, Maria Seale
2022 J jnl
CoRR
Subash Neupane, Jesse Ables, William Anderson, Sudip Mittal, Shahram Rahimi, Ioana Banicescu, Maria Seale
2022 C conf
ISPDC
William S. Sanders, Srishti Srivastava, Ioana Banicescu
2021 conf
SSCI
Stefano Iannucci, Jesse Ables, William Anderson, Bhuvanesh Abburi, Valeria Cardellini, Ioana Banicescu
2020 J jnl
Future Gener. Comput. Syst.
Stefano Iannucci, Valeria Cardellini, Ovidiu Daniel Barba, Ioana Banicescu
2020 conf
ICCS (2)
Srishti Srivastava, Ioana Banicescu, William S. Sanders
2020 J jnl
Future Gener. Comput. Syst.
Ali Mohammed, Ahmed Eleliemy, Florina M. Ciorba, Franziska Kasielke, Ioana Banicescu
2020 J jnl
Future Gener. Comput. Syst.
Patrick Day, Stefano Iannucci, Ioana Banicescu
2020 C conf
ISPDC
William S. Sanders, Srishti Srivastava, Ioana Banicescu
2020 conf
PP
Ali Mohammed, Aurélien Cavelan, Florina M. Ciorba, Rubén M. Cabezón, Ioana Banicescu
2019 conf
IPDPS Workshops
William S. Sanders, Srishti Srivastava, Ioana Banicescu
2019 conf
FAS*W@SASO/ICAC
Stefano Iannucci, Ovidiu Daniel Barba, Valeria Cardellini, Ioana Banicescu
2019 J jnl
CoRR
Ali Mohammed, Ahmed Eleliemy, Florina M. Ciorba, Franziska Kasielke, Ioana Banicescu
2019 C conf
ISPDC
Franziska Kasielke, Ronny Tschüter, Christian Iwainsky, Markus Velten, Florina M. Ciorba, Ioana Banicescu
2019 conf
IPDPS Workshops
Ioana Banicescu, Peter Strazdins, Eric Aubanel, Raphaël Couturier, Suzanne Michelle Shontz, Thomas Rauber, Gudula Rünger, Laurence T. Yang
2019 J jnl
CoRR
Ali Mohammed, Aurélien Cavelan, Florina M. Ciorba, Rubén M. Cabezón, Ioana Banicescu
2018 C conf
ISPDC
Ali Mohammed, Ahmed Eleliemy, Florina M. Ciorba, Franziska Kasielke, Ioana Banicescu
2018 J jnl
CoRR
Ali Mohammed, Ahmed Eleliemy, Florina M. Ciorba, Franziska Kasielke, Ioana Banicescu
2018 C conf
ISPDC
Srishti Srivastava, Ioana Banicescu
2018 ch.
Topics in Parallel and Distributed Computing
Srishti Srivastava, Ioana Banicescu
2017 C conf
CLUSTER
Stefano Iannucci, Hisham A. Kholidy, Amrita Dhakal Ghimire, Rui Jia, Sherif Abdelwahed, Ioana Banicescu
2017 C conf
ISPDC
Anthony Boulmier, Ioana Banicescu, Florina M. Ciorba, Nabil Abdennadher
2017 conf
IPDPS Workshops
Franziska Hoffeins, Florina M. Ciorba, Ioana Banicescu
2017 J jnl
J. Parallel Distributed Comput.
Sushil K. Prasad, Ioana Banicescu, Martina Barnas, Domingo Giménez, Andrew Lumsdaine
2017 J jnl
Concurr. Comput. Pract. Exp.
Srishti Srivastava, Ioana Banicescu
2017 C conf
ISPDC
Franziska Hoffeins, Florina M. Ciorba, Ioana Banicescu
2016 ch.
Resource Management for Big Data Platforms
Nitin Sukhija, Alessandro Morari, Ioana Banicescu
2016 J jnl
Future Gener. Comput. Syst.
Rajat Mehrotra, Srishti Srivastava, Ioana Banicescu, Sherif Abdelwahed
2015 ch.
Handbook on Data Centers
Rajat Mehrotra, Ioana Banicescu, Srishti Srivastava, Sherif Abdelwahed
2015 C conf
ISPDC
Nitin Sukhija, Ioana Banicescu, Florina M. Ciorba
2015 conf
CSE
Srishti Srivastava, Ioana Banicescu
2014 conf
ARMS-CC@PODC
Rajat Mehrotra, Srishti Srivastava, Ioana Banicescu, Sherif Abdelwahed
2014 conf
IPDPS Workshops
Nitin Sukhija, Brandon M. Malone, Srishti Srivastava, Ioana Banicescu, Florina M. Ciorba
2014 C conf
ISPDC
Mahadevan Balasubramaniam, Ioana Banicescu, Florina M. Ciorba
2014 conf
ICPP Workshops
Mahadevan Balasubramaniam, Ioana Banicescu, Florina M. Ciorba
2013 C conf
ISPDC
Mahadevan Balasubramaniam, Ioana Banicescu, Florina M. Ciorba
2013 conf
IPDPS Workshops
Nitin Sukhija, Ioana Banicescu, Srishti Srivastava, Florina M. Ciorba
2013 C conf
ISPDC
Srishti Srivastava, Brandon M. Malone, Nitin Sukhija, Ioana Banicescu, Florina M. Ciorba
2013 B conf
ICPP
Mahadevan Balasubramaniam, Ioana Banicescu, Florina M. Ciorba
2012 conf
IPDPS Workshops
Florina M. Ciorba, Timothy M. Hansen, Srishti Srivastava, Ioana Banicescu, Anthony A. Maciejewski, Howard Jay Siegel
2012 conf
IPDPS Workshops
Rajat Mehrotra, Ioana Banicescu, Srishti Srivastava
2012 C conf
ISPDC
Srishti Srivastava, Nitin Sukhija, Ioana Banicescu, Florina M. Ciorba
2012 conf
IPDPS Workshops
Mahadevan Balasubramaniam, Nitin Sukhija, Florina M. Ciorba, Ioana Banicescu, Srishti Srivastava
2011 J jnl
J. Supercomput.
Ioana Banicescu, Hyeona Lim, Ricolindo Cariño, Seongjai Kim
2011 C conf
ISPDC
Srishti Srivastava, Ioana Banicescu, Florina M. Ciorba, Wolfgang E. Nagel
2011 J jnl
J. Comput. Appl. Math.
Ioana Banicescu, Ricolindo Cariño, Jane L. Harvill, John Patrick Lestrade
2010 conf
IPDPS Workshops
Srishti Srivastava, Ioana Banicescu, Florina M. Ciorba
2009 A conf
IPDPS
Philip J. Vardon, Ioana Banicescu, Peter John Cleall, Hywel R. Thomas, Roger N. Philp
2009 C conf
ISPDC
Ioana Banicescu, Florina M. Ciorba, Ricolindo Cariño
2008 J jnl
J. Supercomput.
Ricolindo Cariño, Ioana Banicescu
2008 C conf
ISPDC
Mahbubur Rashid, Ioana Banicescu, Ricolindo Cariño
2008 conf
IGARSS (2)
He Yang, Qian Du, Wei Zhu, Ioana Banicescu, James E. Fowler
2008 A conf
IPDPS
Rohit Chaube, Ioana Banicescu, Ricolindo Cariño
2007 J jnl
Scalable Comput. Pract. Exp.
Ricolindo Cariño, Ioana Banicescu
2007 C conf
ISPDC
Rohit Chaube, Ricolindo Cariño, Ioana Banicescu
2006 C conf
ISPDC
Ricolindo Cariño, Ioana Banicescu
2006 Misc conf
International Conference on Computational Science (2)
Ricolindo Cariño, Ioana Banicescu, Wenzhong Gao
2006 A conf
IPDPS
Ricolindo Cariño, Ioana Banicescu, Hyeona Lim, Neil Williams, Seongjai Kim
2005 C conf
CLUSTER
Ricolindo Cariño, Ioana Banicescu
2005 J jnl
Clust. Comput.
Ricolindo Cariño, Ioana Banicescu
2005 conf
CLADE
S. Dhandayuthapani, Ioana Banicescu, Ricolindo Cariño, E. Hansen, Jaderick P. Pabico, Mahbubur Rashid
2005 Misc conf
International Conference on Computational Science (1)
Ioana Banicescu, Ricolindo Cariño, Jane L. Harvill, John Patrick Lestrade
2005 J jnl
Parallel Comput.
Ioana Banicescu, Ricolindo Cariño, Jaderick P. Pabico, Mahadevan Balasubramaniam
2005 J jnl
Clust. Comput.
Ray Bair, Ioana Banicescu, Manish Parashar
2005 A conf
IPDPS
Ioana Banicescu, Ricolindo Cariño, Jaderick P. Pabico, Mahadevan Balasubramaniam
2005 J jnl
Parallel Process. Lett.
Ricolindo Cariño, Ioana Banicescu, Ravi K. Vadapalli, Charles A. Weatherford, Jianping Zhu
2005 J jnl
Int. J. Comput. Sci. Eng.
Ioana Banicescu, Ricolindo Cariño, Jaderick P. Pabico, Mahadevan Balasubramaniam
2005 C conf
CLUSTER
Ricolindo Cariño, Ioana Banicescu, Jaderick P. Pabico, Mahbubur Rashid
2005 A conf
IPDPS
Ioana Banicescu, Ricolindo Cariño, Jane L. Harvill, John Patrick Lestrade
2005 J jnl
Sci. Program.
Ioana Banicescu, Ricolindo Cariño, Jane L. Harvill, John Patrick Lestrade
2004 conf
ISPDC/HeteroPar
Mahadevan Balasubramaniam, Kevin J. Barker, Ioana Banicescu, Nikos Chrisochoides, Jaderick P. Pabico, Ricolindo Cariño
2004 conf
PDCS
Ricolindo Cariño, Ioana Banicescu, Thomas Rauber, Gudula Rünger
2003 conf
CLADE
Ricolindo Cariño, Ioana Banicescu
2003 J jnl
Clust. Comput.
Ioana Banicescu, Vijay Velusamy, Johnny Devaprasad
2003 A conf
IPDPS
Ricolindo Cariño, Ioana Banicescu, Ravi K. Vadapalli, Charles A. Weatherford, Jianping Zhu
2002 A conf
IPDPS
Ricolindo Cariño, Ioana Banicescu
2002 A conf
IPDPS
Ioana Banicescu, Vijay Velusamy
2002 conf
IASTED PDCS
Ricolindo Cariño, Ioana Banicescu
2001 J jnl
Concurr. Comput. Pract. Exp.
Ioana Banicescu, Sheikh K. Ghafoor, Vijay Velusamy, Samuel H. Russ, Mark Bilderback
2001 A conf
IPDPS
Ioana Banicescu, Vijay Velusamy
2000 Misc conf
PDPTA
Vijay Velusamy, Ioana Banicescu
1998 A conf
HPDC
Samuel H. Russ, Ioana Banicescu, Sheikh K. Ghafoor, Bharathi Janapareddi, Jonathan Robinson, Rong Lu
1998 J jnl
Inf. Process. Lett.
Edward A. Luke, Ioana Banicescu, Jin Li
1995 A conf
SC
Ioana Banicescu, Susan Flynn Hummel
1995 conf
LCR
Susan Flynn Hummel, Ioana Banicescu, Chui-Tzu Wang, Joel Wein
redb/extractors/pe_extractors/pe_signature.py
← Index redb/extractors/pe_extractors/pe_signature.py python
import inspect
import yara_x
from datetime import datetime, timezone
from signify.authenticode import SignedPEFile
from typing import Any, Dict, List, Tuple

from redb.extractors.enum import Tag
from redb.extractors.pe_extractor import PEExtractor
from redb.models.dataclasses import PECertificate, PESigner, PECodeSigningInfo


class PESignatureExtractor(PEExtractor):
    """
    RFC 3161 - Internet X.509 Public Key Infrastructure Time-Stamp Protocol (TSP)
    Section 2.4.2 defines the TSTInfo structure.
    https://tools.ietf.org/html/rfc3161#section-2.4.2

    Microsoft Authenticode Time Stamping Specification
    https://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/Authenticode_PE.docx
    """

    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.elastic_index = self.index_prefix + "-pe_signature"
        self.log.debug(inspect.currentframe().f_code.co_name)
        self.code_signing_info = None

    def tag(self):
        return [Tag.PE_CERTIFICATE.value, Tag.PE_SIGNER.value, Tag.PE_SIGNATURE.value]

    def _extract_certificate_info(self, certificate):
        self.log.debug(inspect.currentframe().f_code.co_name)

        # YARA-X returns datetime objects directly, not Unix timestamps
        not_before = certificate["not_before"]
        not_after = certificate["not_after"]

        # Handle both datetime objects and Unix timestamps for compatibility
        if isinstance(not_before, datetime):
            valid_from = not_before.strftime("%Y-%m-%d %H:%M:%S")
        else:
            valid_from = datetime.fromtimestamp(int(not_before), timezone.utc).strftime("%Y-%m-%d %H:%M:%S")

        if isinstance(not_after, datetime):
            valid_to = not_after.strftime("%Y-%m-%d %H:%M:%S")
        else:
            valid_to = datetime.fromtimestamp(int(not_after), timezone.utc).strftime("%Y-%m-%d %H:%M:%S")

        return PECertificate(
            certificate_serial_number=certificate["serial"],
            certificate_subject=certificate["subject"],
            certificate_issuer=certificate["issuer"],
            certificate_valid_from=valid_from,
            certificate_valid_to=valid_to,
            certificate_thumbprint=certificate["thumbprint"].upper(),
            certificate_algorithm=certificate["algorithm"],
        )

    def _extract_signer_info(self, signer):
        self.log.debug(inspect.currentframe().f_code.co_name)

        # YARA-X returns datetime objects directly, not Unix timestamps
        not_before = signer["not_before"]
        not_after = signer["not_after"]

        # Handle both datetime objects and Unix timestamps for compatibility
        if isinstance(not_before, datetime):
            valid_from = not_before.strftime("%Y-%m-%d %H:%M:%S")
        else:
            valid_from = datetime.fromtimestamp(int(not_before), timezone.utc).strftime("%Y-%m-%d %H:%M:%S")

        if isinstance(not_after, datetime):
            valid_to = not_after.strftime("%Y-%m-%d %H:%M:%S")
        else:
            valid_to = datetime.fromtimestamp(int(not_after), timezone.utc).strftime("%Y-%m-%d %H:%M:%S")

        return PESigner(
            signer_serial_number=signer["serial"],
            signer_subject=signer["subject"],
            signer_issuer=signer["issuer"],
            signer_valid_from=valid_from,
            signer_valid_to=valid_to,
            signer_thumbprint=signer["thumbprint"].upper(),
            signer_algorithm=signer["algorithm"],
        )

    def _extract_signature_info(self):
        self.log.debug(inspect.currentframe().f_code.co_name)
        pe_rules = """
            import "pe"
            rule is_pe {
                condition: 
                    pe.is_pe
            }
        """
        rule = yara_x.compile(pe_rules)
        results = rule.scan(self.binary)
        yara_output = results.module_outputs

        signature_info = yara_output["pe"]["signatures"][0]
        number_of_certificates = signature_info["number_of_certificates"]
        signature_verified = signature_info["verified"]
        self.code_signing_info = PECodeSigningInfo(
            _id=self.sha256,
            signature_verified=signature_verified,
            number_of_certificates=int(number_of_certificates),
        )

        keys = signature_info.keys()
        if "certificates" in keys:
            self.log.debug("Extracting PE Signing Certificates")
            certificates = signature_info["certificates"]
            certificates_list = []
            for cert in certificates:
                cert_info = self._extract_certificate_info(cert)
                certificates_list.append(cert_info)
            self.code_signing_info.x509_certificates = certificates_list

        if "signer_info" in keys:
            self.log.debug("Extracting PE Signing Signer Info")
            signers = signature_info["signer_info"]["chain"]
            signers_list = []
            for signer in signers:
                sig = self._extract_signer_info(signer)
                signers_list.append(sig)
            self.code_signing_info.signers = signers_list

        if "countersignatures" in keys:
            self.log.debug("Extracting PE Signing Countersignatures")
            countersignatures = signature_info["countersignatures"][0]["chain"]
            countersigners_list = []
            for csigner in countersignatures:
                csig = self._extract_signer_info(csigner)
                countersigners_list.append(csig)
            self.code_signing_info.countersigners = countersigners_list

        with open(self.filepath, "rb") as f:
            self.log.debug("Extracting PE Signing spcSpOpusInfo")
            sig_pefile = SignedPEFile(f)
            try:
                spc_opusinfo = {}
                for signed_data in sig_pefile.signed_datas:
                    spc_opusinfo["ProgramName"] = signed_data.signer_info.program_name
                    spc_opusinfo["MoreInfo"] = signed_data.signer_info.more_info
                    self.code_signing_info.spcSpOpusInfo = spc_opusinfo

                    if signed_data.signer_info.countersigner is not None:
                        stime = signed_data.signer_info.countersigner.signing_time
                        self.code_signing_info.date_signed = stime.strftime(
                            "%Y-%m-%d %H:%M:%S"
                        )
            except Exception as e:
                self.log.error(
                    f"Error while extracting spcSpOpusInfo or signing date: {e}"
                )

    def extract(self):
        try:
            self.log.debug(inspect.currentframe().f_code.co_name)
            if self._is_signed():
                self._extract_signature_info()
                # self.export_to_elastic([self.code_signing_info])
                return self.code_signing_info
            return None
        except Exception as e:
            self.log.error(f"Error extracting PE Signature: {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.extract()
    #     elif exporter_type == "ClickHouseExporter":
    #         signing_info = self.extract()
    #         if signing_info is None:
    #             return None
                
    #         current_time = datetime.now(timezone.utc)
            
    #         # Prepare data for redb_pe_signatures table
    #         signatures_data = [[
    #             self.sha256,                                    # sha256
    #             self.md5,                                       # md5
    #             self.sha1,                                      # sha1
    #             signing_info.signature_verified,                # signature_verified
    #             datetime.strptime(signing_info.date_signed, "%Y-%m-%d %H:%M:%S") if signing_info.date_signed else None,  # date_signed
    #             signing_info.number_of_certificates,            # number_of_certificates
    #             signing_info.spcSpOpusInfo.get('ProgramName', None) if signing_info.spcSpOpusInfo else None,  # program_name
    #             signing_info.spcSpOpusInfo.get('MoreInfo', None) if signing_info.spcSpOpusInfo else None,    # more_info
    #             current_time                                    # analysis_date
    #         ]]

    #         certificates_data = []
            
    #         # Process signers
    #         if signing_info.signers:
    #             for signer in signing_info.signers:
    #                 certificates_data.append(self._prepare_certificate_data(signer, 'signer', current_time))
            
    #         # Process countersigners
    #         if signing_info.countersigners:
    #             for csigner in signing_info.countersigners:
    #                 certificates_data.append(self._prepare_certificate_data(csigner, 'countersigner', current_time))
            
    #         # Process x509 certificates
    #         if signing_info.x509_certificates:
    #             for cert in signing_info.x509_certificates:
    #                 certificates_data.append(self._prepare_certificate_data(cert, 'chain', current_time))
            
    #         return {
    #             'multi_table': True,
    #             'signatures': {
    #                 'table': 'redb_pe_signatures',
    #                 'data': signatures_data,
    #                 'column_names': [
    #                     'sha256', 'md5', 'sha1', 'signature_verified', 'date_signed',
    #                     'number_of_certificates', 'spcSpOpusInfo_program_name', 'spcSpOpusInfo_more_info', 'analysis_date'
    #                 ],
    #                 'column_type_names': [
    #                     'FixedString(64)', 'FixedString(32)', 'FixedString(40)',
    #                     'Boolean', 'DateTime64(3, \'UTC\')', 'UInt8',
    #                     'Nullable(String)', 'Nullable(String)', 'DateTime64(3, \'UTC\')'
    #                 ]
    #             },
    #             'certificates': {
    #                 'table': 'redb_pe_certificates',
    #                 'data': certificates_data,
    #                 'column_names': [
    #                     'sha256', 'md5', 'sha1', 'certificate_type', 'certificate_algorithm',
    #                     'certificate_issuer', 'certificate_subject', 'certificate_serial_number',
    #                     'certificate_thumbprint', 'certificate_valid_from', 'certificate_valid_to',
    #                     'analysis_date'
    #                 ],
    #                 'column_type_names': [
    #                     'FixedString(64)', 'FixedString(32)', 'FixedString(40)',
    #                     'Enum(\'signer\', \'countersigner\', \'chain\')', 'LowCardinality(String)',
    #                     'LowCardinality(String)', 'LowCardinality(String)', 'String',
    #                     'String', 'DateTime64(3, \'UTC\')', 'DateTime64(3, \'UTC\')',
    #                     'DateTime64(3, \'UTC\')'
    #                 ]
    #             }
    #         }

    # def _prepare_certificate_data(self, cert, cert_type: str, analysis_time: datetime) -> List:
    #     """Helper method to prepare certificate data for ClickHouse"""
    #     self.log.debug(inspect.currentframe().f_code.co_name)
    #     prefix = "certificate_" if hasattr(cert, "certificate_algorithm") else "signer_"
        
    #     # Get serial number and clean it up
    #     serial_number = getattr(cert, f"{prefix}serial_number")
    #     if serial_number:
    #         serial_number = serial_number.replace(':', '')
        
    #     return [
    #         self.sha256,                          # sha256
    #         self.md5,                             # md5
    #         self.sha1,                            # sha1
    #         cert_type,                            # certificate_type
    #         getattr(cert, f"{prefix}algorithm"),   # certificate_algorithm
    #         getattr(cert, f"{prefix}issuer"),     # certificate_issuer
    #         getattr(cert, f"{prefix}subject"),    # certificate_subject
    #         serial_number,                        # certificate_serial_number
    #         getattr(cert, f"{prefix}thumbprint"),  # certificate_thumbprint
    #         datetime.strptime(getattr(cert, f"{prefix}valid_from"), "%Y-%m-%d %H:%M:%S"),  # certificate_valid_from
    #         datetime.strptime(getattr(cert, f"{prefix}valid_to"), "%Y-%m-%d %H:%M:%S"),    # certificate_valid_to
    #         analysis_time                         # analysis_date
    #     ]
    def prepare_export_data(self, exporter_type: str) -> Any:
        self.log.debug(inspect.currentframe().f_code.co_name)
        if exporter_type == "ElasticsearchExporter":
            return self.extract()
        elif exporter_type == "ClickHouseExporter":
            signing_info = self.extract()
            if signing_info is None:
                return None
                
            current_time = datetime.now(timezone.utc)
            
            # Prepare data for redb_pe_signatures table
            signatures_data = [[
                self.sha256,                                    # sha256
                self.md5,                                       # md5
                self.sha1,                                      # sha1
                signing_info.signature_verified,                # signature_verified
                datetime.strptime(signing_info.date_signed, "%Y-%m-%d %H:%M:%S") if signing_info.date_signed else None,  # date_signed
                signing_info.number_of_certificates,            # number_of_certificates
                signing_info.spcSpOpusInfo.get('ProgramName', None) if signing_info.spcSpOpusInfo else None,  # program_name
                signing_info.spcSpOpusInfo.get('MoreInfo', None) if signing_info.spcSpOpusInfo else None,    # more_info
                current_time                                    # analysis_date
            ]]

            # Prepare data for redb_pe_certificates table
            certificates_data = []
            
            # Process signers
            if signing_info.signers:
                for signer in signing_info.signers:
                    certificates_data.append(self._prepare_certificate_data(signer, 'signer', current_time))
            
            # Process countersigners
            if signing_info.countersigners:
                for csigner in signing_info.countersigners:
                    certificates_data.append(self._prepare_certificate_data(csigner, 'countersigner', current_time))
            
            # Process x509 certificates
            if signing_info.x509_certificates:
                for cert in signing_info.x509_certificates:
                    certificates_data.append(self._prepare_certificate_data(cert, 'chain', current_time))
            
            return {
                'multi_table': True,
                'signatures': {
                    'table': 'redb_pe_signatures',
                    'data': signatures_data,
                    'column_names': [
                        'sha256', 'md5', 'sha1', 'signature_verified', 'date_signed',
                        'number_of_certificates', 'spcSpOpusInfo_program_name', 'spcSpOpusInfo_more_info', 'analysis_date'
                    ],
                    'column_type_names': [
                        'FixedString(64)', 'FixedString(32)', 'FixedString(40)',
                        'Boolean', 'DateTime64(3, \'UTC\')', 'UInt8',
                        'Nullable(String)', 'Nullable(String)', 'DateTime64(3, \'UTC\')'
                    ]
                },
                'certificates': {
                    'table': 'redb_pe_certificates',
                    'data': certificates_data,
                    'column_names': [
                        'sha256', 'md5', 'sha1', 'certificate_type', 'certificate_algorithm',
                        'certificate_issuer', 'certificate_subject', 'certificate_serial_number',
                        'certificate_thumbprint', 'certificate_valid_from', 'certificate_valid_to',
                        'analysis_date'
                    ],
                    'column_type_names': [
                        'FixedString(64)', 'FixedString(32)', 'FixedString(40)',
                        'Enum8(\'signer\' = 1, \'countersigner\' = 2, \'chain\' = 3)', 'LowCardinality(String)',
                        'LowCardinality(String)', 'LowCardinality(String)', 'String',
                        'String', 'DateTime64(3, \'UTC\')', 'DateTime64(3, \'UTC\')',
                        'DateTime64(3, \'UTC\')'
                    ]
                }
            }

    # def _prepare_certificate_data(self, cert, cert_type: str, analysis_time: datetime) -> List:
    #     """Helper method to prepare certificate data for ClickHouse"""
    #     self.log.debug(inspect.currentframe().f_code.co_name)
    #     prefix = "certificate_" if hasattr(cert, "certificate_algorithm") else "signer_"
        
    #     # Get serial number and clean it up - with strict handling
    #     serial_number = getattr(cert, f"{prefix}serial_number", "UNKNOWN")
    #     if not serial_number or not str(serial_number).strip():
    #         serial_number = "UNKNOWN"
    #     else:
    #         serial_number = serial_number.replace(':', '')
    #         if not serial_number.strip():  # Double check after cleaning
    #             serial_number = "UNKNOWN"
        
    #     return [
    #         self.sha256,                          # sha256
    #         self.md5,                             # md5
    #         self.sha1,                            # sha1
    #         cert_type,                            # certificate_type
    #         getattr(cert, f"{prefix}algorithm"),   # certificate_algorithm
    #         getattr(cert, f"{prefix}issuer"),     # certificate_issuer
    #         getattr(cert, f"{prefix}subject"),    # certificate_subject
    #         serial_number,                        # certificate_serial_number
    #         getattr(cert, f"{prefix}thumbprint"),  # certificate_thumbprint
    #         datetime.strptime(getattr(cert, f"{prefix}valid_from"), "%Y-%m-%d %H:%M:%S"),  # certificate_valid_from
    #         datetime.strptime(getattr(cert, f"{prefix}valid_to"), "%Y-%m-%d %H:%M:%S"),    # certificate_valid_to
    #         analysis_time                         # analysis_date
    #     ]

    def _prepare_certificate_data(self, cert, cert_type: str, analysis_time: datetime) -> List:
        """Helper method to prepare certificate data for ClickHouse"""
        self.log.debug(inspect.currentframe().f_code.co_name)
        prefix = "certificate_" if hasattr(cert, "certificate_algorithm") else "signer_"
        
        def clean_string(value, field_name):
            if value is None or (isinstance(value, str) and not value.strip()):
                self.log.warning(f"Empty or None value found for {field_name}")
                return "UNKNOWN"
            return str(value).strip()
        
        try:
            serial_number = getattr(cert, f"{prefix}serial_number", "UNKNOWN")
            serial_number = clean_string(serial_number, "serial_number")
            if serial_number != "UNKNOWN":
                serial_number = serial_number.replace(':', '')
        
            return [
                clean_string(self.sha256, "sha256"),
                clean_string(self.md5, "md5"),
                clean_string(self.sha1, "sha1"),
                cert_type,
                clean_string(getattr(cert, f"{prefix}algorithm"), "algorithm"),
                clean_string(getattr(cert, f"{prefix}issuer"), "issuer"),
                clean_string(getattr(cert, f"{prefix}subject"), "subject"),
                serial_number,
                clean_string(getattr(cert, f"{prefix}thumbprint"), "thumbprint"),
                datetime.strptime(getattr(cert, f"{prefix}valid_from"), "%Y-%m-%d %H:%M:%S"),
                datetime.strptime(getattr(cert, f"{prefix}valid_to"), "%Y-%m-%d %H:%M:%S"),
                analysis_time
            ]
        except Exception as e:
            self.log.error(f"Error preparing certificate data: {str(e)}")
            self.log.error(f"Certificate data that caused error: {cert}")
            raise

    def get_clickhouse_table(self) -> str:
        """Required by PEExtractor abstract base class"""
        return "redb_pe_signatures"  # Return the primary table

    def get_clickhouse_tables(self) -> Dict[str, str]:
        """Additional method for multi-table support"""
        return {
            'signatures': 'redb_pe_signatures',
            'certificates': 'redb_pe_certificates'
        }