Xiaohua Zhou

76 papers A* 5A 4B 6C 7Misc 5Journal 29Unranked 18
YearRankTypeTitle / Venue / Authors
2026 J jnl
IEEE Wirel. Commun. Lett.
Tianyu Fang, Xiaohua Zhou, Yijie Mao
2025 J jnl
IEEE Trans. Geosci. Remote. Sens.
Chunyang Pei, Zhixian Zhu, Chunlu Wang, Jiwu Li, Xiaohua Zhou, Linhang Zhang, Zubin Chen
2025 conf
ICC
Xiaohua Zhou, Tianyu Fang, Yijie Mao
2025 conf
ECC
Xu Du, Xiaohua Zhou, Shijie Zhu, Apostolos I. Rikos
2025 J jnl
CoRR
Xu Du, Xiaohua Zhou, Shijie Zhu
2025 J jnl
IEEE Trans. Instrum. Meas.
Siqi Wang, Zhongrui Wang, Junye Tong, Tianyuan Hou, Yuhang Wang, Xiaohua Zhou, Yi Xin
2025 J jnl
IEEE Commun. Lett.
Xiaohua Zhou, Tianyu Fang, Yijie Mao
2025 J jnl
CoRR
Xiaohua Zhou, Tianyu Fang, Yijie Mao
2025 J jnl
IEEE Internet Things J.
Xiaohua Zhou, Tianyu Fang, Yijie Mao
2025 J jnl
Int. J. Hum. Comput. Interact.
Xiaohua Zhou, Ching-Sing Chai, Morris Siu-Yung Jong, Xi Bei Xiong
2025 J jnl
Clust. Comput.
Jiwu Li, Zhiyuan Li, Renjie He, Xiaohua Zhou, Zubin Chen
2025 J jnl
Int. J. Digit. Earth
Ping He, Yu Chen, Xingping Wen, Xiaohua Zhou, Zailin Chen, Zhongchang Sun, Xianfeng Cheng
2025 J jnl
Interact. Learn. Environ.
Feifei Wang, Xiaohua Zhou, Kangxin Li, Alan C. K. Cheung, Ming Tian
2024 J jnl
CoRR
Xiaohua Zhou, Tianyu Fang, Yijie Mao
2024 conf
GLOBECOM (Workshops)
Xiaohua Zhou, Xu Du, Yijie Mao
2024 J jnl
Biomed. Signal Process. Control.
Zongpeng Zhang, Taoyun Ji, Mingqing Xiao, Wen Wang, Guojing Yu, Tong Lin, Yuwu Jiang, Xiaohua Zhou, Zhouchen Lin
2024 J jnl
Multim. Tools Appl.
Xiaohua Zhou, Xinkai Meng, Jianbin Zheng, Gengfa Fang, Tongjian Guo
2024 J jnl
Comput. Hum. Behav.
Lu Yu, Xiaohua Zhou
2023 conf
CECNet
Qinglei Wang, Yanbo Liang, Rongguang Guo, Weizhi Wang, Xiaohua Zhou
2023 J jnl
ICT Express
Xiaohua Zhou, Jianbin Zheng, Xinkai Meng, Guanghui Sun, Ruyun Tian
2022 J jnl
PLoS Comput. Biol.
Yunjun Zhang, Tom Britton, Xiaohua Zhou
2021 conf
AISS
Xiaohua Zhou, Xinkai Meng, Guanghui Sun, Jainbin Zheng, Wenrui Ye
2021 C conf
ICCE
Xiaohua Zhou, Morris Siu-Yung Jong, Ching-Sing Chai
2021 J jnl
Remote. Sens.
Xiaohua Zhou, Xuezhi Wang, Yuanchun Zhou, Qinghui Lin, Jianghua Zhao, Xianghai Meng
2020 J jnl
CoRR
Gang Huang, Xiaohua Zhou, Qingyang Song
2020 C conf
ICCE
Morris Siu-Yung Jong, Chin-Chung Tsai, Haoran Xie, Frankie Kwan Kit Wong, Vincent Wai-Leuk Tam, Xiaohua Zhou, Mengyuen Chen
2020 J jnl
IEEE Access
Ruyun Tian, Longxu Wang, Yuanjie Jiang, Jun Lin, Linhang Zhang, Xiaohua Zhou
2019 J jnl
Sensors
Ruyun Tian, Longxu Wang, Xiaohua Zhou, Hao Xu, Jun Lin, Linhang Zhang
2019 C conf
ICCE
Morris Siu-Yung Jong, Chin-Chung Tsai, Haoran Xie, Frankie Kwan Kit Wong, Vincent Wai-Leuk Tam, Xiaohua Zhou
2019 J jnl
Comput. Stat. Data Anal.
Dalei Yu, Chang Ding, Na He, Ruiwu Wang, Xiaohua Zhou, Lei Shi
2019 C conf
ICCE
Mengyuan Chen, Morris Siu-Yung Jong, Ching-Sing Chai, Xiaohua Zhou
2017 J jnl
J. Multivar. Anal.
Zhihua Sun, Feifei Chen, Xiaohua Zhou, Qingzhao Zhang
2013 C conf
IGARSS
Xiaohua Zhou, Yu Guo, Hao Li
2013 conf
GreenCom/iThings/CPScom
Xiaohua Zhou, Jian Huang, Weifeng Lv, Dapeng Li
2013 conf
ITST
Xiaohua Zhou, Jian Huang, Ren Jing, Dapeng Li
2013 conf
CloudCom (1)
Dapeng Li, Xiaohua Zhou, Qi Wang, Mengdan Gao
2013 conf
ITST
Dapeng Li, Haitao Yu, Xiaohua Zhou, Mengdan Gao
2013 conf
ADMA (1)
Jinhui Nie, Hongqi Su, Xiaohua Zhou
2012 J jnl
IEEE Trans. Syst. Man Cybern. Part A
Xiaodan Zhang, Xiaohua Hu, Tingting Hu, E. K. Park, Xiaohua Zhou
2011 conf
ISNN (3)
Chunning Song, Xiaohua Zhou, Xiaofeng Lin, Shaojian Song
2010 ch.
Strategic Advancements in Utilizing Data Mining and Warehousing Technologies
Xiaodan Zhang, Xiaohua Hu, Jiali Xia, Xiaohua Zhou, Palakorn Achananuparp
2010 ch.
Strategic Advancements in Utilizing Data Mining and Warehousing Technologies
Xiaodan Zhang, Liping Jing, Xiaohua Hu, Michael K. Ng, Jiali Xia, Xiaohua Zhou
2009 Misc conf
GrC
Guangrong Li, Xiaodan Zhang, Illhoi Yoo, Xiaohua Zhou
2009 conf
JCDL
Xiaohua Zhou, Palakorn Achananuparp, E. K. Park, Xiaohua Hu, Xiaodan Zhang
2009 A* conf
KDD
Xiaohua Hu, Xiaodan Zhang, Caimei Lu, E. K. Park, Xiaohua Zhou
2008 J jnl
Int. J. Data Warehous. Min.
Xiaodan Zhang, Xiaohua Hu, Jiali Xia, Xiaohua Zhou, Palakorn Achananuparp
2008 conf
BIBM
Xiaohua Zhou, Xiaohua Hu, Xiaodan Zhang, Daniel Duanqing Wu, Tingting He, Aijing Luo
2008 A* conf
SIGIR
Xiaodan Zhang, Xiaohua Hu, Xiaohua Zhou
2008 J jnl
Int. J. Data Warehous. Min.
Xiaodan Zhang, Liping Jing, Xiaohua Hu, Michael K. Ng, Jiali Xia Jiangxi, Xiaohua Zhou
2008 A conf
SDM
Xiaohua Zhou, Xiaodan Zhang, Xiaohua Hu
2008 B conf
IJCNN
Palakorn Achananuparp, Xiaohua Zhou, Xiaohua Hu, Xiaodan Zhang
2008 conf
Dublin Core Conference
Xia Lin, Jiexun Li, Xiaohua Zhou
2008 conf
ICADL
Palakorn Achananuparp, Xiaohua Hu, Xiaohua Zhou, Xiaodan Zhang
2007 B conf
DASFAA
Xiaodan Zhang, Liping Jing, Xiaohua Hu, Michael K. Ng, Xiaohua Zhou
2007 A conf
CIKM
Xiaohua Zhou, Xiaohua Hu, Xiaodan Zhang, Xiajiong Shen
2007 Misc conf
GrC
Chen Wu, Xiaohua Hu, Zhoujun Li, Xiaohua Zhou, Palakorn Achananuparp
2007 conf
ICTAI (2)
Xiaohua Zhou, Xiaodan Zhang, Xiaohua Hu
2007 A* conf
IJCAI
Xiaohua Zhou, Xiaodan Zhang, Xiaohua Hu
2007 J jnl
IEEE Trans. Knowl. Data Eng.
Xiaohua Zhou, Xiaohua Hu, Xiaodan Zhang
2007 B conf
DaWaK
Xiaodan Zhang, Xiaohua Hu, Jiali Xia, Xiaohua Zhou, Palakorn Achananuparp
2006 B conf
CBMS
Hyoil Han, Yoori Choi, Yoo Myung Choi, Xiaohua Zhou, Ari D. Brooks
2006 C conf
BIBE
Xiaodan Zhang, Daniel Duanqing Wu, Xiaohua Zhou, Xiaohua Hu
2006 Misc conf
SAC
Xiaohua Zhou, Hyoil Han, Isaac Chankai, Ann Prestrud, Ari D. Brooks
2006 A* conf
SIGIR
Xiaohua Zhou, Xiaohua Hu, Xiaodan Zhang, Xia Lin, Il-Yeol Song
2006 C conf
ISI
Xiaohua Hu, Xiaodan Zhang, Daniel Duanqing Wu, Xiaohua Zhou, Peter Rumm
2006 A conf
CIKM
Xiaohua Hu, Xiaodan Zhang, Xiaohua Zhou
2006 B conf
PRICAI
Xiaohua Zhou, Xiaodan Zhang, Xiaohua Hu
2006 J jnl
Trans. Comp. Sys. Biology
Xiaohua Zhou, Xiaohua Hu, Guangren Li, Xia Lin, Xiaodan Zhang
2006 B conf
DASFAA
Xiaohua Zhou, Xiaohua Hu, Xia Lin, Hyoil Han, Xiaodan Zhang
2006 A* conf
ICDM
Xiaodan Zhang, Xiaohua Zhou, Xiaohua Hu
2006 A conf
ECIR
Xiaohua Zhou, Xiaodan Zhang, Xiaohua Hu
2005 Misc conf
IKE
Xiaohua Zhou
2005 conf
ICCSA (3)
Xiaohua Zhou, Il-Yeol Song
2005 conf
ICDE Workshops
Xiaohua Zhou, Hyoil Han, Isaac Chankai, Ann Prestrud, Ari D. Brooks
2005 Misc conf
FLAIRS
Xiaohua Zhou, Hyoil Han
1991 J jnl
CVGIP Graph. Model. Image Process.
Xiaohua Zhou, Richard Gordon
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"