Manolis Maragoudakis

116 papers A* 1A 3B 13C 4Misc 6Journal 37Unranked 52
YearRankTypeTitle / Venue / Authors
2025 conf
NiDS (1)
Athanasios Kanavos, Gerasimos Vonitsanos, Manolis Maragoudakis, Phivos Mylonas
2025 B conf
IEEE Big Data
Nikolaos Roufas, Athanasios Kanavos, Ioannis Karamitsos, Khalil Al-Hussaeni, Manolis Maragoudakis
2025 J jnl
Comput.
Alexios Kaponis, Manolis Maragoudakis, Konstantinos Chrysanthos Sofianos
2025 J jnl
Big Data Cogn. Comput.
George Papageorgiou, Vangelis Sarlis, Manolis Maragoudakis, Ioannis Magnisalis, Christos Tjortjis
2025 conf
AIAI Workshops (2)
Orestis Papadimitriou, Khalil Al-Hussaeni, Ioannis Karamitsos, Manolis Maragoudakis
2025 conf
AIAI (3)
Konstantinos Chrysanthos Sofianos, Michalis Stefanidakis, Manolis Maragoudakis, Alexios Kaponis, Anastasia Georgaki, Linas Bukauskas
2025 J jnl
Int. J. Artif. Intell. Tools
Orestis Papadimitriou, Athanasios Kanavos, Manolis Maragoudakis, Ioannis Karamitsos
2025 conf
AIAI Workshops (2)
Athanasios Kanavos, Ioannis Karamitsos, Manolis Maragoudakis
2024 conf
ICACS
Orestis Papadimitriou, Athanasios Kanavos, Manolis Maragoudakis, Vassilis C. Gerogiannis
2024 conf
SEEDA-CECNSM
Athanasios Kanavos, Orestis Papadimitriou, Gerasimos Vonitsanos, Manolis Maragoudakis, Phivos Mylonas
2024 conf
NiDS
Orestis Papadimitriou, Athanasios Kanavos, Gerasimos Vonitsanos, Manolis Maragoudakis, Phivos Mylonas
2024 B conf
IEEE Big Data
Athanasios Kanavos, Orestis Papadimitriou, Khalil Al-Hussaeni, Ioannis Karamitsos, Manolis Maragoudakis
2024 conf
SMAP
Orestis Papadimitriou, Athanasios Kanavos, Gerasimos Vonitsanos, Manolis Maragoudakis, Panagiotis Karkazis, Phivos Mylonas
2024 J jnl
Comput.
Athanasios Kanavos, Orestis Papadimitriou, Khalil Al-Hussaeni, Manolis Maragoudakis, Ioannis Karamitsos
2023 conf
SMAP
Orestis Papadimitriou, Athanasios Kanavos, Phivos Mylonas, Manolis Maragoudakis
2023 conf
IISA
Orestis Papadimitriou, Athanasios Kanavos, Manolis Maragoudakis
2023 conf
PETRA
Alexios Kaponis, Alexios A. Kaponis, Manolis Maragoudakis
2023 conf
NiDS (2)
Orestis Papadimitriou, Athanasios Kanavos, Phivos Mylonas, Manolis Maragoudakis
2023 conf
SMAP
Athanasios Kanavos, Orestis Papadimitriou, Manolis Maragoudakis
2023 B conf
IEEE Big Data
Athanasios Kanavos, Orestis Papadimitriou, Alexios Kaponis, Manolis Maragoudakis
2023 conf
IISA
Athanasios Kanavos, Orestis Papadimitriou, Phivos Mylonas, Manolis Maragoudakis
2023 J jnl
Frontiers Appl. Math. Stat.
Ivan Jacobs, Lim Chwee Ming, Jamie Mong, Manolis Maragoudakis, Nishant Malik
2022 J jnl
Comput.
Spyridon Garmpis, Manolis Maragoudakis, Aristogiannis Garmpis
2022 conf
SEEDA-CECNSM
Athanasios Kanavos, Efstratios Kolovos, Orestis Papadimitriou, Manolis Maragoudakis
2022 conf
SETN
Alexios Kaponis, Manolis Maragoudakis
2022 J jnl
Neural Comput. Appl.
Alexandros Dimitrios Zervopoulos, Aikaterini Georgia Alvanou, Konstantinos Bezas, Asterios Papamichail, Manolis Maragoudakis, Katia Kermanidis
2022 conf
SETN
Spyros Zoupanos, Stratis Kolovos, Athanasios Kanavos, Orestis Papadimitriou, Manolis Maragoudakis
2022 J jnl
CoRR
Spyros Zoupanos, Stratis Kolovos, Athanasios Kanavos, Orestis Papadimitriou, Manolis Maragoudakis
2022 conf
SETN
Ioannis Konstantinidis, Manolis Maragoudakis, Ioannis Magnisalis, Christos Berberidis, Vassilios Peristeras
2021 conf
IISA
Andreas Kanavos, Theodor Panagiotakopoulos, Gerasimos Vonitsanos, Manolis Maragoudakis, Yiannis Kiouvrekis
2021 conf
SMAP
Gerasimos Vonitsanos, Theodor Panagiotakopoulos, Andreas Kanavos, Manolis Maragoudakis, Phivos Mylonas
2021 J jnl
Comput.
Maria Eleni Skarkala, Manolis Maragoudakis, Stefanos Gritzalis, Lilian Mitrou
2020 J jnl
Comput.
Christos Kalyvas, Manolis Maragoudakis
2020 conf
SEEDA-CECNSM
Christos Kalyvas, Manolis Maragoudakis
2020 J jnl
Int. J. Data Anal. Tech. Strateg.
Manolis Maragoudakis
2020 conf
AIAI (Workshops)
Maria Nefeli Nikiforos, Spiridon Vergis, Andreana Stylidou, Nikolaos Augoustis, Katia Lida Kermanidis, Manolis Maragoudakis
2020 conf
AIAI (2)
Alexandros Dimitrios Zervopoulos, Aikaterini Georgia Alvanou, Konstantinos Bezas, Asterios Papamichail, Manolis Maragoudakis, Katia Kermanidis
2020 conf
SEEDA-CECNSM
Maria Eleni Skarkala, Manolis Maragoudakis, Stefanos Gritzalis, Lilian Mitrou
2020 conf
EGOV
Euripidis N. Loukis, Niki Kyriakou, Manolis Maragoudakis
2019 J jnl
Algorithms
Manolis Maragoudakis
2019 J jnl
Entertain. Comput.
Javier Gómez, Letizia Jaccheri, Manolis Maragoudakis, Kshitij Sharma
2019 conf
EGOV
Euripidis N. Loukis, Manolis Maragoudakis, Niki Kyriakou
2019 J jnl
Data Knowl. Eng.
Christos Kalyvas, Manolis Maragoudakis
2018 J jnl
Int. J. Data Min. Model. Manag.
Konstantinos Kontos, Manolis Maragoudakis
2018 J jnl
Algorithms
Foteini Kollintza-Kyriakoulia, Manolis Maragoudakis, Anastasia Krithara
2018 conf
SETN
Antonios Pantazopoulos, Manolis Maragoudakis
2017 J jnl
Algorithms
Vasileios Athanasiou, Manolis Maragoudakis
2017 conf
HICSS
Lefkothea Spiliotopoulou, Dimitrios Damopoulos, Yannis Charalabidis, Manolis Maragoudakis, Stefanos Gritzalis
2017 J jnl
CoRR
Nikolaos K. Tselios, Manolis Maragoudakis
2017 conf
HICSS
Niki Kyriakou, Manolis Maragoudakis, Euripidis N. Loukis, Marinos Themistocleous
2016 J jnl
Knowl. Based Syst.
Nektaria Potha, Manolis Maragoudakis, Dimitrios P. Lyras
2016 J jnl
Int. J. Soc. Netw. Min.
Manolis Maragoudakis, Ioannis Markou
2016 Misc conf
AIAI
Vasileios Athanasiou, Manolis Maragoudakis
2015 conf
EANN Workshops
Katia Lida Kermanidis, Manolis Maragoudakis, Spyros Vosinakis
2015 conf
ePart
Yannis Charalabidis, Manolis Maragoudakis, Euripidis N. Loukis
2015 conf
EEPM@eGOV
Antonis Ramfos, Akrivi Kiousi, Miltiadis Kokkonidis, Christophe Leclercq, David Mekkaoui, Maxime Sattonnay, Manolis Maragoudakis, Aggeliki Androutsopoulou, Yannis Charalabidis, Jörn Kohlhammer, Tobias Ruppert, Hendrik Lücke-Tieke, Nikos Dimakopoulos, Leonidas Kallipolitis, Pavel Nikodem, Tomas Madlenak, Francesco Mureddu, Demetrios Pyrenis, Matthew Protonotarios, Charalampos Ipektsidis
2015 C conf
EANN
Nektaria Potha, Manolis Maragoudakis
2015 J jnl
Int. J. Data Min. Model. Manag.
Euangelos Linardos, Katia Lida Kermanidis, Manolis Maragoudakis
2014 conf
ICDM Workshops
Nektaria Potha, Manolis Maragoudakis
2014 conf
AIAI (Workshops)
Manolis Maragoudakis, Katia Lida Kermanidis, Spyros Vosinakis
2014 J jnl
Univers. Access Inf. Soc.
Manolis Maragoudakis, Euripidis N. Loukis
2014 J jnl
Int. J. Artif. Intell. Tools
Alexandros Panteli, Manolis Maragoudakis, Stefanos Gritzalis
2013 Misc conf
AIAI
Konstantinos Kontos, Manolis Maragoudakis
2013 Misc conf
AIAI
Katia Kermanidis, Manolis Maragoudakis, Spyros Vosinakis, Nikos Exadaktylos
2013 conf
EANN (1)
Vicky Politopoulou, Manolis Maragoudakis
2013 J jnl
Int. J. Soc. Netw. Min.
Katia Lida Kermanidis, Manolis Maragoudakis
2012 J jnl
Int. J. Artif. Intell. Tools
Manolis Maragoudakis, Dimitrios P. Lyras, Kyriakos N. Sgarbas
2012 conf
AIAI (2)
Kostas Anagnostou, Manolis Maragoudakis
2012 B conf
ASONAM
Maria Eleni Skarkala, Manolis Maragoudakis, Stefanos Gritzalis, Lilian Mitrou, Hannu Toivonen, Pirjo Moen
2012 conf
PETRA
Egidijus Paliulis, Manolis Maragoudakis, Alexandros Panteli
2012 J jnl
OR Insight
Manolis Maragoudakis, Euripidis N. Loukis
2011 Misc conf
AIAI
Alexandros Panteli, Manolis Maragoudakis
2011 conf
ePart
Manolis Maragoudakis, Euripidis N. Loukis, Yannis Charalabidis
2011 J jnl
Health Informatics J.
Manolis Maragoudakis, Ilias Maglogiannis
2011 conf
PETRA
Manolis Maragoudakis, Euripidis N. Loukis
2011 J jnl
Int. J. Knowl. Eng. Data Min.
Konstantinos Kotis, Andreas Papasalouros, Manolis Maragoudakis
2011 B conf
TrustBus
Maria Eleni Skarkala, Manolis Maragoudakis, Stefanos Gritzalis, Lilian Mitrou
2011 J jnl
Comput. Secur.
Constantinos Kolias, Georgios Kambourakis, Manolis Maragoudakis
2010 conf
ICTAI (2)
Manolis Maragoudakis, Euripidis N. Loukis
2010 conf
PETRA
Euripidis N. Loukis, Manolis Maragoudakis
2010 Misc conf
AIAI
Manolis Maragoudakis, Dimitrios N. Serpanos
2009 J jnl
Data Knowl. Eng.
Emmanouil Magkos, Manolis Maragoudakis, Vassilios Chrissikopoulos, Stefanos Gritzalis
2009 conf
Panhellenic Conference on Informatics
Kostas Anagnostou, Manolis Maragoudakis
2009 J jnl
IEEE Trans. Syst. Man Cybern. Part A
Georgios N. Yannakakis, Manolis Maragoudakis, John Hallam
2008 C conf
BIBE
Manolis Maragoudakis, Ilias Maglogiannis, Dimitrios Lymberopoulos
2008 C conf
Privacy in Statistical Databases
Emmanouil Magkos, Manolis Maragoudakis, Vassilios Chrissikopoulos, Stefanos Gritzalis
2008 B conf
LREC
Katia Kermanidis, Aristomenis Thanopoulos, Manolis Maragoudakis, Nikos Fakotakis
2008 A conf
ECAI
Manolis Maragoudakis, Euripidis N. Loukis, Panayotis-Prodromos Pantelides
2008 J jnl
e Minds Int. J. Hum. Comput. Interact.
Christos Fidas, Manolis Maragoudakis, Nikolaos M. Avouris
2008 J jnl
Nat. Lang. Eng.
Katia Kermanidis, Manolis Maragoudakis, Nikos Fakotakis, George K. Kokkinakis
2008 C conf
ADMA
Manolis Maragoudakis, Nikolaos Cosmas, Aristogiannis Garbis
2007 conf
ICTAI (2)
Manolis Maragoudakis
2007 J jnl
IEEE Intell. Syst.
Manolis Maragoudakis, Aristomenis Thanopoulos, Nikos Fakotakis
2006 conf
SETN
Manolis Maragoudakis, Nikos Fakotakis
2006 B conf
LREC
Manolis Maragoudakis, Katia Kermanidis, Aristogiannis Garbis, Nikos Fakotakis
2006 J jnl
J. Educ. Technol. Soc.
Nikolaos K. Tselios, Adrian G. Stoica, Manolis Maragoudakis, Nikolaos M. Avouris, Vassilis Komis
2005 J jnl
J. Quant. Linguistics
Manolis Maragoudakis, Katia Kermanidis, Alexandros Tasikas, Nikos Fakotakis, George K. Kokkinakis
2005 conf
User Modeling
Georgios N. Yannakakis, Manolis Maragoudakis
2004 B conf
LREC
Manolis Maragoudakis, Nikos Fakotakis, George Kokkinakis
2004 conf
TSD
Manolis Maragoudakis, Todor Ganchev, Nikos Fakotakis
2004 B conf
LREC
Manolis Maragoudakis, Nikos Fakotakis
2004 J jnl
Int. J. Artif. Intell. Tools
Manolis Maragoudakis, Aristomenis Thanopoulos, Kyriakos N. Sgarbas, Nikos Fakotakis
2004 B conf
COLING
Katia Kermanidis, Manolis Maragoudakis, Nikos Fakotakis, George Kokkinakis
2004 B conf
LREC
Panagiotis Zervas, Manolis Maragoudakis, Nikos Fakotakis, George Kokkinakis
2003 conf
TSD
Manolis Maragoudakis, Panagiotis Zervas, Nikos Fakotakis, George K. Kokkinakis
2003 A conf
INTERSPEECH
Panagiotis Zervas, Manolis Maragoudakis, Nikos Fakotakis, George Kokkinakis
2003 B conf
KES
Manolis Maragoudakis, Aristomenis Thanopoulos, Kyriakos N. Sgarbas, Nikos Fakotakis
2003 conf
TSD
Manolis Maragoudakis, Aristomenis Thanopoulos, Nikos Fakotakis
2002 B conf
LREC
Manolis Maragoudakis, Katia Kermanidis, Nikos Fakotakis, George Kokkinakis
2002 conf
SETN
Manolis Maragoudakis, Nikolaos K. Tselios, Nikos Fakotakis, Nikolaos M. Avouris
2002 Misc conf
ICASSP
Manolis Maragoudakis, Ergina Kavallieratou, Nikos Fakotakis
2002 conf
ICPR (3)
Manolis Maragoudakis, Ergina Kavallieratou, Nikos Fakotakis
2002 conf
TSD
Manolis Maragoudakis, Aristomenis Thanopoulos, Nikos Fakotakis
2001 A conf
ICDAR
Manolis Maragoudakis, Ergina Kavallieratou, Nikos Fakotakis, George K. Kokkinakis
2001 conf
TSD
Katia Kermanidis, Manolis Maragoudakis, Nikos Fakotakis, George K. Kokkinakis
2001 A* conf
ICDM
Manolis Maragoudakis, Katia Kermanidis, Nikos Fakotakis, George K. Kokkinakis
redb/extractors/pe_extractors/pe_dotnet.py
← Index redb/extractors/pe_extractors/pe_dotnet.py python
import inspect
import pefile
from dotnetfile import DotNetPE

