Manlin Wang

37 papers B 1C 3Misc 1Journal 23Unranked 9
YearRankTypeTitle / Venue / Authors
2026 J jnl
IEEE Trans. Wirel. Commun.
Xing Lv, Manlin Wang, Chunqi Chen, Bin Xia
2026 J jnl
IEEE Trans. Wirel. Commun.
Yinghong Guo, Yixiao Gu, Manlin Wang, Bin Xia
2026 J jnl
IEEE Trans. Wirel. Commun.
Chunqi Chen, Manlin Wang, Zhen Xu, Xing Lv, Bin Xia
2026 J jnl
IEEE Trans. Veh. Technol.
Yinghong Guo, Yixiao Gu, Manlin Wang, Chaoyang Lei, Bin Xia
2025 conf
ICC
Manlin Wang, Xing Lv, Zhen Xu, Bin Xia
2025 J jnl
IEEE Trans. Inf. Forensics Secur.
Manlin Wang, Yao Yao, Haiyang Ding, Shihai Shao, Bin Xia, Jiangzhou Wang
2025 J jnl
IEEE Trans. Wirel. Commun.
Manlin Wang, Zhen Xu, Xing Lv, Bin Xia
2025 J jnl
IEEE Trans. Geosci. Remote. Sens.
Sihan Meng, Xin Hu, Manlin Wang, Yao Li, Jie Wang, Zhixiang Yin, Penghai Wu
2025 J jnl
IEEE Internet Things J.
Zhen Xu, Manlin Wang, Bin Xia, Jiangzhou Wang
2025 J jnl
IEEE Wirel. Commun. Lett.
Xing Lv, Manlin Wang, Zhen Xu, Bin Xia
2025 J jnl
IEEE Trans. Wirel. Commun.
Yichen Liu, Yinghong Guo, Yixiao Gu, Manlin Wang, Junhua Liu, Bin Xia
2025 J jnl
IEEE Wirel. Commun. Lett.
Manlin Wang, Tian Liu, Ouxin Lu, Di Wang, Bin Xia
2025 conf
ICC
Yichen Liu, Yinghong Guo, Yixiao Gu, Manlin Wang, Junhua Liu, Bin Xia
2024 C conf
SNPD
Manlin Wang, Ting Jiang
2024 J jnl
IEEE Trans. Wirel. Commun.
Bin Xia, Zhen Xu, Manlin Wang, Chunqi Chen, Yao Yao, Jiangzhou Wang
2024 J jnl
IEEE Trans. Wirel. Commun.
Manlin Wang, Yao Yao, Bin Xia, Zhiyong Chen, Jiangzhou Wang
2024 J jnl
IEEE Trans. Wirel. Commun.
Manlin Wang, Bin Xia, Yao Yao, Zhiyong Chen, Jiangzhou Wang
2024 J jnl
Sci. China Inf. Sci.
Manlin Wang, Bin Xia, Jiangzhou Wang
2024 conf
WCSP
Manlin Wang, Chunqi Chen, Xing Lv, Bin Xia
2023 J jnl
IEEE Trans. Veh. Technol.
Manlin Wang, Zhen Xu, Bin Xia, Yinghong Guo
2023 C conf
ICCC
Zhen Xu, Manlin Wang, Bin Xia, Jiangzhou Wang
2023 conf
VTC Fall
Yao Yao, Manlin Wang, Bin Xia
2023 C conf
ICCC
Manlin Wang, Yao Yao, Bin Xia, Zhiyong Chen, Jiangzhou Wang
2023 J jnl
CoRR
Manlin Wang, Yao Yao, Bin Xia, Zhiyong Chen, Jiangzhou Wang
2023 J jnl
IEEE Trans. Veh. Technol.
Manlin Wang, Zhen Xu, Bin Xia, Yinghong Guo, Zhiyong Chen
2023 J jnl
IEEE Wirel. Commun. Lett.
Zhongwei Wang, Manlin Wang, Bin Xia, Yinghong Guo, Jiangzhou Wang
2023 J jnl
IEEE Trans. Veh. Technol.
Manlin Wang, Jienan Chen, Jiyun Tao, Hongye Li
2023 J jnl
IEEE Internet Things J.
Manlin Wang, Bin Xia, Zhen Xu, Yinghong Guo, Zhiyong Chen
2023 J jnl
IEEE Trans. Veh. Technol.
Chunqi Chen, Manlin Wang, Bin Xia, Yinghong Guo, Jiangzhou Wang
2022 conf
VTC Fall
Hongjie He, Bin Xia, Yinghong Guo, Manlin Wang
2022 conf
Geoinformatics
Manlin Wang, Xiaoliang Wang, Yuan Zhou, Jianpeng Cao, Xianmin Mai
2022 B conf
GLOBECOM
Yinghong Guo, Chengliang Yin, Ouxin Lu, Manlin Wang, Bin Xia
2021 conf
GLOBECOM (Workshops)
Manlin Wang, Yinghong Guo, Bin Xia
2018 conf
ROBIO
Qiang Nie, Xin Wang, Jiangliu Wang, Manlin Wang, Yunhui Liu
2016 J jnl
Neurocomputing
Xiaoyu Zhang, Manlin Wang, Jiangtao Cui
2015 conf
FSKD
Manlin Wang, Xiaokang Feng, Jiangtao Cui
2013 Misc conf
ICMLC
Manlin Wang, Fei Zhang, Patrick P. K. Chan
redb/extractors/macho_extractors/macho_similarity_hashes.py
← Index redb/extractors/macho_extractors/macho_similarity_hashes.py python
import inspect
from datetime import datetime, timezone
from typing import Any

