Kai Wu

74 papers A* 1A 1B 1Journal 60Unranked 10
YearRankTypeTitle / Venue / Authors
2026 J jnl
IEEE Trans. Wirel. Commun.
Yanmo Hu, Kai Wu, J. Andrew Zhang, Weibo Deng, Y. Jay Guo
2025 J jnl
IEEE Trans. Commun.
Yanmo Hu, J. Andrew Zhang, Kai Wu, Weibo Deng, Y. Jay Guo
2025 J jnl
IEEE Trans. Commun.
Xueyang Wang, Kai Wu, J. Andrew Zhang, Shiqi Gong, Chengwen Xing
2025 J jnl
IEEE Robotics Autom. Lett.
Kai Wu, Qi Chen, Huan Zhao, Mingfeng Wang
2025 conf
WIFS
Chen Li, Xuelei Qi, Kai Wu, Xin Yuan, Wei Ni, Ren Ping Liu, Quan Z. Sheng
2025 B conf
GLOBECOM
Zhongqin Wang, J. Andrew Zhang, Kai Wu, Y. Jay Guo
2025 J jnl
IEEE Trans. Commun.
Jinsong Chen, Kai Wu, Jinping Niu, Yanyan Li, Pengfei Xu, J. Andrew Zhang
2025 J jnl
CoRR
Tengjun Ni, Xin Yuan, Shenghong Li, Kai Wu, Ren Ping Liu, Wei Ni, Wenjie Zhang
2025 J jnl
Signal Process.
Kai Wu, Jing Dong, Guifu Hu, Chang Liu, Wenwu Wang
2025 J jnl
CoRR
Zhongqin Wang, J. Andrew Zhang, Kai Wu, Min Xu, Y. Jay Guo
2025 A conf
ICWS
Chen Li, Xuelei Qi, Xin Yuan, Kai Wu, Yang Zhang, Wei Ni, Ren Ping Liu, Quan Z. Sheng
2025 J jnl
IEEE Commun. Mag.
J. Andrew Zhang, Hongyang Zhang, Kai Wu, Xiaojing Huang, Jinhong Yuan, Y. Jay Guo
2025 conf
EMNLP (Findings)
Hangyu He, Xin Yuan, Kai Wu, Ren Ping Liu, Wei Ni
2024 J jnl
IEEE Commun. Lett.
Jinsong Chen, Kang-Feng Zhu, Kai Wu, Jinping Niu, J. Andrew Zhang
2024 J jnl
Sensors
Jinsong Chen, Kai Wu, Jinping Niu, Yanyan Li
2024 J jnl
IEEE Internet Things J.
Kai Wu, J. Andrew Zhang, Zhitong Ni, Xiaojing Huang, Y. Jay Guo, Shanzhi Chen
2024 J jnl
CoRR
Yanmo Hu, Kai Wu, J. Andrew Zhang, Weibo Deng, Y. Jay Guo
2024 J jnl
IEEE Trans. Wirel. Commun.
Yanmo Hu, Kai Wu, J. Andrew Zhang, Weibo Deng, Y. Jay Guo
2024 conf
ICC Workshops
Yanmo Hu, Kai Wu, J. Andrew Zhang, Weibo Deng, Y. Jay Guo
2024 J jnl
Digit. Commun. Networks
Jiangtao Liu, Kai Wu, Tao Su, J. Andrew Zhang
2024 J jnl
IEEE Signal Process. Mag.
Kai Wu, Jacopo Pegoraro, Francesca Meneghello, J. Andrew Zhang, Jesus Omar Lacruz, Joerg Widmer, Francesco Restuccia, Michele Rossi, Xiaojing Huang, Daqing Zhang, Giuseppe Caire, Y. Jay Guo
2023 conf
ICC
Kai Wu, J. Andrew Zhang, Xiaojing Huang, Y. Jay Guo
2023 conf
ICC Workshops
Charles A. Guo, Y. Jay Guo, Kai Wu, Jinhong Yuan
2023 A* conf
ICDE
Jason Sun, Haoxiang Ma, Li Zhang, Huicong Liu, Haiyang Shi, Shangyu Luo, Kai Wu, Kevin Bruhwiler, Cheng Zhu, Yuanyuan Nie, Jianjun Chen, Lei Zhang, Yuming Liang
2023 J jnl
IEEE Trans. Veh. Technol.
J. Andrew Zhang, Kai Wu, Xiaojing Huang, Y. Jay Guo
2023 J jnl
Neural Networks
Jing Dong, Kai Wu, Chang Liu, Xue Mei, Wenwu Wang
2023 J jnl
Environ. Model. Softw.
Zhiyi Zhu, Min Chen, Zhen Qian, Hengyue Li, Kai Wu, Zaiyang Ma, Yongning Wen, Songshan Yue, Guonian Lü
2023 conf
ICMRE
Dehua Gao, Kai Wu, Jiaquan Li, Junpei Zhong, Huan Zhao
2023 J jnl
IEEE Wirel. Commun. Lett.
Yang Sun, J. Andrew Zhang, Kai Wu, Ren Ping Liu
2023 J jnl
IEEE Commun. Mag.
Kai Wu, Jian (Andrew) Zhang, Xiaojing Huang, Robert W. Heath Jr., Y. Jay Guo
2023 conf
NER
Renata Saha, Kai Wu, Jianping Wang
2023 J jnl
IEEE Trans. Syst. Man Cybern. Syst.
Haitao Liu, Kai Wu, Yew-Soon Ong, Chao Bian, Xiaomo Jiang, Xiaofang Wang
2023 J jnl
IEEE Internet Things J.
Kai Wu, J. Andrew Zhang, Xiaojing Huang, Y. Jay Guo
2023 J jnl
IEEE Trans. Commun.
Zhitong Ni, J. Andrew Zhang, Kai Wu, Kai Yang, Ren Ping Liu
2023 J jnl
IEEE Trans. Commun.
Kai Wu, J. Andrew Zhang, Xiaojing Huang, Y. Jay Guo, Lajos Hanzo
2023 J jnl
IEEE Trans. Signal Process.
Zhitong Ni, J. Andrew Zhang, Kai Wu, Ren Ping Liu
2023 J jnl
IEEE Trans. Commun.
Yunsi Ma, Nan Wu, Kai Wu, J. Andrew Zhang
2022 J jnl
IEEE Trans Autom. Sci. Eng.
Chen Zhang, Jun Long Lim, Ouyang Liu, Aayush Madan, Yongwei Zhu, Shili Xiang, Kai Wu, Rebecca Yen-Ni Wong, Eugene Phua Jiliang, Karan M. Sabnani, Keng Boon Siah, Wenyu Jiang, Yixin Wang, Emily Hao Jianzhong, Steven C. H. Hoi
2022 J jnl
Sensors
Kai Wu, J. Andrew Zhang, Xiaojing Huang, Y. Jay Guo, Diep N. Nguyen, Asanka Kekirigoda, Kin-Ping Hui
2022 J jnl
Proc. VLDB Endow.
Jianjun Chen, Yonghua Ding, Ye Liu, Fangshi Li, Li Zhang, Mingyi Zhang, Kui Wei, Lixun Cao, Dan Zou, Yang Liu, Lei Zhang, Rui Shi, Wei Ding, Kai Wu, Shangyu Luo, Jason Sun, Yuming Liang
2022 J jnl
IEEE Commun. Surv. Tutorials
J. Andrew Zhang, Md. Lushanur Rahman, Kai Wu, Xiaojing Huang, Y. Jay Guo, Shanzhi Chen, Jinhong Yuan
2022 J jnl
CoRR
Kai Wu, J. Andrew Zhang, Y. Jay Guo
2022 J jnl
IEEE Signal Process. Mag.
Kai Wu, J. Andrew Zhang, Y. Jay Guo
2022 J jnl
IEEE J. Sel. Areas Commun.
Kai Wu, J. Andrew Zhang, Xiaojing Huang, Y. Jay Guo
2022 J jnl
IEEE Trans. Wirel. Commun.
Kai Wu, J. Andrew Zhang, Xiaojing Huang, Y. Jay Guo
2022 J jnl
IEEE Commun. Mag.
J. Andrew Zhang, Kai Wu, Xiaojing Huang, Y. Jay Guo, Daqing Zhang, Robert W. Heath Jr.
2022 J jnl
Sensors
Kai Wu, Jian Andrew Zhang, Xiaojing Huang, Yingjie Jay Guo
2022 J jnl
CoRR
Kai Wu, J. Andrew Zhang, Zhitong Ni, Xiaojing Huang, Y. Jay Guo, Shanzhi Chen
2022 J jnl
CoRR
Haitao Liu, Kai Wu, Yew-Soon Ong, Xiaomo Jiang, Xiaofang Wang
2022 J jnl
IEEE J. Sel. Top. Appl. Earth Obs. Remote. Sens.
Min Cao, Lijiao Chang, Shangjing Ma, Zijun Zhao, Kai Wu, Xue Hu, Qiushi Gu, Guonian Lü, Min Chen
2022 conf
VTC Spring
Kai Wu, J. Andrew Zhang, Xiaojing Huang, Y. Jay Guo
2022 J jnl
Sensors
Kai Wu, J. Andrew Zhang, Xiaojing Huang, Y. Jay Guo
2022 J jnl
CoRR
Kai Wu, J. Andrew Zhang, Xiaojing Huang, Y. Jay Guo, Lajos Hanzo
2022 J jnl
CoRR
Zhitong Ni, J. Andrew Zhang, Kai Wu, Ren Ping Liu
2021 J jnl
IEEE Trans. Veh. Technol.
Kai Wu, J. Andrew Zhang, Xiaojing Huang, Y. Jay Guo
2021 J jnl
CoRR
Vinit Kumar Chugh, Kai Wu, Venkatramana D. Krishna, Arturo di Girolamo, Robert P. Bloom, Yongqiang Andrew Wang, Renata Saha, Shuang Liang, Maxim C.-J. Cheeran, Jianping Wang
2021 J jnl
Comput. Chem. Eng.
Xinhe Chen, Kai Wu, Andrew Bai, Cornelius M. Masuku, Jacques Niederberger, Fábio S. Liporace, Lorenz T. Biegler
2021 J jnl
IEEE Trans. Commun.
Kai Wu, J. Andrew Zhang, Xiaojing Huang, Y. Jay Guo, Jinhong Yuan
2021 J jnl
IEEE Trans. Commun.
Kai Wu, J. Andrew Zhang, Xiaojing Huang, Y. Jay Guo, Robert W. Heath Jr.
2020 conf
ICC Workshops
Kai Wu, Y. Jay Guo, Xiaojing Huang, Robert W. Heath Jr.
2020 J jnl
CoRR
Md. Lushanur Rahman, J. Andrew Zhang, Kai Wu, Xiaojing Huang, Y. Jay Guo, Shanzhi Chen, Jinhong Yuan
2020 J jnl
IEEE Trans. Wirel. Commun.
Chuan Qin, J. Andrew Zhang, Xiaojing Huang, Kai Wu, Y. Jay Guo
2020 J jnl
CoRR
Kai Wu, J. Andrew Zhang, Xiaojing Huang, Y. Jay Guo
2020 conf
ICC Workshops
Yawen Fan, Jingchao Bao, Kai Wu, Husheng Li
2020 J jnl
IEEE Commun. Lett.
Kai Wu, Wei Ni, J. Andrew Zhang, Ren Ping Liu, Y. Jay Guo
2020 J jnl
IEEE Commun. Lett.
Kai Wu, Wei Ni, J. Andrew Zhang, Ren Ping Liu, Y. Jay Guo
2019 J jnl
IEEE Commun. Lett.
Qiang Li, Tao Su, Kai Wu
2019 J jnl
IEEE J. Sel. Areas Commun.
Kai Wu, Wei Ni, Tao Su, Ren Ping Liu, Y. Jay Guo
2019 J jnl
IEEE Trans. Wirel. Commun.
Kai Wu, Wei Ni, Tao Su, Ren Ping Liu, Y. Jay Guo
2019 J jnl
IEEE J. Sel. Top. Signal Process.
Kai Wu, Wei Ni, Tao Su, Ren Ping Liu, Y. Jay Guo
2019
Kai Wu
2019 J jnl
IEEE Commun. Mag.
Kai Wu, Wei Ni, Tao Su, Ren Ping Liu, Y. Jay Guo
2018 J jnl
IEEE J. Sel. Areas Commun.
Kai Wu, Wei Ni, Tao Su, Ren Ping Liu, Y. Jay Guo
2018 J jnl
IEEE Trans. Wirel. Commun.
Kai Wu, Wei Ni, Tao Su, Ren Ping Liu, Y. Jay Guo
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