Olaf Maennel

93 papers A* 13A 13B 8C 2Misc 6Journal 30Unranked 19
YearRankTypeTitle / Venue / Authors
2026 A* conf
WWW
Liangwei Nathan Zheng, Wenhao Liang, Wei Emma Zhang, Miao Xu, Olaf Maennel, Weitong Chen
2026 J jnl
CoRR
Zhifang Zhang, Bojun Yang, Shuo He, Weitong Chen, Wei Emma Zhang, Olaf Maennel, Lei Feng, Miao Xu
2025 conf
VTC2025-Spring
Andrew Roberts, Jingyue Cheng, Olaf Maennel, Mohammad Hamad, Sebastian Steinhorst
2025 A conf
CIKM
Liangwei Nathan Zheng, Wei Emma Zhang, Lin Yue, Miao Xu, Olaf Maennel, Weitong Chen
2025 conf
VTC2025-Spring
Andrew Roberts, Mohsen Malayjerdi, Mauro Bellone, Raivo Sell, Olaf Maennel, Mohammad Hamad, Sebastian Steinhorst
2025 conf
SEAMS@ICSE
Andrew Roberts, Mohsen Malayjerdi, Mauro Bellone, Raivo Sell, Olaf Maennel, Mohammad Hamad, Sebastian Steinhorst
2025 A conf
CIKM
Wenhao Liang, Wei Emma Zhang, Lin Yue, Miao Xu, Olaf Maennel, Weitong Chen
2025 A conf
CIKM
Wenhao Liang, Wei Emma Zhang, Lin Yue, Miao Xu, Olaf Maennel, Weitong Chen
2025 J jnl
CoRR
Wenhao Liang, Wei Emma Zhang, Lin Yue, Miao Xu, Olaf Maennel, Weitong Chen
2025 J jnl
CoRR
Liangwewi Nathan Zheng, Wei Emma Zhang, Lin Yue, Miao Xu, Olaf Maennel, Weitong Chen
2025 J jnl
CoRR
Andrew Roberts, Lorenz Teply, Mert D. Pesé, Olaf Maennel, Mohammad Hamad, Sebastian Steinhorst
2025 J jnl
ACM Trans. Comput. Educ.
Kaie Maennel, Olaf Maennel
2025 J jnl
CoRR
Liangwei Nathan Zheng, Wenhao Liang, Wei Emma Zhang, Miao Xu, Olaf Maennel, Weitong Chen
2025 Misc conf
CSR
Muhammed Erbas, Gábor Visky, Olaf Maennel, Leonidas Tsiopoulos, Risto Vaarandi
2025 J jnl
CoRR
Wenhao Liang, Wei Emma Zhang, Lin Yue, Miao Xu, Olaf Maennel, Weitong Chen
2025 J jnl
CoRR
Liangwei Nathan Zheng, Wei Emma Zhang, Mingyu Guo, Miao Xu, Olaf Maennel, Weitong Chen
2025 J jnl
Dagstuhl Artifacts Ser.
Andreas Finkenzeller, Andrew Roberts, Mauro Bellone, Olaf Maennel, Mohammad Hamad, Sebastian Steinhorst
2025 B conf
ECRTS
Andreas Finkenzeller, Andrew Roberts, Mauro Bellone, Olaf Maennel, Mohammad Hamad, Sebastian Steinhorst
2025 A* conf
SP
Bradley Morgan, Gal Horowitz, Sioli O'Connell, Stephan van Schaik, Chitchanok Chuengsatiansup, Daniel Genkin, Olaf Maennel, Paul Montague, Eyal Ronen, Yuval Yarom
2025 J jnl
CoRR
Bradley Morgan, Gal Horowitz, Sioli O'Connell, Stephan van Schaik, Chitchanok Chuengsatiansup, Daniel Genkin, Olaf Maennel, Paul Montague, Eyal Ronen, Yuval Yarom
2025 conf
KDD (2)
Liangwei Nathan Zheng, Chang George Dong, Wei Emma Zhang, Lin Yue, Miao Xu, Olaf Maennel, Weitong Chen
2025 J jnl
CoRR
Wenhao Liang, Wei Zhang, Yue Lin, Miao Xu, Olaf Maennel, Weitong Chen
2024 A conf
DATE
Andrew Roberts, Mohammad Reza Heidari Iman, Mauro Bellone, Tara Ghasempouri, Jaan Raik, Olaf Maennel, Mohammad Hamad, Sebastian Steinhorst
2024 conf
CyCon
Erwin Orye, Gábor Visky, Alexander Rohl, Olaf Maennel
2024 A conf
CIKM
Liangwei Nathan Zheng, Zhengyang Li, Chang George Dong, Wei Emma Zhang, Lin Yue, Miao Xu, Olaf Maennel, Weitong Chen
2024 J jnl
CoRR
Liangwei Nathan Zheng, Zhengyang Li, Chang George Dong, Wei Emma Zhang, Lin Yue, Miao Xu, Olaf Maennel, Weitong Chen
2024 Misc conf
CSR
Gábor Visky, Sokratis K. Katsikas, Olaf Maennel
2024 Misc conf
SISY
Gábor Visky, Adam Balint, Risto Vaarandi, Mauno Pihelgas, Olaf Maennel
2024 J jnl
CoRR
Mohammad Hamad, Andreas Finkenzeller, Michael Kühr, Andrew Roberts, Olaf Maennel, Vassilis Prevelakis, Sebastian Steinhorst
2024 J jnl
Comput. Secur.
Mohammad Hamad, Andreas Finkenzeller, Michael Kühr, Andrew Roberts, Olaf Maennel, Vassilis Prevelakis, Sebastian Steinhorst
2024 J jnl
CoRR
Liangwei Nathan Zheng, Chang George Dong, Wei Emma Zhang, Lin Yue, Miao Xu, Olaf Maennel, Weitong Chen
2024 C conf
ICISSP
Pavel Chikul, Hayretdin Bahsi, Olaf Maennel
2023 conf
VehicleSec
Andrew Roberts, Mohsen Malayjerdi, Mauro Bellone, Olaf Maennel, Ehsan Malayjerdi
2021 C conf
MEDI
Pavel Chikul, Hayretdin Bahsi, Olaf Maennel
2021 conf
EuroS&P Workshops
Andrew Roberts, Olaf Maennel, Nikita Snetkov
2021 Misc conf
CogSIMA
Yazeed Haddad, Erwin Orye, Olaf Maennel
2020 conf
MetroInd4.0&IoT
Clifford Brown, Tommi Elo, Kristine Hovhannisyan, Daniel Hutzschenreuter, Petri Kuosmanen, Olaf Maennel, Tuukka Mustapää, Pekka Nikander, Thomas Wiedenhoefer
2019 J jnl
Int. J. Crit. Infrastructure Prot.
Luis-Carlos Herrera, Olaf Maennel
2019 J jnl
J. Digit. Forensics Secur. Law
Jens Getreu, Olaf Maennel
2018 conf
HCI (25)
Toomas Lepik, Kaie Maennel, Margus Ernits, Olaf Maennel
2018 conf
NordSec
Kaie Maennel, Sten Mäses, Olaf Maennel
2018 conf
HCI (25)
Sten Mäses, Liina Randmann, Olaf Maennel, Birgy Lorenz
2017 conf
NordSec
Kaie Maennel, Rain Ottis, Olaf Maennel
2017 A ed.
Internet Measurement Conference
Steve Uhlig, Olaf Maennel
2017 J jnl
Ann. des Télécommunications
Haider Abbas, Olaf Maennel, Saïd Assar
2016 conf
INFOCOM Workshops
Jun Li, Joshua Stein, Mingwei Zhang, Olaf Maennel
2016 conf
NordSec
Bernhards Blumbergs, Mauno Pihelgas, Markus Kont, Olaf Maennel, Risto Vaarandi
2016 J jnl
IEEE/ACM Trans. Netw.
Andra Lutu, Marcelo Bagnulo, Cristel Pelsser, Olaf Maennel, Jesús Cid-Sueiro
2015 A* ed.
SIGCOMM
Steve Uhlig, Olaf Maennel, Brad Karp, Jitendra Padhye
2015 Misc conf
HotNets
Matthias Wählisch, Robert Schmidt, Thomas C. Schmidt, Olaf Maennel, Steve Uhlig, Gareth Tyson
2015 A* conf
SIGCOMM
Margus Ernits, Johannes Tammekänd, Olaf Maennel
2014 J jnl
IEEE/ACM Trans. Netw.
Nejc Skoberne, Olaf Maennel, Iain Phillips, Randy Bush, Jan Zorz, Mojca Ciglaric
2014 J jnl
RFC
Cristel Pelsser, Randy Bush, Keyur Patel, Pradosh Mohapatra, Olaf Maennel
2014 A* conf
INFOCOM
Andra Lutu, Marcelo Bagnulo, Jesús Cid-Sueiro, Olaf Maennel
2014 B conf
PAM
Andra Lutu, Marcelo Bagnulo, Cristel Pelsser, Olaf Maennel
2014 J jnl
CoRR
Matthias Wählisch, Robert Schmidt, Thomas C. Schmidt, Olaf Maennel, Steve Uhlig
2013 J jnl
it Inf. Technol.
Debbie Perouli, Olaf Maennel, Iain Phillips, Sonia Fahmy, Randy Bush, Rob Austein
2013 A conf
CoNEXT
Simon Knight, Hung X. Nguyen, Olaf Maennel, Iain Phillips, Nickolas J. G. Falkner, Randy Bush, Matthew Roughan
2013 conf
INFOCOM Workshops
Andra Lutu, Marcelo Bagnulo, Olaf Maennel
2013 A* conf
INFOCOM
Andra Lutu, Marcelo Bagnulo, Olaf Maennel
2012 A* conf
SIGCOMM
Simon Knight, Askar Jaboldinov, Olaf Maennel, Iain Phillips, Matthew Roughan
2012 B conf
ICNP
Debbie Perouli, Timothy G. Griffin, Olaf Maennel, Sonia Fahmy, Iain Phillips, Cristel Pelsser
2012 B conf
ICNP
Debbie Perouli, Timothy G. Griffin, Olaf Maennel, Sonia Fahmy, Cristel Pelsser, Alexander J. T. Gurney, Iain Phillips
2012 B conf
ICNP
Debbie Perouli, Stefano Vissicchio, Alexander J. T. Gurney, Olaf Maennel, Timothy G. Griffin, Iain Phillips, Sonia Fahmy, Cristel Pelsser
2012 conf
CSET
Olaf Maennel, Iain Phillips, Debbie Perouli, Randy Bush, Rob Austein, Askar Jaboldinov
2012 A* conf
SIGCOMM
Matthias Wählisch, Olaf Maennel, Thomas C. Schmidt
2011 J jnl
IEEE J. Sel. Areas Commun.
Matthew Roughan, Walter Willinger, Olaf Maennel, Debbie Perouli, Randy Bush
2011 B conf
PAM
Cristel Pelsser, Olaf Maennel, Pradosh Mohapatra, Randy Bush, Keyur Patel
2011 B conf
Networking (1)
Iuniana Oprescu, Mickael Meulle, Steve Uhlig, Cristel Pelsser, Olaf Maennel, Philippe Owezarski
2010 J jnl
IEEE J. Sel. Areas Commun.
Luca Cittadini, Wolfgang Mühlbauer, Steve Uhlig, Randy Bush, Pierre François, Olaf Maennel
2010 Misc conf
TRIDENTCOM
Hung X. Nguyen, Matthew Roughan, Simon Knight, Nick Falkner, Olaf Maennel, Randy Bush
2010 J jnl
Comput. Networks
Wolfgang Mühlbauer, Steve Uhlig, Anja Feldmann, Olaf Maennel, Bruno Quoitin, Bingjie Fu
2010 ed.
StudentWorkshop@CoNEXT
Philip Brighten Godfrey, Chuanxiong Guo, Olaf Maennel
2010 A* conf
SIGCOMM
Iuniana Oprescu, Mickael Meulle, Steve Uhlig, Cristel Pelsser, Olaf Maennel, Philippe Owezarski
2009 conf
ReArch@CoNEXT
Anja Feldmann, Luca Cittadini, Wolfgang Mühlbauer, Randy Bush, Olaf Maennel
2009 A conf
Internet Measurement Conference
Randy Bush, Olaf Maennel, Matthew Roughan, Steve Uhlig
2009 J jnl
ERCIM News
Anja Feldmann, Mario Kind, Olaf Maennel, Gregor Schaffrath, Christoph Werle
2009 conf
VISA
Gregor Schaffrath, Christoph Werle, Panagiotis Papadimitriou, Anja Feldmann, Roland Bless, Adam Greenhalgh, Andreas Wundsam, Mario Kind, Olaf Maennel, Laurent Mathy
2009 A conf
ITC
Hamed Haddadi, Damien Fay, Almerima Jamakovic, Olaf Maennel, Andrew W. Moore, Richard Mortier, Steve Uhlig
2008 J jnl
CoRR
Hamed Haddadi, Damien Fay, Almerima Jamakovic, Olaf Maennel, Andrew W. Moore, Richard Mortier, Miguel Rio, Steve Uhlig
2008 A conf
Internet Measurement Conference
Matthew Roughan, Simon Jonathan Tuke, Olaf Maennel
2008 A conf
Internet Measurement Conference
Andrew Coyle, Miro Kraetzl, Olaf Maennel, Matthew Roughan
2007 A* conf
SIGCOMM
Wolfgang Mühlbauer, Steve Uhlig, Bingjie Fu, Mickael Meulle, Olaf Maennel
2007 A conf
ITC
Ashley Flavel, Matthew Roughan, Nigel G. Bean, Olaf Maennel
2007 conf
INM@SIGCOMM
Randy Bush, James Hiebert, Olaf Maennel, Matthew Roughan, Steve Uhlig
2006 A* conf
SIGCOMM
Wolfgang Mühlbauer, Anja Feldmann, Olaf Maennel, Matthew Roughan, Steve Uhlig
2005
Olaf Maennel
2004 A conf
Internet Measurement Conference
Anja Feldmann, Nils Kammenhuber, Olaf Maennel, Bruce M. Maggs, Roberto De Prisco, Ravi Sundaram
2004 A* conf
SIGCOMM
Anja Feldmann, Olaf Maennel, Zhuoqing Morley Mao, Arthur W. Berger, Bruce M. Maggs
2004 B conf
PAM
Anja Feldmann, Hongwei Kong, Olaf Maennel, Alexander Tudor
2003 J jnl
Comput. Commun. Rev.
Vinay Aggarwal, Olaf Maennel, Jeffrey C. Mogul, Allyn Romanow
2002 J jnl
Comput. Commun. Rev.
Olaf Maennel, Anja Feldmann
2002 A* conf
SIGCOMM
Olaf Maennel, Anja Feldmann
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"