Xiaohui Zhao

67 papers A* 1A 2B 1C 6Misc 1Journal 39Unranked 17
YearRankTypeTitle / Venue / Authors
2026 J jnl
IEEE Trans. Circuits Syst. Video Technol.
Xiaohui Zhao, Xiangyu Meng, Qiyang Li, Xingwang Cai, Deyin Ma, Xiaohu Shi
2025 J jnl
Comput. Electron. Agric.
Jianing Long, Zhao Zhang, Qu Zhang, Xiaohui Zhao, C. Igathinathane, Jianfei Xing, Chayan Kumer Saha, Wenyi Sheng, Han Li, Man Zhang
2025 J jnl
CoRR
Ying Chang, Xiaohu Shi, Xiaohui Zhao, Zhaohuang Chen, Deyin Ma
2025 conf
OFC
Xiaohui Zhao, Trung-Hien Nguyen, Loig Godard, Nayla El Dahdah, Romain Brenot, Sheherazade Lamkadmi Azouigui, Hartmut Hafermann, Massimo Tornatore, Yann Frignac, Sami Mumtaz, Abel Lorences-Riesgo, Gabriel Charlet
2025 J jnl
Biomed. Signal Process. Control.
Hongjin Li, Xiaohui Zhao, Hang Liu, Ziyi Wang, Yukai Cai, Chuanshuai Yang, Fengyu Cong
2025 A* conf
ICLR
Shuo Li, Tao Ji, Xiaoran Fan, Linsheng Lu, Leyi Yang, Yuming Yang, Zhiheng Xi, Rui Zheng, Yuran Wang, Xiaohui Zhao, Tao Gui, Qi Zhang, Xuanjing Huang
2025 conf
ECOC
Salma ElMiz, Maha Bouhadida, Abir Hraghi, Xiaohui Zhao, Loig Godard, Iosif Demirtzioglou, Nayla El Dahdah, Yann Frignac
2025 J jnl
Appl. Soft Comput.
Xiaohui Zhao, Xia Li, Qi Zhao, Bai Yan, Yuhui Shi, Jiajin Kang
2025 conf
ECOC
Xiaohui Zhao, Abir Hraghi, Celestino Sanches Martins, Trung-Hien Nguyen, Iosif Demirtzioglou, Hartmut Hafermann, Massimo Tornatore, Yann Frignac, Sami Mumtaz, Abel Lorences-Riesgo, Gabriel Charlet
2025 conf
OFC
Hartmut Hafermann, Loig Godard, Xiaohui Zhao, Abel Lorences-Riesgo, Zhenzhen Zhang, Romain Brenot, Yann Frignac, Gabriel Charlet
2025 J jnl
IEEE Trans. Consumer Electron.
Ciyuan Peng, Tianqi Guo, Chengyao Xie, Xiaomei Bai, Jingjing Zhou, Xiaohui Zhao, Estrid He, Feng Xia
2024 J jnl
Telecommun. Syst.
Lingling Chen, Ziwei Wang, Xiaohui Zhao, Xuan Shen, Wei He
2024 B conf
IJCNN
Xinhua Wang, Hao Lu, Liancheng Xu, Lei Guo, Xiaohui Zhao
2024 J jnl
BMC Medical Imaging
Zhiqiang Liu, Xiwei Zhang, Xiaohui Zhao, Qianqian Guo, Zhengjiang Li, Minghui Wei, Lijuan Niu, Changming An
2024 J jnl
Pervasive Mob. Comput.
Lingling Chen, Xuan Shen, Xiaohui Zhao, Ziwei Wang, Wei He, Guoji Xu, Yiyang Chen
2024 J jnl
CoRR
Shuo Li, Tao Ji, Xiaoran Fan, Linsheng Lu, Leyi Yang, Yuming Yang, Zhiheng Xi, Rui Zheng, Yuran Wang, Xiaohui Zhao, Tao Gui, Qi Zhang, Xuanjing Huang
2023 J jnl
IEEE Trans. Multim.
Yang Yu, Xiaohui Zhao, Rongrong Ni, Siyuan Yang, Yao Zhao, Alex C. Kot
2023 J jnl
Sensors
Xiaohui Zhao, Leqi Ding, Jingsheng Yan, Jin Xu, Hao He
2023 J jnl
Health Inf. Sci. Syst.
Durgesh Samariya, Jiangang Ma, Sunil Aryal, Xiaohui Zhao
2023 conf
ICONIP (13)
Durgesh Samariya, Jiangang Ma, Sunil Aryal, Xiaohui Zhao
2023 J jnl
Biomed. Signal Process. Control.
Hang Liu, Shaowei Cui, Xiaohui Zhao, Fengyu Cong
2023 conf
OFC
Salma Escobar-Landero, Xiaohui Zhao, Abel Lorences-Riesgo, Dylan Le Gac, Yann Frignac, Gabriel Charlet
2023 conf
OFC
Hartmut Hafermann, Xiaohui Zhao, Shuqi Yu, Yann Frignac
2023 J jnl
IEEE Trans. Comput. Soc. Syst.
Jinpeng Wei, Shaojian Qu, Qiuhan Wang, Dongqing Luan, Xiaohui Zhao
2022 J jnl
IEEE Access
Xiaohui Zhao, Xueqin Shen, Wenbo Wan, Yuanyuan Lu, Shidong Hu, Ruoxiu Xiao, Xiaohui Du, Junlai Li
2022 Misc conf
ICASSP
Xiaohui Zhao, Yang Yu, Rongrong Ni, Yao Zhao
2022 conf
ICEBE
Xiaohui Zhao, Taiwo Oseni, Bhanu Teja Medishetty
2022 J jnl
Sensors
Xiaohui Zhao, Yaowen Zhang, Hao Wang, Yu Liu, Bao Zhang, Shaoyang Hu
2021 conf
ICEBE
Xiaohui Zhao
2021 conf
ISEEIE
Wei Yang, Zhaolin Fan, Xiaobing Deng, Xiaohui Zhao
2020 J jnl
npj Digit. Medicine
Scott D. Tagliaferri, Maia Angelova, Xiaohui Zhao, Patrick J. Owen, Clint T. Miller, Tim Wilkin, Daniel L. Belavy
2020 J jnl
IEEE Trans. Comput. Soc. Syst.
Ping Zhao, Haojun Huang, Xiaohui Zhao, Daiyu Huang
2019 J jnl
Wirel. Networks
Mingyue Zhou, Xiaohui Zhao, Hao Yin
2019 J jnl
CoRR
Xiaohui Zhao, Zhuo Wu, Xiaoguang Wang
2019 J jnl
Comput. Biol. Chem.
Xiaohui Zhao, Yuanyuan Zhao, Zhixing Ren, Yu Li
2019 J jnl
CoRR
Atilim Günes Baydin, Lei Shao, Wahid Bhimji, Lukas Heinrich, Lawrence Meadows, Jialin Liu, Andreas Munk, Saeid Naderiparizi, Bradley Gram-Hansen, Gilles Louppe, Mingfei Ma, Xiaohui Zhao, Philip H. S. Torr, Victor W. Lee, Kyle Cranmer, Prabhat, Frank Wood
2019 A conf
SC
Atilim Günes Baydin, Lei Shao, Wahid Bhimji, Lukas Heinrich, Lawrence Meadows, Jialin Liu, Andreas Munk, Saeid Naderiparizi, Bradley Gram-Hansen, Gilles Louppe, Mingfei Ma, Xiaohui Zhao, Philip H. S. Torr, Victor W. Lee, Kyle Cranmer, Prabhat, Frank Wood
2018 C conf
APCC
Xu He, Suying Cui, Xiaohui Zhao
2018 A conf
ICDCS
Xiaohui Zhao, Jianguo Yao, Ping Gao, Haibing Guan
2018 J jnl
IEEE Netw.
Xiaohui Zhao, Hanyang Ma, Yuan Jin, Jianguo Yao
2017 J jnl
J. Inf. Process. Syst.
Mingyue Zhou, Xiaohui Zhao
2017 J jnl
Wirel. Pers. Commun.
Mingyue Zhou, Xiaohui Zhao
2017 conf
CSE/EUC (1)
Xiaohui Zhao, Sai Guo, Yanlei Wang
2017 C conf
ICCC
Munyaradzi Munochiveyi, Xiaohui Zhao, Joseph Mudare
2016 J jnl
J. Ambient Intell. Humaniz. Comput.
Jialing Han, Xiaohui Zhao, Chunyan Qiu
2016 C conf
QSHINE
Xiaohui Zhao, Liqiang Zhao, Kai Liang
2016 J jnl
IET Image Process.
Yong Wang, Yuqing Wang, Xiaohui Zhao
2016 J jnl
IET Commun.
Mingyue Zhou, Xiaohui Zhao
2014 J jnl
Comput. Electr. Eng.
Yanping Zhao, Xiaohui Zhao, Bo Wang
2014 J jnl
IEICE Electron. Express
Yang Li, Xiaowen Chen, Xiaohui Zhao, Yong Yang, Hengzhu Liu
2013 conf
EIDWT
Jialinh Han, Xiaohui Zhao
2013 conf
NAS
Xiaohui Zhao, Xinlong Luo, Tong Wu, Dengkun Xiao
2012 J jnl
Int. J. Circuit Theory Appl.
Xiaokuo Yang, Li Cai, Hongtu Huang, Xiaohui Zhao
2012 J jnl
Int. J. Circuit Theory Appl.
Xiaokuo Yang, Li Cai, Hongtu Huang, Xiaohui Zhao
2012 J jnl
Microelectron. J.
Xiaokuo Yang, Li Cai, Qiang Kang, Xiaohui Zhao
2012 J jnl
J. Softw.
Hong Jiang, Yu Zhang, Hongjun Liu, Xiaohui Zhao, Chang Liu
2010 J jnl
Microelectron. J.
Xiaokuo Yang, Li Cai, Xiaohui Zhao, Nansheng Zhang
2010 C conf
CIS
Xiaohui Zhao, Liaojun Pang, Jingjuan Bi, Qingqi Pei, Huixian Li
2010 conf
ICEE
Hongni Dong, Jiang Wu, Xiaohui Zhao, Yanfen Li
2007 conf
GCC
Xiaohui Zhao, Yu Fang
2007 C conf
IGARSS
Xiaohui Zhao, Yu Fang, Bin Chen
2007 J jnl
Comput. Ind. Eng.
Jie Gao, Mitsuo Gen, Linyan Sun, Xiaohui Zhao
2007 conf
SNPD (3)
Shifeng Ou, Xiaohui Zhao, Ying Gao
2007 conf
SNPD (3)
Shifeng Ou, Xiaohui Zhao, Ying Gao
2002 C conf
DEXA
Xiaohui Zhao
1994 J jnl
IEEE Trans. Autom. Control.
Rogelio Lozano, Xiaohui Zhao
1994 J jnl
Autom.
Rogelio Lozano, Xiaohui Zhao, Rubén G. Moctezuma
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"