Weihao Zhang

44 papers A 3B 2Misc 1Journal 31Unranked 7
YearRankTypeTitle / Venue / Authors
2026 J jnl
CoRR
Songchen Ma, Hongyi Li, Weihao Zhang, Yonghao Tan, Pingcheng Dong, Yu Liu, Lan Liu, Yuzhong Jiao, Xuejiao Liu, Luhong Liang, Kwang-Ting Cheng
2026 J jnl
IEEE Internet Things J.
Shuai Chen, Weihao Zhang, Guoming Zhang, Xiaoyu Ji, Haiming Chen, Xinyan Zhou
2026 J jnl
CoRR
Weihao Zhang, Yitong Zhou, Huanyu Qu, Hongyi Li
2026 J jnl
Int. J. Softw. Eng. Knowl. Eng.
Heling Cao, Weihao Zhang, Yun Wang, Yonghe Chu, Miaolei Deng, Zhenghao He
2025 conf
ACL (1)
Guo Tang, Zheng Chu, Wenxiang Zheng, Junjia Xiang, Yizhuo Li, Weihao Zhang, Ming Liu, Bing Qin
2025 J jnl
Artif. Intell. Medicine
Xianliang Jiang, Dingxin Yu, Guang Jin, Fei Lei, Weihao Zhang, Xinyan Zhou
2025 J jnl
CoRR
Hongyi Li, Songchen Ma, Huanyu Qu, Weihao Zhang, Jia Chen, Junfeng Lin, Fengbin Tu, Rong Zhao
2025 J jnl
Mach. Intell. Res.
Tong Niu, Haoyu Huang, Yu Du, Weihao Zhang, Luping Shi, Rong Zhao
2025 J jnl
CoRR
Huanyu Qu, Weihao Zhang, Junfeng Lin, Songchen Ma, Hongyi Li, Luping Shi, Chengzhong Xu
2025 J jnl
IEEE Internet Things J.
Weihao Zhang, Xinyan Zhou, Dingxin Yu, Guoming Zhang, Xianliang Jiang, Haiming Chen
2025 J jnl
IEEE Trans. Autom. Control.
Weihao Zhang, Di Zhao, Shu Liang
2025 Misc conf
ICASSP
Weihao Zhang, Xin Xia, Maopeng Li, Yunbo Zhao
2025 B conf
PPoPP
Junfeng Lin, Ziming Liu, Yang You, Jun Wang, Weihao Zhang, Rong Zhao
2024 J jnl
IEEE Trans. Ind. Informatics
Weihao Zhang, Jiapeng Wang, Min Tang, Honglin Ma, Linzhi Wang, Qi Zhang, Shuqian Fan
2024 conf
PRCV (9)
Weihao Zhang, Zhilin Li, Bin Li, Mingliang Zhang
2024 J jnl
Expert Syst. Appl.
Cai Yi, Weihao Zhang, Hu Cao, Lei Yan, Qiuyang Zhou, Ying Shi, Guiting Tang, Le Ran, Jianhui Lin
2024 J jnl
IEEE Trans. Instrum. Meas.
Weihao Zhang, Cai Yi, Lei Yan, Qi Liu, Qiuyang Zhou, Pengfei He, Le Ran, Yunzhi Lin
2024 J jnl
Neural Comput. Appl.
Weihao Zhang, Lei Yu, Huiqi Wang, Witold Pedrycz
2024 J jnl
CoRR
Tong Niu, Haoyu Huang, Yu Du, Weihao Zhang, Luping Shi, Rong Zhao
2024 J jnl
CoRR
Weihao Zhang, Yu Du, Hongyi Li, Songchen Ma, Rong Zhao
2024 J jnl
IEEE Trans. Computers
Hongyi Li, Songchen Ma, Taoyi Wang, Weihao Zhang, Guanrui Wang, Chenhang Song, Huanyu Qu, Junfeng Lin, Cheng Ma, Jing Pei, Rong Zhao
2024 conf
ICC
Weihao Zhang, Xinyan Zhou, Haiming Chen
2024 A conf
AAMAS
Tong Niu, Weihao Zhang, Rong Zhao
2024 J jnl
CoRR
Tong Niu, Weihao Zhang, Rong Zhao
2024 J jnl
IEEE Trans. Computers
Junfeng Lin, Huanyu Qu, Songchen Ma, Xinglong Ji, Hongyi Li, Xiaochuan Li, Chenhang Song, Weihao Zhang
2023 conf
CGI (3)
Yuqin Zeng, Zhen Chen, Weihao Zhang, Jiapeng Wang, Shuqian Fan
2023 J jnl
Frontiers Neurorobotics
Bojian Chen, Weihao Zhang, Wenbin Wu, Yiran Li, Zhuolei Chen, Chenglong Li
2023 J jnl
Medical Biol. Eng. Comput.
Weihao Zhang, Yuting Lu, Haodong Zheng, Lei Yu
2023 J jnl
Comput. Ind.
Weihao Zhang, Yuqin Zeng, Jiapeng Wang, Honglin Ma, Qi Zhang, Shuqian Fan
2022 conf
ICME Workshops
Weihao Zhang, Jiapeng Wang, Honglin Ma, Qi Zhang, Shuqian Fan
2022 J jnl
IEICE Electron. Express
Zhewang Ma, Weihao Zhang, Fan Liu, Masataka Ohira
2022 J jnl
IEICE Trans. Electron.
Fan Liu, Zhewang Ma, Weihao Zhang, Masataka Ohira, Dongchun Qiao, Guosheng Pu, Masaru Ichikawa
2022 J jnl
IEICE Electron. Express
Weihao Zhang, Zhewang Ma, Fan Liu, Masataka Ohira, Xiaolong Wang
2022 J jnl
Sci. Robotics
Songchen Ma, Jing Pei, Weihao Zhang, Guanrui Wang, Dahu Feng, Fangwen Yu, Chenhang Song, Huanyu Qu, Cheng Ma, Mingsheng Lu, Faqiang Liu, Wenhao Zhou, Yujie Wu, Yihan Lin, Hongyi Li, Taoyi Wang, Jiuru Song, Xue Liu, Guoqi Li, Rong Zhao, Luping Shi
2021 J jnl
CoRR
Yan Zhao, Weihao Zhang, Enyi Tang, Haipeng Cai, Xi Guo, Na Meng
2021 J jnl
IEICE Electron. Express
Weihao Zhang, Zhewang Ma, Fan Liu, Masataka Ohira
2021 J jnl
Multim. Tools Appl.
Fengcai Huo, Weihao Zhang, Qiong Wang, Weijian Ren
2021 J jnl
Remote. Sens.
Weihao Zhang, Jiancun Shi, Huiwei Yi, Yan Zhu, Bing Xu
2020 J jnl
Sensors
Feifei Liu, Weihao Zhang, Yu Sun, Jianwei Liu, Jungang Miao, Feng He, Xiaojun Wu
2020 A conf
ICCAD
Yi-Hsiang Lai, Hongbo Rong, Size Zheng, Weihao Zhang, Xiuping Cui, Yunshan Jia, Jie Wang, Brendan Sullivan, Zhiru Zhang, Yun Liang, Youhui Zhang, Jason Cong, Nithin George, Jose Alvarez, Christopher J. Hughes, Pradeep Dubey
2019 B conf
ICIP
Daiheng Gao, Zhenzhi Wu, Weihao Zhang
2018 A conf
IROS
Bin Zhao, Weihao Zhang, Zhaoyu Zhang, Xiangyang Zhu, Kai Xu
2018 conf
ROBIO
Zhaoyu Zhang, Zhonghao Wu, Lingyun Zeng, Weihao Zhang, Kai Xu
2018 conf
AIM
Weihao Zhang, Zhixiong Yang, Tianlai Dong, Kai Xu
redb/extractors/macho_extractors/macho_universal.py
← Index redb/extractors/macho_extractors/macho_universal.py python
import hashlib
import inspect
import json
from datetime import datetime, timezone
from typing import Any, List

