Oliver Sander

118 papers A 6B 3C 8Misc 4Journal 60Unranked 32
YearRankTypeTitle / Venue / Authors
2026 J jnl
J. Num. Math.
Sören Bartels, Klaus Böhnlein, Christian Palus, Oliver Sander
2025 J jnl
CoRR
Christian Engwer, Carsten Gräser, Steffen Müthing, Simon Praetorius, Oliver Sander
2025 J jnl
CoRR
Klaus Böhnlein, Stefan Neukamm, Oliver Sander
2025 J jnl
SIAM J. Numer. Anal.
Gentian Zavalani, Oliver Sander, Michael Hecht
2025 J jnl
CoRR
Marvin Fuchs, Lukas Scheller, Timo Muscheid, Oliver Sander, Luis E. Ardila-Perez
2025 J jnl
CoRR
Markus Blatt, Samuel Burbulla, Ansgar Burchardt, Andreas Dedner, Christian Engwer, Carsten Gräser, Christoph Grüninger, Robert Klöfkorn, Timo Koch, Santiago Ospina De Los Ríos, Simon Praetorius, Oliver Sander
2024 J jnl
CoRR
Marvin Fuchs, Hendrik Krause, Timo Muscheid, Lukas Scheller, Luis E. Ardila-Perez, Oliver Sander
2024 Misc conf
QCE
Robert Gartmann, Valentin Stumpert, Lukas Scheller, Richard Weller, Luis E. Ardila-Perez, Oliver Sander
2024 J jnl
Multiscale Model. Simul.
Sabine Haberland, Patrick Jaap, Stefan Neukamm, Oliver Sander, Mario Varga
2024 Misc conf
QCE
Mario Schlösser, Luis E. Ardila-Perez, Robert Gartmann, Lukas Scheller, Marvin Fuchs, Oliver Sander, Roger Heil, Christian Roth, Ilja Bekman, Markus Jerger, Rami Barends, Stefan van Waasen
2024 Misc conf
QCE
Robert Gartmann, Oliver Krömer, Richard Weller, Nick Karcher, Luis E. Ardila-Perez, Oliver Sander
2024 Misc conf
QCE
Luis E. Ardila-Perez, Marvin Fuchs, Robert Gartmann, Lukas Scheller, Mario Schlösser, Roger Heil, Christian Roth, Ilja Bekman, Markus Jerger, Rami Barends, Stefan van Waasen, Oliver Sander
2023 J jnl
J. Nonlinear Sci.
Klaus Böhnlein, Stefan Neukamm, David Padilla-Garza, Oliver Sander
2023 J jnl
CoRR
Lisa Julia Nebel, Oliver Sander, Mircea Bîrsan, Patrizio Neff
2023 J jnl
CoRR
Gentian Zavalani, Oliver Sander, Michael Hecht
2023 J jnl
ACM Trans. Reconfigurable Technol. Syst.
Richard Gebauer, Nick Karcher, Mehmed Güler, Oliver Sander
2023 J jnl
CoRR
Marvin Fuchs, Luis E. Ardila-Perez, Torben Mehner, Oliver Sander
2022 J jnl
CoRR
Sören Bartels, Klaus Böhnlein, Christian Palus, Oliver Sander
2022 J jnl
J. Nonlinear Sci.
Jendrik Voss, Robert J. Martin, Oliver Sander, Siddhant Kumar, Dennis M. Kochmann, Patrizio Neff
2022 J jnl
CoRR
Jendrik Voss, Robert J. Martin, Oliver Sander, Siddhant Kumar, Dennis M. Kochmann, Patrizio Neff
2022 J jnl
CoRR
Sabine Haberland, Patrick Jaap, Stefan Neukamm, Oliver Sander, Mario Varga
2021 conf
FPT
Richard Gebauer, Nick Karcher, Oliver Sander
2021 J jnl
CoRR
Oliver Sander
2021 J jnl
IEEE Signal Process. Lett.
Jonas A. Kunzler, Rodrigo Pinto Lemos, Nick Karcher, Oliver Sander
2021 conf
SoCC
Richard Gebauer, Nick Karcher, Jonas Hurst, Marc Weber, Oliver Sander
2021 J jnl
Comput. Math. Appl.
Peter Bastian, Markus Blatt, Andreas Dedner, Nils-Arne Dreier, Christian Engwer, René Fritze, Carsten Gräser, Christoph Grüninger, Dominic Kempf, Robert Klöfkorn, Mario Ohlberger, Oliver Sander
2021 J jnl
CoRR
Oliver Sander, Ruth Schöbel, Robert Speck
2020 J jnl
ZfBB
Kerstin Risse, Oliver Sander
2020 J jnl
CoRR
Richard Gebauer, Nick Karcher, Jonas Hurst, Marc Weber, Oliver Sander
2020 book
Oliver Sander
2020 J jnl
J. Nonlinear Sci.
Robert J. Martin, Jendrik Voss, Ionel-Dumitrel Ghiba, Oliver Sander, Patrizio Neff
2020 J jnl
CoRR
Carsten Gräser, Daniel Kienle, Oliver Sander
2020 J jnl
CoRR
Nick Karcher, Richard Gebauer, Robin Bauknecht, Rainer Illichmann, Oliver Sander
2019 J jnl
SIAM J. Sci. Comput.
Jonathan Youett, Oliver Sander, Ralf Kornhuber
2019 J jnl
J. Frankl. Inst.
Rodrigo Pinto Lemos, Jonas A. Kunzler, Diego Fernando Burgos, Mário José de Souza, Hugo Vinicius Leao e Silva, Yroá R. Ferreira, Edna Lúcia Flôres, Oliver Sander
2019 J jnl
SIAM J. Numer. Anal.
Philipp Grohs, Hanne Hardering, Oliver Sander, Markus Sprecher
2019 J jnl
CoRR
Peter Bastian, Markus Blatt, Andreas Dedner, Nils-Arne Dreier, Christian Engwer, René Fritze, Carsten Gräser, Dominic Kempf, Robert Klöfkorn, Mario Ohlberger, Oliver Sander
2019 J jnl
J. Frankl. Inst.
Rodrigo Pinto Lemos, Jonas A. Kunzler, Diego Fernando Burgos, Mário José de Souza, Hugo Vinicius Leao e Silva, Yroá R. Ferreira, Edna Lúcia Flôres, Oliver Sander
2019 J jnl
J. Frankl. Inst.
Rodrigo Pinto Lemos, Jonas A. Kunzler, Diego Fernando Burgos, Mário José de Souza, Hugo Vinicius Leao e Silva, Yroá R. Ferreira, Edna Lúcia Flôres, Oliver Sander
2018 J jnl
CoRR
Christian Engwer, Carsten Gräser, Steffen Müthing, Oliver Sander
2017 B conf
FPL
Robin Aggleton, Luis E. Ardila-Perez, Fionn Amhairghen Ball, Matthias Norbert Balzer, James John Brooke, Luigi Calligaris, Michele Caselle, Davide Cieri, Emyr John Clement, Geoffrey Hall, Kristian Harder, Peter R. Hobson, Gregory M. Iles, Thomas James, Konstantinos Manolopoulos, Takashi Matsushita, Alexander D. Morton, David Newbold, Sudarshan Paramesvaran, Mark Franco Pesaresi, Ivan D. Reid, Andrew W. Rose, Oliver Sander, Thomas Schuh, Claire Shepherd-Themistocleous, Antoni Shtipliyski, Sioni Paris Summers, Alexander D. Tapper, Ian Tomalin, Kirika Uchida, Paschalis Vichoudis, Marc Weber
2017 conf
MOCAST
Christos Gentsos, Giacomo Fedi, Guido Magazzù, Daniel Magalotti, Atanu Modak, Loriano Storchi, Fabrizio Palla, Gian Mario Bilei, Nicolo Vladi Biesuz, Suvankar Roy Chowdhury, Francesco Crescioli, Bruno Checcucci, Denis Tcherniakhovski, Geoffrey Christian Galbit, Guillaume Baulieu, Matthias Norbert Balzer, Oliver Sander, Sebastien Viret, Leonello Servoli, Spiridon Nikolaidis
2016 C conf
DSD
Christian Amstutz, Oliver Sander
2016 conf
ARC
Falco K. Bapp, Oliver Sander, Timo Sandmann, Hannes Stoll, Jürgen Becker
2015 C conf
DS-RT
Alisson Vasconcelos de Brito, Harald Bucher, Helder F. de A. Oliveira, Luis Feliphe S. Costa, Oliver Sander, Elmar U. K. Melcher, Jürgen Becker
2015 conf
SimuTools
Harald Bucher, Marius-Florian Buciuman, Alexander Klimm, Oliver Sander, Jürgen Becker
2015 J jnl
Microprocess. Microsystems
Simon Reder, Christoph Roth, Harald Bucher, Oliver Sander, Jürgen Becker
2015 conf
HPCS
Viet Vu Duy, Oliver Sander, Timo Sandmann, Jan Heidelberger, Steffen Baehr, Jürgen Becker
2015 J jnl
Found. Comput. Math.
Philipp Grohs, Hanne Hardering, Oliver Sander
2015 C conf
DS-RT
Harald Bucher, Alexander Klimm, Oliver Sander, Jürgen Becker
2015 J jnl
CoRR
Oliver Sander, Timo Koch, Natalie Schröder, Bernd Flemisch
2015 J jnl
CoRR
Christian Engwer, Carsten Gräser, Steffen Müthing, Oliver Sander
2014 C conf
Software Engineering
Ottmar Bender, Wolfgang Böhm, Stefan Henkler, Oliver Sander, Andreas Vogelsang, Thorsten Weyer
2014 conf
FPT
Oliver Sander, Steffen Baehr, Enno Lübbers, Timo Sandmann, Viet Vu Duy, Jürgen Becker
2014 C conf
DSD
Christoph Roth, Simon Reder, Harald Bucher, Oliver Sander, Jürgen Becker
2014 conf
MWSCAS
Oliver Sander, Falco Bapp, Timo Sandmann, Viet Vu Duy, Steffen Bähr, Jürgen Becker
2014 conf
ReConFig
Viet Vu Duy, Oliver Sander, Timo Sandmann, Steffen Bähr, Jan Heidelberger, Jürgen Becker
2014 C ed.
Software Engineering (Workshops)
Klaus Schmid, Wolfgang Böhm, Robert Heinrich, Andrea Herrmann, Anne Hoffmann, Dieter Landes, Marco Konersmann, Thomas Ruhroth, Oliver Sander, Volker Stolz, Baltasar Trancón y Widemann, Rüdiger Weißbach
2014 A conf
DATE
Oliver Sander, Timo Sandmann, Viet Vu Duy, Steffen Bähr, Falco Bapp, Jürgen Becker, Hans-Ulrich Michel, Dirk Kaule, Daniel Adam, Enno Lübbers, Jürgen Hairbucher, Andre Oliver Richter, Christian Herber, Andreas Herkersdorf
2014 J jnl
J. Num. Math.
Carsten Gräser, Oliver Sander
2014 J jnl
SIAM J. Sci. Comput.
Heiko Berninger, Sébastien Loisel, Oliver Sander
2014 conf
IPDPS Workshops
Viet Vu Duy, Timo Sandmann, Steffen Baehr, Oliver Sander, Jürgen Becker
2013 conf
SBCCI
Christoph Roth, Harald Bucher, Simon Reder, Florian Buciuman, Oliver Sander, Jürgen Becker
2013 conf
ReCoSoC
Michael Dreschmann, Oliver Sander, Alexander Klimm, Christoph Roth, Jürgen Becker
2013 ch.
Domain Decomposition Methods in Science and Engineering XX
Oliver Sander
2013 C conf
DS-RT
Alisson Vasconcelos de Brito, Angelo V. Negreiros, Christoph Roth, Oliver Sander, Jürgen Becker
2013 J jnl
it Inf. Technol.
Oliver Sander, Alexander Klimm, Jürgen Becker
2013 ch.
Domain Decomposition Methods in Science and Engineering XX
Heiko Berninger, Ralf Kornhuber, Oliver Sander
2013 conf
ReCoSoC
Christoph Roth, Harald Bucher, Simon Reder, Oliver Sander, Jürgen Becker
2013 conf
IPDPS Workshops
Jürgen Becker, Ramachandran Vaidyanathan, Peter Athanas, Marco D. Santambrogio, René Cumplido, Oliver Sander
2013 J jnl
Int. J. Reconfigurable Comput.
Massimo Conti, Elmar U. K. Melcher, Jürgen Becker, Alisson Vasconcelos de Brito, Oliver Sander
2013 J jnl
Comput. Vis. Sci.
Oliver Sander, Corinna Klapproth, Jonathan Youett, Ralf Kornhuber, Peter Deuflhard
2012 conf
SimuTools
Christoph Roth, Simon Reder, Oliver Sander, Michael Hübner, Jürgen Becker
2012 conf
ISSoC
Christoph Roth, Simon Reder, Gokhan Erdogan, Oliver Sander, Gabriel Marchesan Almeida, Harald Bucher, Jürgen Becker
2012 J jnl
Int. J. Reconfigurable Comput.
Christoph Roth, Joachim Meyer, Michael Rückauer, Oliver Sander, Jürgen Becker
2012 J jnl
Int. J. Reconfigurable Comput.
Oliver Sander, Benjamin Glas, Lars Braun, Klaus D. Müller-Glaser, Jürgen Becker
2011 conf
ReCoSoC
Mahtab Niknahad, Oliver Sander, Jürgen Becker
2011 J jnl
Comput. Vis. Sci.
Heiko Berninger, Oliver Sander
2011 A conf
DATE
Joachim Meyer, Juanjo Noguera, Michael Hübner, Lars Braun, Oliver Sander, R. M. Gil, Rodney Stewart, Jürgen Becker
2011 J jnl
SIAM J. Numer. Anal.
Heiko Berninger, Ralf Kornhuber, Oliver Sander
2011 conf
SBCCI
Christoph Roth, Oliver Sander, Jürgen Becker
2011 conf
SimuTools
Christoph Roth, Oliver Sander, Matthias Kühnle, Jürgen Becker
2011 conf
IPDPS Workshops
Christoph Roth, Gabriel Marchesan Almeida, Oliver Sander, Luciano Ost, Nicolas Hebert, Gilles Sassatelli, Pascal Benoit, Lionel Torres, Jürgen Becker
2011 J jnl
Int. J. Reconfigurable Comput.
Benjamin Glas, Oliver Sander, Vitali Stuckert, Klaus D. Müller-Glaser, Jürgen Becker
2011 J jnl
Comput. Vis. Sci.
Oliver Sander
2010 conf
SoC
Alexander Klimm, Matthias Haas, Oliver Sander, Jürgen Becker
2010 conf
ReCoSoC
Benjamin Glas, Oliver Sander, Vitali Stuckert, Klaus D. Müller-Glaser, Jürgen Becker
2010 conf
ISVLSI (Selected papers)
Joachim Meyer, Michael Hübner, Lars Braun, Oliver Sander, Juanjo Noguera, Rodney Stewart, Jürgen Becker
2010 conf
ISVLSI
Michael Hübner, Joachim Meyer, Oliver Sander, Lars Braun, Jürgen Becker, Juanjo Noguera, Rodney Stewart
2010 conf
ReConFig
Oliver Sander, Benjamin Glas, Lars Braun, Klaus D. Müller-Glaser, Jürgen Becker
2010 J jnl
Bioinform.
André Altmann, Laura Tolosi, Oliver Sander, Thomas Lengauer
2010 ed.
ReCoSoC
Michael Hübner, Loïc Lagadec, Oliver Sander, Jürgen Becker
2010 B conf
FPL
Michael Dreschmann, Michael Hübner, Moritz Röger, Oliver Sander, Christos Klamouris, Jürgen Becker, Wolfgang Freude, Juerg Leuthold
2010 J jnl
Comput. Vis. Sci.
Heiko Berninger, Oliver Sander
2009 A conf
IPDPS
Alexander Klimm, Oliver Sander, Jürgen Becker
2009 conf
VTC Spring
Benjamin Glas, Oliver Sander, Vitali Stuckert, Klaus D. Müller-Glaser, Jürgen Becker
2009 conf
FPT
Oliver Sander, Benjamin Glas, Christoph Roth, Jürgen Becker, Klaus D. Müller-Glaser
2009 A conf
DATE
Oliver Sander, Benjamin Glas, Christoph Roth, Jürgen Becker, Klaus D. Müller-Glaser
2009 conf
SBCCI
Oliver Sander, Christoph Roth, Vitali Stuckert, Jürgen Becker
2009 C conf
IEEE International Workshop on Rapid System Prototyping
Oliver Sander, Benjamin Glas, Christoph Roth, Jürgen Becker, Klaus D. Müller-Glaser
2009 J jnl
Computing
Carsten Gräser, Oliver Sander
2008 conf
ARCS
Alexander Klimm, Oliver Sander, Jürgen Becker, Sylvain Subileau
2008 A conf
DATE
Benjamin Glas, Alexander Klimm, Oliver Sander, Klaus D. Müller-Glaser, Jürgen Becker
2008 J jnl
Computing
Peter Bastian, Markus Blatt, Andreas Dedner, Christian Engwer, Robert Klöfkorn, Mario Ohlberger, Oliver Sander
2008 J jnl
Computing
Peter Bastian, Markus Blatt, Andreas Dedner, Christian Engwer, Robert Klöfkorn, Ralf Kornhuber, Mario Ohlberger, Oliver Sander
2008 A conf
IPDPS
Benjamin Glas, Alexander Klimm, Oliver Sander, Klaus D. Müller-Glaser, Jürgen Becker
2008 conf
ARC
Oliver Sander, Lars Braun, Michael Hübner, Jürgen Becker
2008 J jnl
PLoS Comput. Biol.
Nils Weinhold, Oliver Sander, Francisco S. Domingues, Thomas Lengauer, Ingolf Sommer
2008 conf
FPT
Oliver Sander, Michael Hübner, Jürgen Becker, Matthias Traub
2008 B conf
APBC
Oliver Sander, Francisco S. Domingues, Hongbo Zhu, Thomas Lengauer, Ingolf Sommer
2008
Oliver Sander
2007 J jnl
Bioinform.
Ingolf Sommer, Oliver Müller, Francisco S. Domingues, Oliver Sander, Joachim Weickert, Thomas Lengauer
2007 J jnl
PLoS Comput. Biol.
Oliver Sander, Tobias Sing, Ingolf Sommer, Andrew J. Low, Peter K. Cheung, P. Richard Harrigan, Thomas Lengauer, Francisco S. Domingues
2006 J jnl
Numerische Mathematik
Vicent Caselles, Laura Igual, Oliver Sander
2006 J jnl
BMC Bioinform.
Ingolf Sommer, Stefano Toppo, Oliver Sander, Thomas Lengauer, Silvio C. E. Tosatto
2006 J jnl
BMC Bioinform.
Oliver Sander, Ingolf Sommer, Thomas Lengauer
2005 J jnl
Bioinform.
Tobias Sing, Oliver Sander, Niko Beerenwinkel, Thomas Lengauer
2003 conf
ICIP (3)
Oliver Sander, Marcelo Bertalmío, Vicent Caselles
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"