Xiaohao Cai

90 papers A* 3A 5B 1C 2Journal 71Unranked 8
YearRankTypeTitle / Venue / Authors
2026 J jnl
CoRR
Lingzhi Shen, Xiaohao Cai, Yunfei Long, Imran Razzak, Guanming Chen, Shoaib Jameel
2026 A* conf
AAAI
Hongli Chen, Pengcheng Fang, Yuxia Chen, Yingxuan Ren, Jing Hao, Fangfang Tang, Xiaohao Cai, Shanshan Shan, Feng Liu
2026 A* conf
AAAI
Dongjie Fu, Tengjiao Sun, Pengcheng Fang, Xiaohao Cai, Hansung Kim
2026 J jnl
CoRR
Dalia Nahhas, Xiaohao Cai, Imran Razzak, Shoaib Jameel
2026 J jnl
CoRR
Huahua Lin, Katayoun Farrahi, Xiaohao Cai
2025 conf
ECC
Daniel Hobson, Bing Chu, Xiaohao Cai
2025 J jnl
Artif. Intell. Rev.
Khaled Alomar, Halil Ibrahim Aysel, Xiaohao Cai
2025 J jnl
CoRR
Halil Ibrahim Aysel, Xiaohao Cai, Adam Prügel-Bennett
2025 J jnl
CoRR
Ruixiao Zhang, Runwei Guan, Xiangyu Chen, Adam Prügel-Bennett, Xiaohao Cai
2025 A conf
CIKM
Lingzhi Shen, Xiaohao Cai, Yunfei Long, Imran Razzak, Guanming Chen, Shoaib Jameel
2025 J jnl
CoRR
Lingzhi Shen, Xiaohao Cai, Yunfei Long, Imran Razzak, Guanming Chen, Shoaib Jameel
2025 J jnl
CoRR
Huahua Lin, Xiaohao Cai, Mark S. Nixon, James M. Mulqueeney, Thomas H. G. Ezard
2025 A conf
WSDM
Lingzhi Shen, Yunfei Long, Xiaohao Cai, Imran Razzak, Guanming Chen, Kang Liu, Shoaib Jameel
2025 J jnl
CoRR
Xudong Han, Pengcheng Fang, Yueying Tian, Jianhui Yu, Xiaohao Cai, Daniel Roggen, Philip Birch
2025 J jnl
CoRR
Guanming Chen, Lingzhi Shen, Xiaohao Cai, Imran Razzak, Shoaib Jameel
2025 J jnl
CoRR
Hongli Chen, Pengcheng Fang, Yuxia Chen, Yingxuan Ren, Jing Hao, Fangfang Tang, Xiaohao Cai, Shanshan Shan, Feng Liu
2025 J jnl
CoRR
Pengcheng Fang, Hongli Chen, Guangzhen Yao, Jian Shi, Fangfang Tang, Xiaohao Cai, Shanshan Shan, Feng Liu
2025 A conf
ICME
Lingzhi Shen, Yunfei Long, Xiaohao Cai, Guanming Chen, Yuhan Wang, Imran Razzak, Shoaib Jameel
2025 J jnl
CoRR
Lingzhi Shen, Yunfei Long, Xiaohao Cai, Guanming Chen, Yuhan Wang, Imran Razzak, Shoaib Jameel
2025 B conf
IJCNN
Lingzhi Shen, Yunfei Long, Xiaohao Cai, Guanming Chen, Imran Razzak, Shoaib Jameel
2025 J jnl
CoRR
Lingzhi Shen, Yunfei Long, Xiaohao Cai, Guanming Chen, Imran Razzak, Shoaib Jameel
2025 J jnl
CoRR
Dongjie Fu, Tengjiao Sun, Pengcheng Fang, Xiaohao Cai, Hansung Kim
2025 J jnl
CoRR
Yiyang Zhang, Tengjiao Sun, Pengcheng Fang, Deng-Bao Wang, Xiaohao Cai, Min-Ling Zhang, Hansung Kim
2025 J jnl
Trans. Mach. Learn. Res.
Juheon Lee, Xiaohao Cai, Carola-Bibiane Schönlieb, Simon Masnou
2025 A* conf
ICRA
Runwei Guan, Ruixiao Zhang, Ningwei Ouyang, Jianan Liu, Ka Lok Man, Xiaohao Cai, Ming Xu, Jeremy S. Smith, Eng Gee Lim, Yutao Yue, Hui Xiong
2025 J jnl
CoRR
Bochen Lyu, Yiyang Jia, Xiaohao Cai, Zhanxing Zhu
2025 conf
MICCAI (16)
Guanghua He, Wangang Cheng, Hancan Zhu, Xiaohao Cai, Gaohang Yu
2025 J jnl
CoRR
Guanghua He, Wangang Cheng, Hancan Zhu, Xiaohao Cai, Gaohang Yu
2024 J jnl
Pattern Anal. Appl.
Wai-Tsun Yeung, Xiaohao Cai, Zizhen Liang, Byung-Ho Kang
2024 A conf
ECAI
Ruixiao Zhang, Yihong Wu, Juheon Lee, Xiaohao Cai, Adam Prügel-Bennett
2024 J jnl
CoRR
Ruixiao Zhang, Yihong Wu, Juheon Lee, Adam Prügel-Bennett, Xiaohao Cai
2024 J jnl
CoRR
Keqiang Fan, Xiaohao Cai, Mahesan Niranjan
2024 J jnl
Comput. Biol. Medicine
Keqiang Fan, Xiaohao Cai, Mahesan Niranjan
2024 J jnl
Frontiers Comput. Sci.
Xiaohao Cai, Youwei Wen, Jianming Liang
2024 J jnl
CoRR
Lingzhi Shen, Yunfei Long, Xiaohao Cai, Imran Razzak, Guanming Chen, Kang Liu, Shoaib Jameel
2024 J jnl
IEEE Trans. Artif. Intell.
Halil Ibrahim Aysel, Xiaohao Cai, Adam Prügel-Bennett
2024 J jnl
CoRR
Juheon Lee, Xiaohao Cai, Carola-Bibiane Schönlieb, Simon Masnou
2024 J jnl
CoRR
Keqiang Fan, Xiaohao Cai, Mahesan Niranjan
2024 J jnl
Image Vis. Comput.
Keqiang Fan, Xiaohao Cai, Mahesan Niranjan
2024 J jnl
CoRR
Khaled Alomar, Halil Ibrahim Aysel, Xiaohao Cai
2024 J jnl
CoRR
Ruixiao Zhang, Juheon Lee, Xiaohao Cai, Adam Prügel-Bennett
2024 J jnl
CoRR
Runwei Guan, Ruixiao Zhang, Ningwei Ouyang, Jianan Liu, Ka Lok Man, Xiaohao Cai, Ming Xu, Jeremy S. Smith, Eng Gee Lim, Yutao Yue, Hui Xiong
2023 A conf
ECAI
Gennaro Auricchio, Ruixiao Zhang, Jie Zhang, Xiaohao Cai
2023 J jnl
CoRR
Gennaro Auricchio, Ruixiao Zhang, Jie Zhang, Xiaohao Cai
2023 J jnl
CoRR
Gaohang Yu, Jinhong Feng, Zhongming Chen, Xiaohao Cai, Liqun Qi
2023 J jnl
J. Imaging
Khaled Alomar, Halil Ibrahim Aysel, Xiaohao Cai
2023 J jnl
CoRR
Jiahui Liu, Keqiang Fan, Xiaohao Cai, Mahesan Niranjan
2023 J jnl
CoRR
Jiahui Liu, Xiaohao Cai, Mahesan Niranjan
2023 conf
ICONIP (6)
Keqiang Fan, Xiaohao Cai, Mahesan Niranjan
2023 J jnl
CoRR
Keqiang Fan, Xiaohao Cai, Mahesan Niranjan
2023 J jnl
CoRR
Wandi Dong, Gaohang Yu, Liqun Qi, Xiaohao Cai
2023 J jnl
J. Sci. Comput.
Wandi Dong, Gaohang Yu, Liqun Qi, Xiaohao Cai
2023 J jnl
Sensors
Leyang Li, Guixing Cao, Jun Liu, Xiaohao Cai
2023 J jnl
Digit. Signal Process.
Mingyang Du, Ping Zhong, Xiaohao Cai, Daping Bi, Aiqi Jing
2023 J jnl
CoRR
Halil Ibrahim Aysel, Xiaohao Cai, Adam Prügel-Bennett
2023 J jnl
CoRR
Jiahui Liu, Xiaohao Cai, Mahesan Niranjan
2023 C conf
ICMLA
Khaled Alomar, Xiaohao Cai
2023 J jnl
CoRR
Khaled Alomar, Xiaohao Cai
2022 conf
RFID-TA
Mingyang Du, Ping Zhong, Xiaohao Cai, Daping Bi, Zhifei Li
2022 J jnl
IEEE Trans. Aerosp. Electron. Syst.
Mingyang Du, Ping Zhong, Xiaohao Cai, Daping Bi
2022 J jnl
Stat. Comput.
Xiaohao Cai, Jason D. McEwen, Marcelo Pereyra
2021 J jnl
IEEE Trans. Signal Process.
Mingyang Du, Xikai He, Xiaohao Cai, Daping Bi
2021 conf
EUSIPCO
Dimitrios Mallios, Xiaohao Cai
2020 J jnl
CoRR
Wai-Tsun Yeung, Xiaohao Cai, Zizhen Liang, Byung-Ho Kang
2020 J jnl
IEEE Trans. Geosci. Remote. Sens.
Jonathan Williams, Carola-Bibiane Schönlieb, Tom Swinfield, Juheon Lee, Xiaohao Cai, Lan Qie, David A. Coomes
2020 J jnl
Pattern Recognit.
Xiaohao Cai, Christopher G. R. Wallis, Jennifer Y. H. Chan, Jason D. McEwen
2019 J jnl
CoRR
Xiaohao Cai, Raymond H. Chan, Xiaoyu Xie, Tieyong Zeng
2019 J jnl
SIAM J. Sci. Comput.
Xiaohao Cai, Raymond H. Chan, Carola-Bibiane Schönlieb, Gabriele Steidl, Tieyong Zeng
2019 conf
EUSIPCO
Xiaohao Cai, Marcelo Pereyra, Jason D. McEwen
2019 J jnl
CoRR
Jonathan V. Williams, Carola-Bibiane Schönlieb, Tom Swinfield, Juheon Lee, Xiaohao Cai, Lan Qie, David A. Coomes
2018 J jnl
CoRR
Xiaohao Cai, Raymond H. Chan, Carola-Bibiane Schönlieb, Gabriele Steidl, Tieyong Zeng
2017 J jnl
J. Sci. Comput.
Xiaohao Cai, Raymond H. Chan, Mila Nikolova, Tieyong Zeng
2017 J jnl
CoRR
Juheon Lee, David Coomes, Carola-Bibiane Schönlieb, Xiaohao Cai, Jan Lellmann, Michele Dalponte, Yadvinder Malhi, Nathalie Butt, Mike Morecroft
2017 J jnl
CoRR
Xiaohao Cai, Luke Pratley, Jason D. McEwen
2017 J jnl
CoRR
Xiaohao Cai, Marcelo Pereyra, Jason D. McEwen
2017 J jnl
CoRR
Xiaohao Cai, Marcelo Pereyra, Jason D. McEwen
2017 J jnl
Comput. Geosci.
Benjamin Bauer, Xiaohao Cai, Stephan Peth, Katja Schladitz, Gabriele Steidl
2016 J jnl
IEEE J. Sel. Top. Appl. Earth Obs. Remote. Sens.
Juheon Lee, Xiaohao Cai, Jan Lellmann, Michele Dalponte, Yadvinder Malhi, Nathalie Butt, Mike Morecroft, Carola-Bibiane Schönlieb, David A. Coomes
2016 J jnl
CoRR
Xiaohao Cai, Christopher G. R. Wallis, Jennifer Y. H. Chan, Jason D. McEwen
2015 J jnl
CoRR
Xiaohao Cai, Raymond H. Chan, Mila Nikolova, Tieyong Zeng
2015 C conf
IGARSS
Juheon Lee, Xiaohao Cai, Carola-Bibiane Schönlieb, David Coomes
2015 J jnl
IEEE Trans. Geosci. Remote. Sens.
Juheon Lee, Xiaohao Cai, Carola-Bibiane Schönlieb, David Coomes
2015 J jnl
Pattern Recognit.
Xiaohao Cai
2014 J jnl
CoRR
Juheon Lee, Xiaohao Cai, Carola-Bibiane Schönlieb, David Coomes
2014 J jnl
CoRR
Xiaohao Cai
2013 J jnl
SIAM J. Imaging Sci.
Xiaohao Cai, Raymond H. Chan, Tieyong Zeng
2013 conf
EMMCVPR
Xiaohao Cai, Gabriele Steidl
2013 J jnl
SIAM J. Imaging Sci.
Xiaohao Cai, Raymond H. Chan, Serena Morigi, Fiorella Sgallari
2011 conf
SSVM
Xiaohao Cai, Raymond H. Chan, Serena Morigi, Fiorella Sgallari
2011 J jnl
CoRR
Xiaohao Cai, Raymond H. Chan, Serena Morigi, Fiorella Sgallari
redb/extractors/decompiler/bninja/analysis/cfg-old.py
← Index redb/extractors/decompiler/bninja/analysis/cfg-old.py python
from collections import deque
from enum import Enum