from redb.extractors.enum import Tag
from redb.extractors.macho_extractor import MachOExtractor
from redb.models.dataclasses import MachOUniversal


class MachOUniversalExtractor(MachOExtractor):

    def __init__(
        self,
        filepath,
        log,
        exporters=None,
        index_prefix=None,
        elastic_index=None,
        known_benign=False,
        known_malicious=False,
        macho=None,
    ):
        super().__init__(
            filepath,
            log,
            exporters,
            index_prefix,
            elastic_index,
            known_benign,
            known_malicious,
            macho,
        )
        self.elastic_index = self.index_prefix + "-macho_universal"
        self.log.debug(inspect.currentframe().f_code.co_name)

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

    def _extract_universal_info(self):
        """Extract Universal/FAT binary architecture information using new API."""
        self.log.debug(inspect.currentframe().f_code.co_name)

        if not self.macho:
            return None

        try:
            # Parse at Universal level first (new API requirement)
            self.macho.parse()

            # Get architectures using new API
            architectures = self.macho.get_architectures()
            if not architectures:
                return None

            # Check if this is a FAT binary
            is_fat = len(architectures) > 1

            architecture_info = []

            # Extract info for each architecture
            for arch_name in architectures:
                try:
                    # Get general info for this architecture
                    general_info = self.macho.get_general_info(arch=arch_name)

                    # Get header info for this architecture
                    header_info = self.macho.get_macho_header(arch=arch_name)

                    # Get architecture-specific MachO instance for detailed analysis
                    arch_macho = self.macho.get_macho_for_arch(arch_name)

                    # Calculate architecture slice hash (if we can access the raw data)
                    arch_sha256 = None
                    arch_md5 = None
                    arch_sha1 = None

                    # For FAT binaries, try to get slice-specific info
                    if is_fat and arch_macho:
                        try:
                            # This would require access to the slice data
                            # For now, we'll use the general file info
                            arch_sha256 = general_info.get('SHA256', '') if general_info else ''
                            arch_md5 = general_info.get('MD5', '') if general_info else ''
                            arch_sha1 = general_info.get('SHA1', '') if general_info else ''
                        except Exception as e:
                            self.log.debug(f"Could not extract slice hash for {arch_name}: {e}")

                    architecture_info.append({
                        'architecture': arch_name,
                        'arch_sha256': arch_sha256,
                        'arch_md5': arch_md5,
                        'arch_sha1': arch_sha1,
                        'cputype': header_info.get('cputype') if header_info else None,
                        'cpusubtype': header_info.get('cpusubtype') if header_info else None,
                        'filetype': header_info.get('filetype') if header_info else None
                    })

                except Exception as e:
                    self.log.warning(f"Error extracting info for architecture {arch_name}: {e}")
                    continue

            # Create Universal dataclass
            macho_universal = MachOUniversal(
                is_fat=is_fat,
                architecture_count=len(architectures),
                architectures=architectures,
                architecture_info=architecture_info,
                fat_hash=self.sha256,
                fat_md5=self.md5,
                fat_sha1=self.sha1
            )

            return macho_universal

        except Exception as e:
            self.log.error(f"Error extracting MachO Universal info: {e}")
            return None

    def _extract_fat_architecture_mappings(self):
        """Extract detailed FAT binary architecture mappings for database relationships."""
        self.log.debug(inspect.currentframe().f_code.co_name)

        if not self.macho:
            return []

        try:
            # Parse at Universal level first
            self.macho.parse()

            # Get architectures using new API
            architectures = self.macho.get_architectures()
            if not architectures or len(architectures) <= 1:
                return []  # Not a FAT binary

            mappings = []
            current_time = datetime.now(timezone.utc)

            # For each architecture, create a mapping record
            for arch_name in architectures:
                try:
                    # Get general info
                    general_info = self.macho.get_general_info()

                    # Create mapping record for FAT binary architecture table
                    mapping = {
                        'fat_hash': self.sha256,  # SHA256 of the FAT binary
                        'architecture': arch_name,
                        'arch_sha256': general_info.get('SHA256', '') if general_info else '',  # Will need proper slice extraction
                        'arch_md5': general_info.get('MD5', '') if general_info else '',
                        'arch_sha1': general_info.get('SHA1', '') if general_info else '',
                        'arch_filename': f"{general_info.get('Filename', '')}.{arch_name}" if general_info else '',
                        'analysis_date': current_time
                    }
                    mappings.append(mapping)

                except Exception as e:
                    self.log.warning(f"Error creating mapping for architecture {arch_name}: {e}")
                    continue

            return mappings

        except Exception as e:
            self.log.error(f"Error extracting FAT architecture mappings: {e}")
            return []

    def extract(self):
        self.log.debug(inspect.currentframe().f_code.co_name)
        try:
            universal_info = self._extract_universal_info()
            return universal_info
        except Exception as e:
            self.log.error(f"Error extracting MachO Universal info: {e}")
            return None

    def extract_fat_binary_basic_properties_data(self):
        """Extract data needed for creating multiple BasicProperties records for FAT binaries.

        Returns:
            Tuple: (is_fat, fat_sha256, architectures_info) where:
                - is_fat: bool indicating if this is a FAT binary
                - fat_sha256: SHA256 of the FAT wrapper
                - architectures_info: dict with arch names and their hashes
        """
        self.log.debug(inspect.currentframe().f_code.co_name)

        if not self.macho:
            return False, None, {}

        try:
            # Parse at Universal level first
            self.macho.parse()

            # Get architectures using new API
            architectures = self.macho.get_architectures()
            if not architectures or len(architectures) <= 1:
                return False, None, {}  # Not a FAT binary

            # This is a FAT binary
            architectures_info = {}

            for arch_name in architectures:
                try:
                    # Get general info for this architecture
                    general_info = self.macho.get_general_info(arch=arch_name)

                    if general_info:
                        architectures_info[arch_name] = {
                            'sha256': general_info.get('SHA256', ''),
                            'md5': general_info.get('MD5', ''),
                            'sha1': general_info.get('SHA1', ''),
                            'filename': general_info.get('Filename', ''),
                            'filesize': general_info.get('Filesize', 0)
                        }
                except Exception as e:
                    self.log.warning(f"Error extracting info for architecture {arch_name}: {e}")
                    continue

            return True, self.sha256, architectures_info

        except Exception as e:
            self.log.error(f"Error extracting FAT binary data: {e}")
            return False, None, {}

    def prepare_export_data(self, exporter_type: str) -> Any:
        if exporter_type == "ElasticsearchExporter":
            return self.extract()
        elif exporter_type == "ClickHouseExporter":
            universal_info = self.extract()
            if universal_info is None:
                return None

            data = []
            current_time = datetime.now(timezone.utc)

            # Get architecture info for the binary
            try:
                if universal_info.is_fat:
                    # For FAT binaries, architecture fields should be NULL since it contains multiple
                    architecture_raw = None
                    architecture_str = None
                else:
                    # For single-arch binaries, get the actual architecture info
                    header_info = self.macho.get_macho_header()
                    architecture_raw = header_info.get('cputype', 0) if header_info else 0
                    architecture_str = universal_info.architectures[0] if universal_info.architectures else None
            except Exception as e:
                self.log.warning(f"Could not get architecture info for binary: {e}")
                architecture_raw = None
                architecture_str = None

            # Main Universal binary record
            data.append([
                self.sha256,                              # sha256
                self.md5,                                 # md5
                self.sha1,                                # sha1
                None,                                     # parent_sha256 (always None for main FAT binary)
                architecture_raw,                         # architecture (raw CPU type)
                architecture_str,                         # architecture_str (human-readable)
                universal_info.is_fat,                    # is_fat
                universal_info.architecture_count,       # architecture_count
                universal_info.architectures,            # architectures (array)
                json.dumps(universal_info.architecture_info[0] if len(universal_info.architecture_info) == 1 else {"architectures": universal_info.architecture_info}) if universal_info.architecture_info else None,  # architecture_info (JSON)
                current_time,                             # analysis_date
            ])

            column_names = [
                'sha256', 'md5', 'sha1', 'parent_sha256', 'architecture', 'architecture_str',
                'is_fat', 'architecture_count', 'architectures', 'architecture_info',
                'analysis_date'
            ]

            column_type_names = [
                'FixedString(64)', 'FixedString(32)', 'FixedString(40)',
                'Nullable(FixedString(64))', 'Nullable(UInt32)', 'LowCardinality(Nullable(String))',
                'UInt8', 'UInt32', 'Array(LowCardinality(String))', 'JSON',
                'DateTime64(3, \'UTC\')'
            ]

            return (data, column_names, column_type_names)

        return None

    def prepare_fat_architecture_export_data(self) -> Any:
        """Prepare export data for the FAT binary architecture mapping table."""
        mappings = self._extract_fat_architecture_mappings()
        if not mappings:
            return None

        data = []
        for mapping in mappings:
            data.append([
                mapping['fat_hash'],
                mapping['architecture'],
                mapping['arch_sha256'],
                mapping['arch_md5'],
                mapping['arch_sha1'],
                mapping['arch_filename'],
                mapping['analysis_date'],
            ])

        column_names = [
            'fat_hash', 'architecture', 'arch_sha256', 'arch_md5', 'arch_sha1',
            'arch_filename', 'analysis_date'
        ]

        column_type_names = [
            'FixedString(64)', 'LowCardinality(String)', 'FixedString(64)',
            'FixedString(32)', 'FixedString(40)', 'String',
            'DateTime64(3, \'UTC\')'
        ]

        return (data, column_names, column_type_names)

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

    # def get_fat_architecture_table(self) -> str:
    #     """Return table name for FAT binary architecture mappings."""
    #     return "redb_fat_binary_architectures"