import base64
from hashlib import md5
from pprint import pprint

import magic
import pefile

from redb.extractors.enum import Tag
from redb.extractors.pe_extractor import PEExtractor
from redb.models.dataclasses import PEDotNet
from datetime import datetime, timezone
import json
from typing import Any


class PEDotNetExtractor(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_dotnet"
        self.dotnet, self.error = self._generate_dotnetfile_object()
        self.log.debug(inspect.currentframe().f_code.co_name)

    def _decode_assembly_flags(self, flag_value):
        self.log.debug(inspect.currentframe().f_code.co_name)
        ASSEMBLY_FLAGS = {
            0x00000001: "COMIMAGE_FLAGS_ILONLY",
            0x00000002: "COMIMAGE_FLAGS_32BITREQUIRED",
            0x00000004: "COMIMAGE_FLAGS_IL_LIBRARY",
            0x00000008: "COMIMAGE_FLAGS_STRONGNAMESIGNED",
            0x00000010: "COMIMAGE_FLAGS_NATIVE_ENTRYPOINT",
            0x00010000: "COMIMAGE_FLAGS_TRACKDEBUGDATA",
            0x00020000: "COMIMAGE_FLAGS_32BITPREFERRED",
        }
        flags = []
        for bit, name in ASSEMBLY_FLAGS.items():
            if flag_value & bit:
                flags.append(name)
        return flags

    def _normalize_data(self, data):
        self.log.debug(inspect.currentframe().f_code.co_name)
        if isinstance(data, str):
            return {"value": data}
        return data

    def _compute_md5(self, data):
        self.log.debug(inspect.currentframe().f_code.co_name)
        if isinstance(data, str):
            # If it's a string, encode it to first
            return md5(data.encode("raw_unicode_escape")).hexdigest()
        elif not isinstance(data, bytes):
            # If it's neither string nor bytes, convert it to string and then to bytes
            return md5(str(data).encode("raw_unicode_escape")).hexdigest()
        else:
            return md5(data).hexdigest()

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

    def extract(self):
        self.log.debug(inspect.currentframe().f_code.co_name)
        metadata = {}

        if self.error:
            metadata["Corrupted"] = self.error.args[0]
            dotnet = PEDotNet(metadata)
            self.dotnet = dotnet  # Store for later use in prepare_export_data
            return dotnet  # Return the extracted data instead of exporting directly

        metadata["info"] = {}
        try:
            available_tables = self.dotnet.existent_metadata_tables()
        except Exception as e:
            self.log.error(f"Error getting metadata tables for {self.hash.sha256}: {e}")
            available_tables = []
            metadata["info"]["PotentiallyCorrupted"] = True

        # GUID extraction
        try:
            input_string = self.dotnet.guid_stream_guids[0].string_representation
            
            formatted_uuid = (
                f"{input_string[6:8]}{input_string[4:6]}{input_string[2:4]}{input_string[0:2]}"
                f"-{input_string[10:12]}{input_string[8:10]}"
                f"-{input_string[14:16]}{input_string[12:14]}"
                f"-{input_string[16:20]}"
                f"-{input_string[20:]}"
            )
            metadata["info"]["ModuleVersionID"] = formatted_uuid
        except Exception as e:
            self.log.error(f"Error extracting GUID for {self.hash.sha256}: {e}")

        # CLR Version
        try:
            metadata["info"]["CLRversion"] = self.dotnet.get_runtime_target_version()
        except Exception as e:
            self.log.error(f"Error getting CLR version for {self.hash.sha256}: {e}")

        # Module information
        try:
            if self.dotnet.metadata_table_exists("Module"):
                metadata["info"]["AssemblyModuleName"] = self.dotnet.Module.get_module_name()
        except Exception as e:
            self.log.error(f"Error getting module info for {self.hash.sha256}: {e}")

        # Basic properties
        try:
            metadata["info"].update({
                "IsNativeNgenImage": self.dotnet.is_native_image(),
                "IsMixedAssembly": self.dotnet.is_mixed_assembly(),
                "IsWindowsFormsApp": self.dotnet.is_windows_forms_app(),
                "EntryPointToken": self.dotnet.clr_header.EntryPointToken.value,
                "HasNativeEntryPoint": self.dotnet.has_native_entry_point(),
            })
        except Exception as e:
            self.log.error(f"Error getting basic properties for {self.hash.sha256}: {e}")

        # Assembly flags
        try:
            metadata["info"]["AssemblyFlags"] = self._decode_assembly_flags(
                self.dotnet.clr_header.Flags.value
            )
        except Exception as e:
            self.log.error(f"Error getting assembly flags for {self.hash.sha256}: {e}")

        # More Metadata/Info CLR Header
        try:
            metadata["info"]["NumOfStreams"] = self.dotnet.get_number_of_streams()
            # [TODO] The following two on VT are "RVA entry point"
            #  and "Resources va" respectively. To verify.
            metadata["info"][
                "ResourcesDirectoryAddress"
            ] = self.dotnet.clr_header.ResourcesDirectoryAddress.value
            metadata["info"][
                "ResourcesDirectorySize"
            ] = self.dotnet.clr_header.ResourcesDirectorySize.value
            metadata["info"][
                "StrongNameSignatureAddress"
            ] = self.dotnet.clr_header.StrongNameSignatureAddress.value
            metadata["info"][
                "StrongNameSignatureSize"
            ] = self.dotnet.clr_header.StrongNameSignatureSize.value
            metadata["info"][
                "CodeManagerTableAddress"
            ] = self.dotnet.clr_header.CodeManagerTableAddress.value
            metadata["info"][
                "CodeManagerTableSize"
            ] = self.dotnet.clr_header.CodeManagerTableSize.value
            metadata["info"][
                "VTableFixupsAddress"
            ] = self.dotnet.clr_header.VTableFixupsAddress.value
            metadata["info"][
                "VTableFixupsSize"
            ] = self.dotnet.clr_header.VTableFixupsSize.value
            metadata["info"][
                "ExportAddressTableJumpsAddress"
            ] = self.dotnet.clr_header.ExportAddressTableJumpsAddress.value
            metadata["info"][
                "ExportAddressTableJumpsSize"
            ] = self.dotnet.clr_header.ExportAddressTableJumpsSize.value
            metadata["info"][
                "ManagedNativeHeaderAddress"
            ] = self.dotnet.clr_header.ManagedNativeHeaderAddress.value
            metadata["info"][
                "ManagedNativeHeaderSize"
            ] = self.dotnet.clr_header.ManagedNativeHeaderSize.value
        except Exception as e:
            self.log.error(f"Error getting more metadata/info clr header for {self.hash.sha256}: {e}")

        # Streams section
        try:
            metadata["Streams"] = {}
            stream_names = self.dotnet.get_stream_names()
            for name in stream_names:
                indx = stream_names.index(name)
                stream_header = self.dotnet.dotnet_stream_headers[indx]
                stream_address = self.dotnet.dotnet_streams[indx].address
                metadata["Streams"][name] = {}
                metadata["Streams"][name]["raw_name"] = base64.b64encode(
                    stream_header.Name.value
                ).decode()
                # metadata["Streams"][name]["raw_name"] = name
                metadata["Streams"][name]["size"] = stream_header.Size.value
                # Retrieve the stream data directly using the given address and size
                stream_data = self.pe.get_data(stream_address, stream_header.Size.value)
                metadata["Streams"][name]["entropy"] = (
                    "%.2f" % pefile.SectionStructure.entropy_H(self.pe, stream_data)
                )
                metadata["Streams"][name]["md5"] = md5(stream_data).hexdigest()
        except Exception as e:
            self.log.error(f"Error getting streams for {self.hash.sha256}: {e}")

        # ManifestResource
        try:
            metadata["ManifestResource"] = ()
            if "ManifestResource" in available_tables:
                metadata["info"]["HasManifestResource"] = True
                metadata["ManifestResource"] = (
                    self.dotnet.ManifestResource.get_resource_names()
                )
        except Exception as e:
            self.log.error(f"Error getting manifest resource for {self.hash.sha256}: {e}")

        # ExternalAssemblyRef
        try:
            metadata["ExternalAssemblyRef"] = {}
            if "AssemblyRef" in available_tables:
                metadata["ExternalAssemblyRef"][
                    "names"
                ] = self.dotnet.AssemblyRef.get_assemblyref_names()
                metadata["ExternalAssemblyRef"][
                    "cultures"
                ] = self.dotnet.AssemblyRef.get_assemblyref_cultures()
        except Exception as e:
            self.log.error(f"Error getting external assembly ref for {self.hash.sha256}: {e}")

        # AssemblyData
        try:
            metadata["AssemblyData"] = {}
            if "Assembly" in available_tables:
                metadata["AssemblyData"][
                    "name"
                ] = self.dotnet.Assembly.get_assembly_name()
                # It's officially a one-row table, but there are ITW files with more than one row.
                # It stores information about the current assembly. It is documented in ECMA-335.
                assembly_table = self.dotnet.metadata_tables_lookup[
                    "Assembly"
                ].table_rows[0]
                metadata["AssemblyData"][
                    "MajorVersion"
                ] = assembly_table.MajorVersion.value
                metadata["AssemblyData"][
                    "MinorVersion"
                ] = assembly_table.MinorVersion.value
                metadata["AssemblyData"]["hashalgid"] = assembly_table.HashAlgId.value
                metadata["AssemblyData"][
                    "BuildNumber"
                ] = assembly_table.BuildNumber.value
                metadata["AssemblyData"][
                    "RevisionNumber"
                ] = assembly_table.RevisionNumber.value
                metadata["AssemblyData"][
                    "culture"
                ] = self.dotnet.Assembly.get_assembly_culture()
        except Exception as e:
            self.log.error(f"Error getting assembly data for {self.hash.sha256}: {e}")

        # TypeDef handling
        try:
            metadata["TypeDef"] = {}
            if "TypeDef" in available_tables:
                metadata["info"]["HasTypeDef"] = True
                # Get basic type definitions
                try:
                    # Get all types (ANY visibility)
                    type_defs = self.dotnet.TypeDef.get_type_names()
                    metadata["TypeDef"]["names"] = type_defs if type_defs else []
                    
                    # Get detailed type information with methods
                    types_with_methods = self.dotnet.TypeDef.get_type_names_with_methods()
                    if types_with_methods:
                        metadata["TypeDef"]["detailed"] = []
                        for type_info in types_with_methods:
                            type_data = {
                                "type": type_info.Type,
                                "namespace": type_info.Namespace,
                                "flags": type_info.Flags,
                                "methods": []
                            }
                            for method in type_info.Methods:
                                method_data = {
                                    "name": method.Name,
                                    "flags": method.Flags
                                }
                                if method.Signature:
                                    method_data["signature"] = {
                                        "parameters": method.Signature.get("parameter", []),
                                        "return_type": method.Signature.get("return", ""),
                                        "has_this": method.Signature.get("hasthis", False)
                                    }
                                type_data["methods"].append(method_data)
                            metadata["TypeDef"]["detailed"].append(type_data)
                except AttributeError as e:
                    self.log.warning(f"TypeDef table exists but attributes missing for {self.hash.sha256}: {e}")
                    # metadata["info"]["TypeDefParsingError"] = f"Missing attributes: {str(e)}"
                except Exception as e:
                    self.log.error(f"Error parsing TypeDef table for {self.hash.sha256}: {e}")
                    # metadata["info"]["TypeDefParsingError"] = str(e)
        except Exception as e:
            self.log.error(f"Error handling TypeDef section for {self.hash.sha256}: {e}")
            metadata["TypeDef"] = {"names": [], "detailed": []}
            # metadata["info"]["TypeDefParsingError"] = str(e)

        # ExternalUnmanagedModules
        try:
            metadata["ExternalUnmanagedModules"] = ()
            if "ModuleRef" in available_tables:
                metadata["info"]["HasModuleRef"] = True
                metadata["ExternalUnmanagedModules"] = (
                    self.dotnet.ModuleRef.get_unmanaged_module_names(
                        self.dotnet.Type.UnmanagedModules.RAW
                    )
                )
        except Exception as e:
            self.log.error(f"Error getting external unmanaged modules for {self.hash.sha256}: {e}")

        # ExternalUnmanagedMethods
        try:
            metadata["ExternalUnmanagedMethods"] = ()
            if "ImplMap" in available_tables:
                metadata["info"]["HasImplMap"] = True
                metadata["ExternalUnmanagedMethods"] = (
                    self.dotnet.ImplMap.get_unmanaged_functions()
                )
        except Exception as e:
            self.log.error(f"Error getting external unmanaged methods for {self.hash.sha256}: {e}")

        # Event
        try:
            metadata["Event"] = ()
            if "Event" in available_tables:
                metadata["info"]["HasEvent"] = True
                metadata["Event"] = self.dotnet.Event.get_event_names()
        except Exception as e:
            self.log.error(f"Error getting event for {self.hash.sha256}: {e}")

        # Resources
        try:
            metadata["Resources"] = []
            if self.dotnet.has_resources():
                tmp_resources_list = []
                resource_data = self.dotnet.get_resources()
                for data in resource_data:
                    tmp_dict = {}
                    for resource_item in data.items():
                        if resource_item[0] == "SubResources":
                            if resource_item[1]:
                                tmp_dict["SubResources"] = {}
                                for sub_resource in resource_item[1]:
                                    for sub_resource_item in sub_resource.items():
                                        if sub_resource_item[0] == "Data":
                                            # Check if data is a sequence type that supports len()
                                            if hasattr(sub_resource_item[1], '__len__') and len(sub_resource_item[1]) > 100:
                                                tmp_dict["SubResources"]["Data"] = {}
                                                try:
                                                    # tmp_dict["SubResources"]["Data"][
                                                    #     "md5"
                                                    # ] = md5(
                                                    #     sub_resource_item[1].encode()
                                                    # ).hexdigest()
                                                    tmp_dict["SubResources"]["Data"][
                                                        "md5"
                                                    ] = self._compute_md5(
                                                        sub_resource_item[1]
                                                    )
                                                except Exception as e:
                                                    self.log.error(
                                                        f"Error in dotnet resources"
                                                        f" extraction {self.hash.sha256}: {e}"
                                                    )
                                                guess = magic.from_buffer(
                                                    sub_resource_item[1], mime=True
                                                )
                                                tmp_dict["SubResources"]["Data"][
                                                    "MimeType"
                                                ] = (guess if guess else None)
                                            else:
                                                normalized_data = self._normalize_data(
                                                    sub_resource_item[1].decode()
                                                    if isinstance(
                                                        sub_resource_item[1], bytes
                                                    )
                                                    else sub_resource_item[1]
                                                )
                                                tmp_dict["SubResources"][
                                                    sub_resource_item[0]
                                                ] = normalized_data
                                        else:
                                            tmp_dict["SubResources"][
                                                sub_resource_item[0]
                                            ] = (
                                                sub_resource_item[1].decode()
                                                if isinstance(
                                                    sub_resource_item[1], bytes
                                                )
                                                else sub_resource_item[1]
                                            )
                        elif resource_item[0] == "Data":
                            # Check if data is a sequence type that supports len()
                            if hasattr(resource_item[1], '__len__') and len(resource_item[1]) > 100:
                                tmp_dict["Data"] = {}
                                tmp_dict["Data"]["md5"] = self._compute_md5(
                                    resource_item[1]
                                )
                                guess = magic.from_buffer(resource_item[1], mime=True)
                                tmp_dict["Data"]["MimeType"] = guess if guess else None
                            else:
                                normalized_data = self._normalize_data(
                                    resource_item[1].decode()
                                    if isinstance(resource_item[1], bytes)
                                    else resource_item[1]
                                )
                                tmp_dict["Data"] = normalized_data
                        else:
                            tmp_dict[resource_item[0]] = (
                                resource_item[1].decode()
                                if isinstance(resource_item[1], bytes)
                                else resource_item[1]
                            )
                    tmp_resources_list.append(tmp_dict)
                metadata["Resources"] = tmp_resources_list
        except Exception as e:
            self.log.error(f"Error getting resources for {self.hash.sha256}: {e}")
            metadata["Resources"] = []  # Ensure we always have a valid list even on error

        dotnet = PEDotNet(metadata)
        self.dotnet = dotnet  # Store for later use in prepare_export_data
        return dotnet  # Return the extracted data instead of exporting directly


    def prepare_export_data(self, exporter_type: str) -> Any:
        if exporter_type == "ElasticsearchExporter":
            return self.dotnet
        elif exporter_type == "ClickHouseExporter":
            # Convert metadata to JSON string
            metadata_json = json.dumps(self.dotnet.dotnet)
            
            data = [[
                self.sha256,
                self.md5,
                self.sha1,
                metadata_json,
                datetime.now(timezone.utc)
            ]]
            
            column_names = [
                'sha256', 'md5', 'sha1', 'dotnet', 'analysis_date'
            ]
            
            if not data:
                return None

            column_type_names = [
                'String', 'String', 'String', 'JSON', 'DateTime64(3, \'UTC\')'
            ]

            return (data, column_names, column_type_names)

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