Carlo Tomasi

109 papers A* 29A 5B 2Misc 7Journal 38Unranked 28
YearRankTypeTitle / Venue / Authors
2025 J jnl
CoRR
Jack Goffinet, Youngjo Min, Carlo Tomasi, David E. Carlson
2024 J jnl
CoRR
Kelsey Lieberman, Shuai Yuan, Swarna Kamlam Ravindran, Carlo Tomasi
2024 J jnl
CoRR
Kelsey Lieberman, Swarna Kamlam Ravindran, Shuai Yuan, Carlo Tomasi
2023 J jnl
CoRR
Swarna Kamlam Ravindran, Carlo Tomasi
2023 A* conf
ICCV
Shuai Yuan, Shuzhi Yu, Hannah Kim, Carlo Tomasi
2023 J jnl
CoRR
Shuai Yuan, Shuzhi Yu, Hannah Kim, Carlo Tomasi
2023 J jnl
CoRR
Shuai Yuan, Carlo Tomasi
2022 conf
ACCV (Workshops)
Hannah Halin Kim, Shuzhi Yu, Shuai Yuan, Carlo Tomasi
2022 J jnl
CoRR
Hannah Halin Kim, Shuzhi Yu, Shuai Yuan, Carlo Tomasi
2022 conf
ECCV (22)
Shuai Yuan, Xian Sun, Hannah Kim, Shuzhi Yu, Carlo Tomasi
2022 J jnl
CoRR
Shuai Yuan, Xian Sun, Hannah Kim, Shuzhi Yu, Carlo Tomasi
2022 A conf
BMVC
Shuzhi Yu, Hannah Halin Kim, Shuai Yuan, Carlo Tomasi
2022 J jnl
CoRR
Shuzhi Yu, Hannah Halin Kim, Shuai Yuan, Carlo Tomasi
2021 A conf
BMVC
Hannah Halin Kim, Shuzhi Yu, Carlo Tomasi
2021 J jnl
CoRR
Hannah Halin Kim, Shuzhi Yu, Carlo Tomasi
2019 J jnl
CoRR
Shuzhi Yu, Carlo Tomasi
2019 conf
CVPR Workshops
Cassandra Carley, Ergys Ristani, Carlo Tomasi
2018 A* conf
CVPR
Ergys Ristani, Carlo Tomasi
2018 J jnl
CoRR
Ergys Ristani, Carlo Tomasi
2017 J jnl
IEEE Trans. Circuits Syst. Video Technol.
Francesco Solera, Simone Calderara, Ergys Ristani, Carlo Tomasi, Rita Cucchiara
2016 J jnl
IEEE Trans. Medical Imaging
Roger S. Zou, Carlo Tomasi
2016 A* conf
AAAI
Benjamin Burchfiel, Carlo Tomasi, Ronald Parr
2016 J jnl
CoRR
Ergys Ristani, Francesco Solera, Roger S. Zou, Rita Cucchiara, Carlo Tomasi
2016 conf
ECCV Workshops (2)
Ergys Ristani, Francesco Solera, Roger S. Zou, Rita Cucchiara, Carlo Tomasi
2015 J jnl
IEEE Trans. Medical Imaging
Rolando Estrada, Michael J. Allingham, Priyatham S. Mettu, Scott W. Cousins, Carlo Tomasi, Sina Farsiu
2015 conf
ICCV Workshops
Cassandra Carley, Carlo Tomasi
2015 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Rolando Estrada, Carlo Tomasi, Scott C. Schmidler, Sina Farsiu
2014 conf
ACCV (5)
Ergys Ristani, Carlo Tomasi
2013 J jnl
Mach. Vis. Appl.
Joaquín Salas, Carlo Tomasi
2013 A* conf
ICCV
Susanna Ricco, Carlo Tomasi
2012 A* conf
CVPR
Susanna Ricco, Carlo Tomasi
2012 conf
ECCV (4)
Ying Zheng, Steve Gu, Carlo Tomasi
2012 conf
ECCV (2)
Steve Gu, Ying Zheng, Carlo Tomasi
2012 Misc conf
ICASSP
Steve Gu, Ying Zheng, Carlo Tomasi
2012 Misc conf
ICASSP
Steve Gu, Ying Zheng, Carlo Tomasi
2012 conf
ECCV (6)
Susanna Ricco, Carlo Tomasi
2012 Misc conf
ICASSP
Ying Zheng, Steve Gu, Carlo Tomasi
2012 A* conf
CVPR
Steve Gu, Ying Zheng, Carlo Tomasi
2011 A* conf
CVPR
Steve Gu, Carlo Tomasi
2011 A* conf
ICCV
Ying Zheng, Steve Gu, Herbert Edelsbrunner, Carlo Tomasi, Philip Benfey
2011 A* conf
ACM Multimedia
Ying Zheng, Steve Gu, Carlo Tomasi
2011 A* conf
ICCV
Steve Gu, Ying Zheng, Carlo Tomasi
2011 conf
MCPR
Joaquín Salas, Carlo Tomasi
2011 J jnl
Commun. ACM
Carlo Tomasi
2010 conf
ECCV (3)
Steve Gu, Ying Zheng, Carlo Tomasi
2010 conf
ACCV (1)
Steve Gu, Ying Zheng, Carlo Tomasi
2010 Misc conf
ICASSP
Seda Remus, Carlo Tomasi
2009 conf
ACCV (3)
Susanna Ricco, Carlo Tomasi
2009 A conf
ICDAR
Rolando Estrada, Carlo Tomasi
2009 Misc conf
ICASSP
Steve Gu, Carlo Tomasi
2008 J jnl
Int. J. Comput. Vis.
Cordelia Schmid, Stefano Soatto, Carlo Tomasi
2008 B conf
ICPR
Tingting Jiang, Carlo Tomasi
2007 J jnl
Image Vis. Comput.
Stanley T. Birchfield, Braga Natarajan, Carlo Tomasi
2007 A* conf
ICCV
Tingting Jiang, Carlo Tomasi
2007 conf
ICDSC
Tingting Jiang, Carlo Tomasi, Scott C. Schmidler
2007 conf
3DIM
Jeff M. Phillips, Ran Liu, Carlo Tomasi
2006 conf
ECCV (3)
Tingting Jiang, Carlo Tomasi
2006 J jnl
CoRR
Jeff M. Phillips, Ran Liu, Carlo Tomasi
2005 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Mark Fashing, Carlo Tomasi
2004 conf
CVPR (2)
Salih Burak Göktürk, Carlo Tomasi
2004 conf
ECCV (3)
Daniel B. Russakoff, Carlo Tomasi, Torsten Rohlfing, Calvin R. Maurer Jr.
2004 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Michael H. Lin, Carlo Tomasi
2003 A* conf
ICCV
Carlo Tomasi, Slav Petrov, Arvind Sastry
2003 J jnl
Commun. ACM
Carlo Tomasi, Abbas Rafii, Ilhami Torunoglu
2003 conf
CVPR (1)
Michael H. Lin, Carlo Tomasi
2003 conf
CHI Extended Abstracts
Helena Roeber, John Bacus, Carlo Tomasi
2002 J jnl
IEEE Trans. Medical Imaging
Burak Acar, Christopher F. Beaulieu, Salih Burak Göktürk, Carlo Tomasi, David S. Paik, R. Brooke Jeffrey Jr., Judy Yee, Sandy Napel
2002 conf
FGR
Salih Burak Göktürk, Carlo Tomasi, Bernd Girod, Jean-Yves Bouguet
2002 J jnl
Int. J. Comput. Vis.
Tong Zhang, Carlo Tomasi
2001 A conf
MICCAI
Salih Burak Göktürk, Carlo Tomasi, Burak Acar, David S. Paik, Christopher F. Beaulieu, Sandy Napel
2001 conf
CVPR (1)
Salih Burak Göktürk, Carlo Tomasi
2001 J jnl
IEEE Trans. Medical Imaging
Salih Burak Göktürk, Carlo Tomasi, Burak Acar, Christopher F. Beaulieu, David S. Paik, R. Brooke Jeffrey Jr., Judy Yee, Sandy Napel
2001 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Mark A. Ruzon, Carlo Tomasi
2001 J jnl
Comput. Vis. Image Underst.
Yossi Rubner, Jan Puzicha, Carlo Tomasi, Joachim M. Buhmann
2001 conf
Bildverarbeitung für die Medizin
Joachim Hornegger, Carlo Tomasi
2001 A conf
MICCAI
Burak Acar, Sandy Napel, David S. Paik, Salih Burak Göktürk, Carlo Tomasi, Christopher F. Beaulieu
2000 A* conf
CVPR
Mark A. Ruzon, Carlo Tomasi
2000 J jnl
Int. J. Comput. Vis.
Yossi Rubner, Carlo Tomasi, Leonidas J. Guibas
1999 A* conf
CVPR
Mark A. Ruzon, Carlo Tomasi
1999 A* conf
ICCV
Mark A. Ruzon, Carlo Tomasi
1999 J jnl
Int. J. Comput. Vis.
Stan Birchfield, Carlo Tomasi
1999 Misc conf
ICIAP
Roberto Manduchi, Carlo Tomasi
1999 A* conf
ICCV
Jan Puzicha, Yossi Rubner, Carlo Tomasi, Joachim M. Buhmann
1999 A* conf
CVPR
Tong Zhang, Carlo Tomasi
1999 Misc conf
ICIAP
Carlo Tomasi, John Zhang
1999 A* conf
ICCV
Stan Birchfield, Carlo Tomasi
1999 A* conf
ICCV
Joachim Hornegger, Carlo Tomasi
1999 A* conf
ICCV
Yossi Rubner, Carlo Tomasi
1998 A* conf
ICCV
Yossi Rubner, Carlo Tomasi, Leonidas J. Guibas
1998 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Stan Birchfield, Carlo Tomasi
1998 conf
ACCV (1)
Yossi Rubner, Carlo Tomasi, Leonidas J. Guibas
1998 A* conf
ICCV
Carlo Tomasi, Roberto Manduchi
1998 A* conf
ICCV
Stan Birchfield, Carlo Tomasi
1998 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Carlo Tomasi, Roberto Manduchi
1998 B conf
SMC
Yossi Rubner, Carlo Tomasi
1997 J jnl
Robotics Auton. Syst.
Illah R. Nourbakhsh, David Andre, Carlo Tomasi, Michael R. Genesereth
1996 A* conf
CVPR
Tina Yu Tian, Carlo Tomasi, David J. Heeger
1996 conf
ECCV (1)
Carlo Tomasi, Roberto Manduchi
1995 conf
ISER
Craig Becker, Héctor H. González-Baños, Jean-Claude Latombe, Carlo Tomasi
1995 conf
ISER
Carlo Tomasi, John Zhang, David Redkey
1995 conf
Storage and Retrieval for Image and Video Databases (SPIE)
Leonidas J. Guibas, Brian Rogoff, Carlo Tomasi
1995 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Daphna Weinshall, Carlo Tomasi
1994 A* conf
CVPR
Jianbo Shi, Carlo Tomasi
1994 A* conf
CVPR
Carlo Tomasi
1993 A* conf
CVPR
Carlo Tomasi, Jianbo Shi
1993 A* conf
ICCV
Daphna Weinshall, Carlo Tomasi
1992 J jnl
Int. J. Comput. Vis.
Carlo Tomasi, Takeo Kanade
1990 A* conf
ICCV
Carlo Tomasi, Takeo Kanade
1984 J jnl
IEEE Trans. Commun.
Silvano Pupolin, Carlo Tomasi
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"