Weijun Li

77 papers A* 5B 3C 5Misc 2Journal 46Unranked 16
YearRankTypeTitle / Venue / Authors
2026 J jnl
Integr.
Juntao Jian, Yan Xing, Shuting Cai, Weijun Li, Xiaoming Xiong
2026 J jnl
Integr.
Yan Xing, Zicheng Deng, Shuting Cai, Weijun Li, Xiaoming Xiong
2026 J jnl
Earth Sci. Informatics
Fu Zhang, Qinghui Li, Hongzhi Chen, Tong Shen, Jingwei Cheng, Weijun Li
2025 J jnl
Symmetry
Weijun Li, Guoliang Yang, Zhangyou Xiong, Xiaojuan Zhu, Xinyu Ma
2025 J jnl
IEEE Trans. Comput. Biol. Bioinform.
Guobo Xie, Weijun Li, Guosheng Gu, Zhiyi Lin, Dayin Li
2025 J jnl
Proc. ACM Hum. Comput. Interact.
Suqi Lou, Weijun Li, Chao Zhang, Shi Chen, Zhicong Lu, Yaxing Yao
2025 J jnl
ACM Trans. Design Autom. Electr. Syst.
Yan Xing, Hongtao Hu, Weijun Li, Shuting Cai, Xiaoming Xiong
2025 J jnl
IEEE Trans. Intell. Transp. Syst.
Weijun Li, Guozhu Cheng
2025 J jnl
IET Comput. Vis.
Shaohua Qi, Weijun Li, Guowei Yang
2025 J jnl
J. Circuits Syst. Comput.
Yihao Huang, Yan Xing, Shuting Cai, Weijun Li, Xiaoming Xiong
2025 J jnl
Eng. Appl. Artif. Intell.
Fu Zhang, Jiapeng Wang, Huangming Xu, Honglin Wu, Jingwei Cheng, Weijun Li
2025 J jnl
ACM Trans. Design Autom. Electr. Syst.
Wenhao Liu, Yan Xing, Shuting Cai, Weijun Li, Xiaoming Xiong
2025 J jnl
CoRR
YanJie Li, Jian Xu, Xueqing Chen, Lina Yu, Shiming Xiang, Weijun Li, Cheng-Lin Liu
2024 J jnl
IEEE Trans. Circuits Syst. I Regul. Pap.
Heng You, Weijun Li, Delong Shang, Yumei Zhou, Shushan Qiao
2024 A* conf
CHI
Chaoran Chen, Weijun Li, Wenxin Song, Yanfang Ye, Yaxing Yao, Toby Jia-Jun Li
2024 J jnl
J. Chem. Inf. Model.
Guobo Xie, Dayin Li, Zhiyi Lin, Guosheng Gu, Weijun Li, Ruibin Chen, Zhenguo Liu
2024 J jnl
Reliab. Eng. Syst. Saf.
Weijun Li, Qiqi Sun, Jiwang Zhang, Laibin Zhang
2024 J jnl
Evol. Intell.
Guanfeng Li, Weijun Li
2024 J jnl
CoRR
Hongxin Peng, Yongjian Liao, Weijun Li, Chuanyu Fu, Guoxin Zhang, Ziquan Ding, Zijie Huang, Qiku Cao, Shuting Cai
2024 J jnl
Adv. Eng. Informatics
Hongxin Peng, Yongjian Liao, Weijun Li, Chuanyu Fu, Guoxin Zhang, Ziquan Ding, Zijie Huang, Qiku Cao, Shuting Cai
2024 A* conf
CHI
Shi Chen, Xiaodong Wang, Weijun Li, Jingao Zhang, Yuge Qi, Jiaqi Teng, Zhihan Zeng
2024 J jnl
ACM Trans. Design Autom. Electr. Syst.
Juming Xian, Yan Xing, Shuting Cai, Weijun Li, Xiaoming Xiong, Zhengfa Hu
2024 J jnl
Appl. Intell.
Fu Zhang, Pengpeng Qiu, Tong Shen, Jingwei Cheng, Weijun Li
2023 Misc conf
IDC
Weijun Li, Yaohua Bu, Suqi Lou, Shi Chen, Lingyun Sun, Changyuan Yang
2023 J jnl
IEEE J. Sel. Top. Appl. Earth Obs. Remote. Sens.
Nan Huang, Zijie Huang, Chuanyu Fu, Hewen Zhou, Yimin Xia, Weijun Li, Xiaoming Xiong, Shuting Cai
2023 J jnl
CoRR
Chaoran Chen, Weijun Li, Wenxin Song, Yanfang Ye, Yaxing Yao, Toby Jia-Jun Li
2023 A* conf
ACM Multimedia
Jingyu Wu, Shi Chen, Shuyu Gan, Weijun Li, Changyuan Yang, Lingyun Sun
2023 Misc conf
IDC
Yilin Shao, Boyu Feng, Yingpin Chen, Yue Yang, Weijun Li, Yifan Yan, Yanan Wang, Ye Tao, Lingyun Sun, Guanyun Wang
2023 J jnl
Frontiers Neurorobotics
Zhaoyong Liu, Yihang Li, Weijun Li, Zefan Li, Haosen Zhang, Xiaoqiang Tan, Guangqiang Wu
2023 J jnl
Proc. ACM Hum. Comput. Interact.
Weijun Li, Shi Chen, Lingyun Sun, Changyuan Yang
2022 J jnl
Entropy
Zhanyou Ma, Zhaokai Li, Weijun Li, Yingnan Gao, Xia Li
2022 J jnl
Reliab. Eng. Syst. Saf.
Shuanglei Liu, Weijun Li, Peng Gao, Yibo Sun
2022 J jnl
IEEE Trans. Intell. Transp. Syst.
Guang Chen, Fa Wang, Weijun Li, Lin Hong, Jörg Conradt, Jieneng Chen, Zhenyan Zhang, Yiwen Lu, Alois C. Knoll
2021 J jnl
IEEE Access
Qun Yang, Dejian Shen, Wencai Du, Weijun Li
2021 J jnl
Comput. Electron. Agric.
Hui Li, Weijun Li, Matthew McEwan, Daoliang Li, Guoping Lian, Tao Chen
2021 conf
ICEA
Hao Liu, Lejun Ji, Ting Xiong, Weijun Li, Lili Wang, Yuanlong Cao
2021 J jnl
Entropy
Zirui Zhang, Ping Chen, Weijun Li, Xiaoming Xiong, Qianxue Wang, Heping Wen, Songbin Liu, Shuting Cai
2021 conf
ICCMA
Dingmei Wang, Yan Wang, Weijun Li, Haiying Dong
2021 J jnl
CoRR
Liang Xu, Liying Zheng, Weijun Li, Zhenbo Chen, Weishun Song, Yue Deng, Yongzhe Chang, Jing Xiao, Bo Yuan
2021 A* conf
CHI
Yaohua Bu, Tianyi Ma, Weijun Li, Hang Zhou, Jia Jia, Shengqi Chen, Kaiyuan Xu, Dachuan Shi, Haozhe Wu, Zhihan Yang, Kun Li, Zhiyong Wu, Yuanchun Shi, Xiaobo Lu, Ziwei Liu
2021 J jnl
CoRR
Yaohua Bu, Tianyi Ma, Weijun Li, Hang Zhou, Jia Jia, Shengqi Chen, Kaiyuan Xu, Dachuan Shi, Haozhe Wu, Zhihan Yang, Kun Li, Zhiyong Wu, Yuanchun Shi, Xiaobo Lu, Ziwei Liu
2020 J jnl
IEEE Access
Feng Li, Weijun Li, Wenfeng Chen, Weifeng Xu, Linqing Huang, Dan Li, Shuting Cai, Ming Yang, Xiaoming Xiong, Yuan Liu
2020 conf
CollaborateCom (1)
Jiayun Lin, Fang Liu, Zhenhua Cai, Zhijie Huang, Weijun Li, Nong Xiao
2020 conf
JCDL
Weijun Li, Fukai Yang, Ruibing Jia, Renmin Li, Minghao Yin
2020 J jnl
CoRR
Yaohua Bu, Weijun Li, Tianyi Ma, Shengqi Chen, Jia Jia, Kun Li, Xiaobo Lu
2020 conf
ICAIS (1)
Zhenyuan Zhang, Fang Liu, Zhenhua Cai, Yihong Su, Weijun Li
2020 B conf
FUZZ-IEEE
Guanfeng Li, Weijun Li, Hairong Wang
2020 J jnl
Comput. Chem. Eng.
Weijun Li, Sai Gu, Xiangping Zhang, Tao Chen
2020 A* conf
ACM Multimedia
Yaohua Bu, Weijun Li, Tianyi Ma, Shengqi Chen, Jia Jia, Kun Li, Xiaobo Lu
2019 J jnl
Reliab. Eng. Syst. Saf.
Weijun Li, Min He, Yibo Sun, Qinggui Cao
2019 J jnl
Sensors
Kan Xie, Yue Lai, Weijun Li
2019 J jnl
Int. J. Pattern Recognit. Artif. Intell.
Kan Xie, Wei Liu, Yue Lai, Weijun Li
2019 conf
AMLTA
Yujie Pei, Jinglong Mu, Weijun Li, Jun Dong, Jianguo Xu, Chunmei Guan, Yi Qu, Hongchuang Ma
2019 conf
HPCC/SmartCity/DSS
Fan Ni, Xingbo Wu, Weijun Li, Lei Wang, Song Jiang
2019 C conf
SERA
Huawei Ma, Wencai Du, Simon Xu, Weijun Li
2018 J jnl
IEEE Access
Weijun Li, Li Yan, Fu Zhang, Xu Chen
2018 conf
ICAIP
Yibang Zhou, Qimeng Liu, Yueteng Zhao, Weijun Li
2018 C conf
ISPDC
Dongyang Li, Yafei Yang, Weijun Li, Qing Yang
2018 B conf
IJCNN
Lusi Li, Haibo He, Jie Li, Weijun Li
2018 C conf
IPCCC
Haitao Wang, Zhanhuai Li, Xiao Zhang, Xiaonan Zhao, Xingsheng Zhao, Weijun Li, Song Jiang
2018 C conf
IPCCC
Fan Ni, Xingbo Wu, Weijun Li, Song Jiang
2018 J jnl
Perform. Evaluation
Fan Ni, Xingbo Wu, Weijun Li, Lei Wang, Song Jiang
2018 J jnl
SIGMETRICS Perform. Evaluation Rev.
Fan Ni, Xingbo Wu, Weijun Li, Lei Wang, Song Jiang
2017 conf
ICNC-FSKD
Xu Chen, Weijun Li, Li Yan
2017 J jnl
J. Intell. Fuzzy Syst.
Xu Chen, Haitao Cheng, Hairong Wang, Weijun Li
2017 J jnl
IEEE Access
Xu Chen, Li Yan, Weijun Li, Zongmin Ma
2015 conf
ICCAIS
Beihai Tan, Jinrong Lin, Qiuming Peng, Weijun Li
2015 J jnl
Knowl. Based Syst.
Fu Zhang, Zong Min Ma, Weijun Li
2014 B conf
FUZZ-IEEE
Weijun Li, Xu Chen, Zongmin Ma
2014 J jnl
Int. J. Distributed Sens. Networks
Weijun Li, Chao Yang, Zhenquan Wu, Beihai Tan, Yuli Fu
2011 conf
AICI (2)
Chen Chen, Weijun Li, Liang Chen
2011 conf
AICI (2)
Liang Chen, Weijun Li, Chen Chen
2009 C conf
IAS
Zhenyu Liu, Weijun Li, Yue Lai
2009 conf
ICNC (1)
Min Zhao, Weijun Li, Guoxu Zhou, Zhiheng Zhou
2009 conf
FSKD (3)
Zhiliang Xu, Zhiheng Zhou, Weijun Li
2008 conf
FSKD (4)
Lei Dai, Weijun Li, Xu Chen, Xiaoxian Jin, Yanfeng Qu
2008 conf
FSKD (1)
Beihai Tan, Weijun Li
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"