Weihua Su

55 papers B 1C 3Journal 44Unranked 7
YearRankTypeTitle / Venue / Authors
2025 J jnl
J. Real Time Image Process.
Dongyuan Zang, Weihua Su, Zijing Song, Jiabao Huang, Meng Yin, Jun Ma, Shenao Song
2025 J jnl
Eur. J. Oper. Res.
Chonghui Zhang, Dandan Luo, Weihua Su, Benjamin Lev
2025 J jnl
CoRR
Hengtao Li, Pengxiang Ding, Runze Suo, Yihao Wang, Zirui Ge, Dongyuan Zang, Kexian Yu, Mingyang Sun, Hongyin Zhang, Donglin Wang, Weihua Su
2025 J jnl
J. Oper. Res. Soc.
Wenting Xue, Zijin Lin, Weihua Su, Chonghui Zhang
2024 conf
ICSIM
Zandong Tian, Qian Chen, Jiahe Peng, Dongyuan Zang, Mianshi Feng, Weihua Su
2024 J jnl
J. Real Time Image Process.
Huixin Liu, Guohua Lu, Mingxi Li, Weihua Su, Ziyi Liu, Xu Dang, Dongyuan Zang
2024 C conf
ACC
Samantha Burton, Tianyi He, Weihua Su
2024 J jnl
Computing
Haijun Gu, Yingyu Ma, Siqi Wang, Xincheng Chen, Weihua Su
2024 J jnl
Inf. Sci.
Dandan Luo, Chonghui Zhang, Weihua Su, Shouzhen Zeng, Tomas Balezentis
2024 J jnl
Vis. Informatics
Zhiguang Zhou, Yize Li, Yuna Ni, Weiwen Xu, Guoting Hu, Ying Lai, Peixiong Chen, Weihua Su
2023 J jnl
Artif. Intell. Rev.
Sichao Chen, Chonghui Zhang, Shouzhen Zeng, Yongheng Wang, Weihua Su
2023 J jnl
Eur. J. Oper. Res.
Weihua Su, Sibo Chen, Chonghui Zhang, Kevin W. Li
2023 J jnl
Expert Syst. Appl.
Chenji Zhao, Shun Xiang, Yuanquan Wang, Zhaoxi Cai, Jun Shen, Shoujun Zhou, Di Zhao, Weihua Su, Shijie Guo, Shuo Li
2023 J jnl
J. Vis.
Zhiguang Zhou, Huihui Li, Fang Liu, Yanan Liu, Chaogeng Huang, Yubo Tao, Hai Lin, Weihua Su
2023 J jnl
CoRR
Tianyi He, Weihua Su
2023 C conf
ACC
Samantha Burton, Tianyi He, Weihua Su
2022 J jnl
Syst.
Weihua Su, Le Zhang, Chonghui Zhang, Shouzhen Zeng, Wangxiu Liu
2022 J jnl
Comput. Ind. Eng.
Na Zhang, Weihua Su, Chonghui Zhang, Shouzhen Zeng
2022 J jnl
Expert Syst. Appl.
Weihua Su, Dandan Luo, Chonghui Zhang, Shouzhen Zeng
2022 J jnl
PeerJ Comput. Sci.
Jilong Zhang, Yajuan Zhang, Hongyang Zhang, Quan Zhang, Weihua Su, Shijie Guo, Yuanquan Wang
2022 J jnl
J. Vis.
Ling Sun, Xiang Zhang, Xiaan Pan, Yuhua Liu, Wanghao Yu, Ting Xu, Fang Liu, Weifeng Chen, Yigang Wang, Weihua Su, Zhiguang Zhou
2021 J jnl
Expert Syst. Appl.
Chonghui Zhang, Weihua Su, Shouzhen Zeng, Tomas Balezentis, Enrique Herrera-Viedma
2021 J jnl
Vis. Informatics
Haoxuan Wang, Yuna Ni, Ling Sun, Yuanyuan Chen, Ting Xu, Xiaohui Chen, Weihua Su, Zhiguang Zhou
2021 J jnl
J. Vis.
Fengling Zheng, Jin Wen, Xiang Zhang, Yuanyuan Chen, Xinlong Zhang, Yanan Liu, Ting Xu, Xiaohui Chen, Yigang Wang, Weihua Su, Zhiguang Zhou
2020 J jnl
IEEE Access
Le Zhang, Chonghui Zhang, Weihua Su, Shouzhen Zeng
2020 J jnl
IEEE Access
Weihua Su, Dingxin Wang, Lili Xu, Shouzhen Zeng, Chonghui Zhang
2020 J jnl
IEEE Geosci. Remote. Sens. Lett.
Boyang Li, Weihua Su, Hang Wu, Ruihao Li, Wenchang Zhang, Wei Qin, Shiyue Zhang, Jiacheng Wei
2020 conf
AIM
Tianyi He, Guoming G. Zhu, Sean Shan-Min Swei, Weihua Su
2019 conf
ICIRA (3)
Rui Jian, Weihua Su, Ruihao Li, Shiyue Zhang, Jiacheng Wei, Boyang Li, Ruqiang Huang
2019 J jnl
IEEE J. Sel. Top. Appl. Earth Obs. Remote. Sens.
Boyang Li, Weihua Su, Hang Wu, Ruihao Li, Wenchang Zhang, Wei Qin, Shiyue Zhang
2019 J jnl
IEEE Trans. Cogn. Dev. Syst.
Fuchun Sun, Wenchang Zhang, Jianhua Chen, Hang Wu, Chuanqi Tan, Weihua Su
2019 conf
RICAI
Bingxuan Li, Weihua Su, Shiyue Zhang
2019 conf
CCTA
Tianyi He, Guoming G. Zhu, Sean Shan-Min Swei, Weihua Su
2018 J jnl
Int. J. Wirel. Mob. Comput.
Guanglan Zhou, Weihua Su, Renan Liu, Jun Hu
2018 J jnl
Symmetry
Jinming Zhou, Weihua Su, Tomas Balezentis, Dalia Streimikiene
2018 J jnl
Vis. Comput.
Baozhen Liu, Hang Wu, Weihua Su, Wenchang Zhang, Jinggong Sun
2018 C conf
ACC
Tianyi He, Guoming G. Zhu, Sean Shan-Min Swei, Weihua Su
2018 J jnl
J. Vis.
Zhiguang Zhou, Huihui Li, Fang Liu, Yanan Liu, Chaogeng Huang, Yubo Tao, Hai Lin, Weihua Su
2017 B conf
SMC
Wenchang Zhang, Fuchun Sun, Chunfang Liu, Weihua Su, Chuanqi Tan, Shaobo Liu
2017 J jnl
Robotics Auton. Syst.
Tao Sun, Xu Xiang, Weihua Su, Hang Wu, Yimin Song
2017 conf
CRC
Zhuo Chen, Weihua Su, Bin Li, Hang Wu, Baozhen Liu, Xiaoli Qin
2017 J jnl
J. Sensors
Hang Wu, Baozhen Liu, Weihua Su, Zihao Chen, Wenchang Zhang, Xudong Ren, Jinggong Sun
2017 J jnl
Signal Process. Image Commun.
Baozhen Liu, Hang Wu, Weihua Su, Jinggong Sun
2017 J jnl
IEEE Computer Graphics and Applications
Zhiguang Zhou, Zhifei Ye, Yanan Liu, Fang Liu, Yubo Tao, Weihua Su
2016 J jnl
IEEE Geosci. Remote. Sens. Lett.
Hang Wu, Baozhen Liu, Weihua Su, Wenchang Zhang, Jinggong Sun
2016 J jnl
Remote. Sens.
Hang Wu, Baozhen Liu, Weihua Su, Wenchang Zhang, Jinggong Sun
2015 conf
ROBIO
Wenchang Zhang, Fuchun Sun, Chunfang Liu, Chunle Gao, Weihua Su
2015 J jnl
Cybern. Syst.
Weihua Su, Chonghui Zhang, Shouzhen Zeng
2014 J jnl
J. Intell. Fuzzy Syst.
Weihua Su, Wei Li, Shouzhen Zeng, Chonghui Zhang
2014 J jnl
J. Intell. Fuzzy Syst.
Shouzhen Zeng, Weihua Su, Ji Chen
2014 J jnl
Int. J. Found. Comput. Sci.
Junping Zhou, Weihua Su, Jianan Wang
2013 J jnl
Int. Trans. Oper. Res.
Weihua Su, Wuzhen Peng, Shouzhen Zeng, Bo Peng, Tiejun Pan
2013 J jnl
CoRR
Junping Zhou, Weihua Su, Minghao Yin
2013 J jnl
Int. J. Uncertain. Fuzziness Knowl. Based Syst.
Weihua Su, Yong Yang, Chonghui Zhang, Shouzhen Zeng
2011 J jnl
Knowl. Based Syst.
Shouzhen Zeng, Weihua Su
redb/extractors/ioc_extractor/ioc_extractor.py
← Index redb/extractors/ioc_extractor/ioc_extractor.py python
"""
IOC Extractor - Extractor class for extracting IOCs from decompilation results.

This extractor works with in-memory data from DecompileBinja, following the
standard Extractor pattern to support both ClickHouse and PrintExporter (dry-run).

Usage:
    # After DecompileBinja completes:
    ioc_extractor = IOCExtractorFromResults(
        analysis_results=decompiler.analysis_results,
        sha256=sha256,
        log=logger,
        exporters=exporters,
        index_prefix=index_prefix
    )
    ioc_extractor.export_data()
"""