from redb.extractors.enum import Tag
from redb.extractors.macho_extractor import MachOExtractor


class MachOSimilarityHashExtractor(MachOExtractor):
    """Extract Mach-O similarity hashes using machofile API.

    Similarity hashes are MD5 fingerprints of sorted, deduplicated binary components:
    - dylib_hash: MD5 of dynamic library names
    - import_hash: MD5 of imported function names
    - export_hash: MD5 of exported symbol names
    - entitlement_hash: MD5 of entitlement names and array values
    - symhash: MD5 of external undefined symbols

    For FAT binaries:
    - Inserts one row per architecture slice with per-slice hashes
    - Inserts one row for the FAT container with combined hashes

    For single-arch binaries:
    - Inserts one row with that architecture's hashes

    Note: parent_sha256 and architecture relationships are tracked in redb_basic_properties,
    not duplicated here. Use JOIN with redb_basic_properties when needed.
    """

    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_hashes"
        self.log.debug(inspect.currentframe().f_code.co_name)

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

    def _extract_similarity_hashes(self, arch_name=None):
        """Extract similarity hashes for a specific architecture."""
        self.log.debug(inspect.currentframe().f_code.co_name)

        if not self.macho:
            return None

        try:
            similarity_hashes = self.macho.get_similarity_hashes(arch=arch_name)
            return similarity_hashes if similarity_hashes else None
        except Exception as e:
            self.log.error(f"Error extracting similarity hashes for arch {arch_name}: {e}")
            return None

    def extract(self):
        self.log.debug(inspect.currentframe().f_code.co_name)
        try:
            if not self.macho:
                return None

            architectures = self.macho.get_architectures()
            if not architectures:
                return None

            if len(architectures) > 1:
                # FAT binary - return combined hashes + per-arch hashes
                results = []

                # First add combined hashes for the FAT container
                all_hashes = self.macho.get_similarity_hashes()
                combined_hashes = all_hashes.get('combined', {}) if all_hashes else {}
                if combined_hashes:
                    combined_hashes['arch_identifier'] = 'fat'
                    results.append(combined_hashes)

                # Then add per-arch hashes
                for arch_name in architectures:
                    hashes = self._extract_similarity_hashes(arch_name)
                    if hashes:
                        hashes['arch_identifier'] = arch_name
                        results.append(hashes)
                return results
            else:
                # Single architecture - return single result
                return self._extract_similarity_hashes(architectures[0])
        except Exception as e:
            self.log.error(f"Error extracting similarity hashes: {e}")
            return None

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

            try:
                architectures = self.macho.get_architectures()
                is_fat = len(architectures) > 1
            except Exception as e:
                self.log.error(f"Could not get architectures: {e}")
                return None

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

            # For FAT binaries, first insert a row for the container with combined hashes
            if is_fat:
                all_hashes = self.macho.get_similarity_hashes()  # Without arch returns all including 'combined'
                combined_hashes = all_hashes.get('combined', {}) if all_hashes else {}
                if combined_hashes:
                    data.append([
                        self.sha256,                                    # sha256 (FAT container)
                        combined_hashes.get('dylib_hash'),              # dylib_hash
                        combined_hashes.get('import_hash'),             # import_hash
                        combined_hashes.get('export_hash'),             # export_hash
                        combined_hashes.get('entitlement_hash'),        # entitlement_hash
                        combined_hashes.get('symhash'),                 # symhash
                        current_time,                                   # analysis_date
                    ])

            # Insert rows for each architecture slice
            for arch_name in architectures:
                # Get architecture-specific sha256
                try:
                    arch_general_info = self.macho.get_general_info(arch=arch_name)
                    arch_sha256 = arch_general_info.get('SHA256', self.sha256)
                except Exception as e:
                    self.log.warning(f"Could not get arch-specific sha256 for {arch_name}: {e}")
                    arch_sha256 = self.sha256

                # Get similarity hashes for this architecture
                similarity_hashes = self._extract_similarity_hashes(arch_name)
                if not similarity_hashes:
                    continue

                data.append([
                    arch_sha256,                                    # sha256 (arch-specific)
                    similarity_hashes.get('dylib_hash'),            # dylib_hash
                    similarity_hashes.get('import_hash'),           # import_hash
                    similarity_hashes.get('export_hash'),           # export_hash
                    similarity_hashes.get('entitlement_hash'),      # entitlement_hash
                    similarity_hashes.get('symhash'),               # symhash
                    current_time,                                   # analysis_date
                ])

            if not data:
                return None

            column_names = [
                'sha256',
                'macho_dylib_hash', 'macho_import_hash', 'macho_export_hash',
                'macho_entitlement_hash', 'macho_symhash',
                'analysis_date'
            ]

            column_type_names = [
                'FixedString(64)',
                'Nullable(FixedString(32))', 'Nullable(FixedString(32))', 'Nullable(FixedString(32))',
                'Nullable(FixedString(32))', 'Nullable(FixedString(32))',
                'DateTime64(3, \'UTC\')'
            ]

            return (data, column_names, column_type_names)

        return None

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