from binaryninja.enums import (
    BranchType,
    InstructionTextTokenType,
)

# Support both package and standalone imports
try:
    from ..utils.hashes import calculate_md5, calculate_sha256
except ImportError:
    # Fallback to absolute imports (for multiprocessing spawned processes)
    from redb.extractors.decompiler.bninja.utils.hashes import calculate_md5, calculate_sha256


class CFGAnalysis:
    def __init__(self, function):
        self.function = function

    def determine_block_type(self, block) -> str:
        """Determine the type of a basic block."""
        # Check if it's a thunk function (usually just a jump or call)
        if len(block.disassembly_text) <= 2 and any(
            "jmp" in line.tokens[0].text.lower() for line in block.disassembly_text
        ):
            return "THUNK"

        # Check if it contains only data (no valid instructions)
        if all(not line.tokens for line in block.disassembly_text):
            return "DATA"

        # Default to code
        return "CODE"

    def extract_cyclomatic_complexity(self):
        """
        Cyclomatic complexity (McCabe’s metric) measures the number of linearly independent paths
        through a function’s control flow graph (CFG).
        The standard formula is:

            M = E - N + 2

        where:
            - E = number of edges in the CFG
            - N = number of nodes (basic blocks)
            - 2 accounts for the entry and exit nodes of a single connected graph
        """
        if self.function is None:
            return 0

        # number of basic blocks
        num_blocks = len(self.function.basic_blocks)
        # number of edges in the graph
        num_edges = sum(
            len(basic_block.outgoing_edges)
            for basic_block in self.function.basic_blocks
        )
        return num_edges - num_blocks + 2

    def extract_function_cfg(self):
        """Extract information about a function CFG and return it as a dictionary."""

        function = self.function
        function_data = {
            "function_address": self.function.start,
            "blocks": [],
            "measures": {
                "cyclomatic_complexity": self.extract_cyclomatic_complexity(),
            },
        }

        if self.function is None:
            return function_data

        # Get the map of the depth associated to every block
        depths = self.get_map_depth()

        # Get the map of the positions associated to every block
        id_maps = self.get_block_id_map()

        # Extract block data with graph structure information
        for block in function.basic_blocks:
            # dominators per every block translated
            dominators = sorted(self.extract_dominators(block, id_maps))

            # post dominators
            post_dominators = sorted(self.extract_post_dominators(block, id_maps))

            # Build block instructions string
            block_instructions = "\n".join(str(line) for line in block.disassembly_text)

            # Determine block type
            block_type = self.determine_block_type(block)

            # Extract successors directly from basic block
            successor_blocks = [edge.target.start for edge in block.outgoing_edges]
            # We ensure a canonical order and we sort the edges
            successor_blocks.sort()

            # Extract predecessors directly from basic block
            predecessor_blocks = [edge.source.start for edge in block.incoming_edges]
            # We ensure a canonical order and we sort the edges
            predecessor_blocks.sort()

            # Determine branch type from outgoing edges
            branch_type = self.determine_branch_type(block)

            instructions_count = len(block.disassembly_text)

            # Create block record
            block_json = {
                "function_address": self.function.start,
                "block_start_address": block.start,
                "block_end_address": block.end,
                "block_size": block.end - block.start,
                "instructions_count": instructions_count,
                "block_instructions_hash": calculate_sha256(block_instructions),
                "predecessor_blocks": predecessor_blocks,
                "successor_blocks": successor_blocks,
                "depth": depths[block.start],
                "position": id_maps[block.start],
                "branch_type": branch_type,
                "block_type": block_type,
                "flags": self.extract_block_flags(block),
                "dominators": dominators,
                "post_dominators": post_dominators,
            }
            function_data["blocks"].append(block_json)

        return function_data

    def extract_dominators(self, bb, id_maps):
        """Extract the dominators normalized"""
        dom_idx = [id_maps[d.start] for d in bb.dominators]
        return dom_idx

    def extract_post_dominators(self, bb, id_maps):
        """Extract the post-dominators normalized"""
        post_dom_idx = [id_maps[d.start] for d in bb.post_dominators]
        return post_dom_idx

    def determine_branch_type(self, block):
        """
        Determine the type of branch at the end of a basic block.
        This combines edge type information with instruction analysis.
        """
        # If no outgoing edges, it might be a return or terminal block
        if not block.outgoing_edges:
            # Check if the last instruction is a return
            for line in reversed(list(block.disassembly_text)):
                if line.tokens and any(
                    token.text.lower() in ["ret", "retn"] for token in line.tokens
                ):
                    return "RETURN"
            return "UNKNOWN"

        # Collect branch types from all outgoing edges
        branch_types = []
        for edge in block.outgoing_edges:
            edge_type = edge.type
            # Map edge type to our branch type enum
            if isinstance(edge_type, str):
                if edge_type == "IndirectCall":
                    branch_types.append("CALL")
                else:
                    branch_types.append("UNKNOWN")
            else:
                # Use our mapping for integer/enum values
                type_mapping = {
                    BranchType.UnconditionalBranch: "DIRECT",
                    BranchType.FalseBranch: "CONDITIONAL",
                    BranchType.TrueBranch: "CONDITIONAL",
                    BranchType.CallDestination: "CALL",
                    BranchType.FunctionReturn: "RETURN",
                    BranchType.SystemCall: "CALL",
                    BranchType.IndirectBranch: "INDIRECT",
                    BranchType.ExceptionBranch: "UNKNOWN",
                    BranchType.UnresolvedBranch: "UNKNOWN",
                    BranchType.UserDefinedBranch: "UNKNOWN",
                }
                branch_types.append(type_mapping.get(edge_type, "UNKNOWN"))

        # Determine overall branch type (prioritize CALL > RETURN > CONDITIONAL > DIRECT)
        if "CALL" in branch_types:
            return "CALL"
        elif "RETURN" in branch_types:
            return "RETURN"
        elif "CONDITIONAL" in branch_types:
            return "CONDITIONAL"
        elif "DIRECT" in branch_types:
            return "DIRECT"
        elif len(block.outgoing_edges) == 1:
            return "FALLTHROUGH"

        # If edge analysis was inconclusive, fall back to instruction analysis
        last_instr = None
        for line in reversed(list(block.disassembly_text)):
            if line.tokens:
                last_instr = line
                break

        if last_instr:
            mnemonic = None
            for token in last_instr.tokens:
                if token.type == InstructionTextTokenType.InstructionToken:
                    mnemonic = token.text.lower()
                    break

            if mnemonic:
                if mnemonic == "call":
                    return "CALL"
                elif mnemonic == "jmp":
                    return "DIRECT"
                elif mnemonic.startswith("j") and mnemonic != "jmp":
                    return "CONDITIONAL"
                elif mnemonic in ["ret", "retn"]:
                    return "RETURN"

        return "UNKNOWN"

    def get_map_depth(self):
        """
        Run a BFS on the basic blocks of the function to assign a depth to every block
        """

        depths = {}
        entry = self.function.get_basic_block_at(self.function.start)

        ### Simple BFS
        q = deque()
        q.append(entry)
        depths[entry.start] = 0

        while q:
            b = q.popleft()
            b_depth = depths[b.start]
            for edge in b.outgoing_edges:
                tgt = edge.target

                if tgt is None:
                    continue

                if tgt.start not in depths:
                    depths[tgt.start] = b_depth + 1
                    q.append(tgt)

        return depths

    def get_block_id_map(self):
        """
        Assign a unique, sequential ID to each basic block of the function using a BFS starting from the entry block.
        """

        id_map = {}
        entry = self.function.get_basic_block_at(self.function.start)

        q = deque()
        q.append(entry)

        current_id = 0
        id_map[entry.start] = current_id

        while q:
            b = q.popleft()
            for edge in b.outgoing_edges:
                tgt = edge.target

                if tgt is None:
                    continue

                if tgt.start not in id_map:
                    current_id += 1
                    id_map[tgt.start] = current_id
                    q.append(tgt)

        return id_map

    def extract_block_flags(self, block):
        """
        Get the flags for every basic block. Currently, we implemented these heuristics:
            - if a basic block is the entry node for a function
            - if a basic block is the exit block for a function
            - if a basic block is part of a natural loop
        """
        flags = []

        if block.start == self.function.start:
            flags.append(BlockFlags.EntryBlock.value)

        if any(edge.type == BranchType.FunctionReturn for edge in block.outgoing_edges):
            flags.append(BlockFlags.ExitBlock.value)

        # if this block is in its dominance frontier, then it's part of a natural loop
        if block in block.dominance_frontier:
            flags.append(BlockFlags.LoopBlock.value)

        return flags


class BlockFlags(Enum):
    # generally, the basic block identifying the entry point of the function
    EntryBlock = "EntryBlock"
    # any basic blocks that makes the control flow exiting from the current function
    ExitBlock = "ExitBlock"
    # any block is in a natural loop if it is in its own dominance frontier
    LoopBlock = "LoopBlock"


class BlockType(Enum):
    THUNK = "THUNK"
    DATA = "DATA"
    PADDING = "PADDING"
    CODE = "CODE"