import inspect
from datetime import datetime, timezone
from pathlib import Path
from typing import Any, List, Dict, Optional

from redb.extractors.enum import Tag
from redb.extractors.database_exporters import DatabaseExporter

# Import the IOCScraper and related classes from standalone module
from redb.extractors.ioc_extractor.standalone_ioc_extractor import (
    IOCScraper,
    IOCType,
    SourceType,
    ExtractedIOC,
)
from typing import Set


class IOCExtractorFromResults:
    """
    Extracts IOCs from in-memory decompilation results.

    This follows a simplified Extractor pattern but doesn't inherit from Extractor
    since it doesn't read from a binary file - instead it takes already-processed
    analysis results from DecompileBinja.
    """

    def __init__(
        self,
        analysis_results: Dict[str, Any],
        sha256: str,
        log: Any,
        exporters: Optional[List[DatabaseExporter]] = None,
        index_prefix: Optional[str] = None,
        tld_file: Optional[Path] = None,
        suppress_types: Optional[Set[IOCType]] = None,
        js_context: bool = False,
    ):
        """
        Initialize IOC Extractor with analysis results.

        Args:
            analysis_results: Dict containing 'strings' and 'decompiled' lists from DecompileBinja
            sha256: Sample SHA256 hash
            log: Logger instance
            exporters: List of database exporters (ClickHouse, Print, etc.)
            index_prefix: Index prefix for database
            tld_file: Optional path to TLD list file
            js_context: When True, the underlying IOCScraper rejects FQDN
                candidates that match JS object-access syntax (see
                JS_FP_TLDS / JS_FP_SLDS). Set this for the JS pipeline only;
                APK suppresses FQDN entirely via suppress_types and binary
                callers leave it disabled.
        """
        self.log = log
        self.log.debug(f"Creating {self.__class__.__name__}")
        self.analysis_results = analysis_results
        self.sha256 = sha256
        self.exporters = exporters or []
        self.index_prefix = index_prefix
        self.scraper = IOCScraper(
            tld_file, suppress_types=suppress_types, js_context=js_context,
        )
        self.extracted_iocs: List[ExtractedIOC] = []

    def extract(self) -> List[ExtractedIOC]:
        """
        Extract IOCs from strings and decompiled functions in analysis_results.

        Returns:
            List of ExtractedIOC objects
        """
        self.log.debug(inspect.currentframe().f_code.co_name)
        self.extracted_iocs = []

        # Extract from strings
        strings_count = self._extract_from_strings()

        # Extract from decompiled functions
        functions_count = self._extract_from_decompiled()

        # Extract from text-based artefact surfaces (JS, PowerShell, etc.)
        text_count = self._extract_from_text()

        self.log.info(
            f"Extracted {len(self.extracted_iocs)} IOCs for {self.sha256[:16]}... "
            f"(strings: {strings_count}, functions: {functions_count}, "
            f"text: {text_count})"
        )

        return self.extracted_iocs

    def _extract_from_strings(self) -> int:
        """Extract IOCs from sample's strings."""
        count = 0
        strings = self.analysis_results.get("strings", [])

        for s in strings:
            string_value = s.get("string", "")
            string_offset = s.get("string_offset", 0)

            if isinstance(string_value, bytes):
                string_value = string_value.decode('utf-8', errors='replace')

            for ioc in self.scraper.scrape(string_value, SourceType.STRING, str(string_offset)):
                self.extracted_iocs.append(ioc)
                count += 1

        return count

    def _extract_from_decompiled(self) -> int:
        """Extract IOCs from sample's decompiled functions.

        Supports both Binja format (key: "decompiled", fields: "decompiled_function",
        "decompiled_function_hash", "function_type") and APK format (key:
        "decompiled_content", fields: "decompiled_method", "decompiled_method_hash",
        "method_type").
        """
        count = 0

        # Binja format
        decompiled = self.analysis_results.get("decompiled", [])
        for func in decompiled:
            func_type = func.get("function_type", "UNKNOWN")
            if func_type in ("LIBRARY", "THUNK"):
                continue

            func_content = func.get("decompiled_function", "")
            func_hash = func.get("decompiled_function_hash", "unknown")

            if isinstance(func_content, bytes):
                func_content = func_content.decode('utf-8', errors='replace')

            for ioc in self.scraper.scrape(func_content, SourceType.DECOMPILED_FUNCTION, func_hash):
                self.extracted_iocs.append(ioc)
                count += 1

        # APK format (decompiled_content with method-level fields)
        decompiled_content = self.analysis_results.get("decompiled_content", [])
        for func in decompiled_content:
            func_type = func.get("method_type", "UNKNOWN")
            if func_type in ("LIBRARY", "THUNK"):
                continue

            func_content = func.get("decompiled_method", "")
            func_hash = func.get("decompiled_method_hash", "unknown")

            if isinstance(func_content, bytes):
                func_content = func_content.decode('utf-8', errors='replace')

            for ioc in self.scraper.scrape(func_content, SourceType.DECOMPILED_FUNCTION, func_hash):
                self.extracted_iocs.append(ioc)
                count += 1

        return count

    def _extract_from_text(self) -> int:
        """Extract IOCs from text-based artefact surfaces.

        Walks `analysis_results["text_raw"]` and `analysis_results["text_normalized"]`,
        each a list of `{"content": str, "content_hash": str}` dicts. Each
        list is routed through its own SourceType (`TEXT_RAW` /
        `TEXT_NORMALIZED`) so analysts can distinguish IOCs that were already
        present in the raw source from those exposed only after normalisation
        (deobfuscation/beautification). Generic across text-based formats —
        used by JS today, intended for PowerShell, Python, email body,
        extracted PDF/Office text in the future.
        """
        count = 0

        for key, source_type in (
            ("text_raw", SourceType.TEXT_RAW),
            ("text_normalized", SourceType.TEXT_NORMALIZED),
        ):
            for entry in self.analysis_results.get(key, []):
                content = entry.get("content", "")
                content_hash = entry.get("content_hash", "unknown")

                if isinstance(content, bytes):
                    content = content.decode('utf-8', errors='replace')

                for ioc in self.scraper.scrape(content, source_type, content_hash):
                    self.extracted_iocs.append(ioc)
                    count += 1

        return count

    def prepare_export_data(self, exporter_type: str) -> Any:
        """
        Prepare data for specific export type.

        Returns tuple for ClickHouse or list of dicts for Print/Elasticsearch.
        """
        self.log.debug(inspect.currentframe().f_code.co_name)

        if not self.extracted_iocs:
            return None

        now = datetime.now(timezone.utc)

        if exporter_type == "ClickHouseExporter":
            data = [
                [
                    self.sha256,
                    ioc.ioc_type.value,
                    ioc.ioc_value,
                    ioc.source_type.value,
                    ioc.source_identifier,
                    now,
                ]
                for ioc in self.extracted_iocs
            ]

            column_names = [
                "sha256",
                "ioc_type",
                "ioc_value",
                "source_type",
                "source_identifier",
                "extracted_at",
            ]

            column_type_names = [
                "FixedString(64)",
                "Enum8('ipv4'=1, 'ipv6'=2, 'fqdn'=3, 'url'=4, 'email'=5, 'server'=6, "
                "'hash_md5'=10, 'hash_sha1'=11, 'hash_sha256'=12, 'cve'=20, 'cwe'=21, 'cpe'=22, "
                "'crypto_btc'=30, 'crypto_eth'=31, 'crypto_xrp'=32, 'crypto_bch'=33, "
                "'crypto_ada'=34, 'crypto_substrate'=35, 'path_linux'=40, 'path_windows'=41, "
                "'registry_key'=42, 'onion'=50)",
                "String",
                "Enum8('decompiled_function'=1, 'disassembled_function'=2, 'string'=3, "
                "'text_raw'=4, 'text_normalized'=5)",
                "String",
                "DateTime64(3, 'UTC')",
            ]

            return (data, column_names, column_type_names)

        else:
            # For PrintExporter and others - return list of dicts
            return [
                {
                    "sha256": self.sha256,
                    "ioc_type": ioc.ioc_type.value,
                    "ioc_value": ioc.ioc_value,
                    "source_type": ioc.source_type.value,
                    "source_identifier": ioc.source_identifier,
                    "extracted_at": now.isoformat(),
                }
                for ioc in self.extracted_iocs
            ]

    def get_clickhouse_table(self) -> str:
        """Return the ClickHouse table name for IOCs."""
        return "redb_iocs"

    def tag(self) -> str:
        """Return the tag for this extractor."""
        return Tag.IOC.value if hasattr(Tag, 'IOC') else "ioc"

    def export_data(self) -> bool:
        """
        Export extracted IOCs to all configured exporters.

        Returns:
            True if export succeeded, False if failed, None if no data
        """
        self.log.debug(inspect.currentframe().f_code.co_name)

        # First extract the IOCs
        extracted = self.extract()

        if not extracted:
            self.log.debug("No IOCs extracted, skipping export")
            return None

        success = True

        from redb.extractors.database_exporters import PrintExporter, ClickHouseExporter

        for exporter in self.exporters:
            try:
                if isinstance(exporter, PrintExporter):
                    # For PrintExporter, pass the list of dicts
                    export_data = self.prepare_export_data("PrintExporter")
                    success &= exporter.export(export_data)

                elif isinstance(exporter, ClickHouseExporter):
                    # For ClickHouse, pass tuple with table info
                    export_data = self.prepare_export_data("ClickHouseExporter")
                    if export_data:
                        success &= exporter.export(
                            export_data,
                            table=self.get_clickhouse_table(),
                            column_names=export_data[1],
                            column_type_names=export_data[2]
                        )

            except Exception as e:
                self.log.error(f"Error exporting IOCs to {exporter.__class__.__name__}: {e}")
                success = False

        return success