Nengfu Xie

45 papers B 2C 4Journal 16Unranked 23
YearRankTypeTitle / Venue / Authors
2026 J jnl
IEEE Trans. Big Data
Yunpeng Zhao, Shansong Wang, Qingtian Zeng, Weijian Ni, Hua Duan, Nengfu Xie, Fengjin Xiao
2025 J jnl
Comput. Electron. Agric.
Shansong Wang, Qingtian Zeng, Guiyuan Yuan, Weijian Ni, Chao Li, Hua Duan, Nengfu Xie, Fengjin Xiao, Xiaofeng Yang
2025 J jnl
Multim. Syst.
Chao Li, Xin Li, Xiangkai Zhu, Qingtian Zeng, Hua Duan, Nengfu Xie
2025 J jnl
Comput. Intell.
Ruiyang Li, Ge Song, Shansong Wang, Qingtian Zeng, Guiyuan Yuan, Weijian Ni, Nengfu Xie, Fengjin Xiao
2025 J jnl
Earth Sci. Informatics
Ying Chen, Huanping Wu, Nengfu Xie, Xiaohe Liang, Lihua Jiang, Minghui Qiu, Yonglei Li
2025 J jnl
Appl. Intell.
Qianyu Song, Chao Li, Jinhu Fu, Qingtian Zeng, Nengfu Xie
2024 J jnl
Multim. Tools Appl.
Shansong Wang, Weijian Ni, Qingtian Zeng, Nengfu Xie, Chao Li
2024 J jnl
Multim. Syst.
Qingtian Zeng, Xinheng Li, Shansong Wang, Weijian Ni, Hua Duan, Nengfu Xie, Fengjin Xiao
2021 C conf
IPCCC
Yuejing Chen, Ailian Zhou, Xiaohe Liang, Nengfu Xie, Huijuan Wang, Xiaoyu Li
2021 J jnl
Multim. Tools Appl.
Xieling Chen, Xinxin Zhang, Haoran Xie, Xiaohui Tao, Fu Lee Wang, Nengfu Xie, Tianyong Hao
2021 J jnl
ACM Trans. Asian Low Resour. Lang. Inf. Process.
Weijian Ni, Tong Liu, Qingtian Zeng, Nengfu Xie
2021 C conf
IPCCC
Yuxin Shi, Ailian Zhou, Xiaohe Liang, Nengfu Xie, Saisai Wu, Xiaoyu Li
2020 C conf
IPCCC
Lihua Jiang, Jiawei Yan, Nengfu Xie
2020 J jnl
IEEE Access
Qingtian Zeng, Xiaojie Tang, Weijian Ni, Hua Duan, Chao Li, Nengfu Xie
2020 C conf
IPCCC
Fan Zhang, Jizhou Wu, Yingli Nie, Lihua Jiang, Ailian Zhou, Nengfu Xie
2020 J jnl
IEEE Access
Wenyan Guo, Qingtian Zeng, Hua Duan, Weijian Ni, Tong Liu, Cong Liu, Nengfu Xie
2019 J jnl
IEEE Access
Chao Li, Qingtian Zeng, Hua Duan, Nengfu Xie
2019 conf
APWeb/WAIM (2)
Weijian Ni, Yujian Sun, Tong Liu, Qingtian Zeng, Nengfu Xie
2019 conf
APWeb/WAIM (1)
Tong Liu, Weijian Ni, Qingtian Zeng, Nengfu Xie
2019 conf
ICIAI
Nengfu Xie, Xiong Wei, Xinning Hao
2018 conf
ICCIP
Hua Zhao, Ruofei Zou, Hua Duan, Qingtian Zeng, Chao Li, Xiuli Diao, Weijian Ni, Nengfu Xie
2018 conf
ICCIP
Guiyuan Yuan, Qingtian Zeng, Hua Duan, Wenyan Guo, Weijian Ni, Nengfu Xie
2018 conf
PRICAI (1)
Weijian Ni, Tong Liu, Qingtian Zeng, Xianke Zhang, Hua Duan, Nengfu Xie
2018 conf
ICCIP
Qingtian Zeng, Hua Zhao, Hua Duan, Chao Li, Weijian Ni, Nengfu Xie, Xiuli Diao
2016 conf
ICSAI
Xinning Hao, Nengfu Xie, Wei Sun
2015 J jnl
Data Sci. J.
Leifeng Guo, Wensheng Wang, Nengfu Xie
2015 conf
CCTA (1)
Xinning Hao, Nengfu Xie, Wei Sun, Xiaochun Zhong, Xuefu Zhang
2015 J jnl
Data Sci. J.
Nengfu Xie, Wensheng Wang, Bingxian Ma, Xuefu Zhang, Wei Sun, Fenglei Guo
2015 J jnl
Data Sci. J.
Dongming Xiang, Nengfu Xie, Bingxian Ma, Kai Xu
2013 conf
CCTA (2)
Nengfu Xie, Xuefu Zhang
2013 conf
CCTA (2)
Lihua Jiang, Nengfu Xie, Hong-Bin Zhang
2013 conf
CCTA (1)
Xiaorong Yang, Nengfu Xie, Dan Wang, Lihua Jiang
2012 conf
CCTA (1)
Lihua Jiang, Hong-Bin Zhang, Xiaorong Yang, Nengfu Xie
2012 conf
CCTA (1)
Nengfu Xie
2012 conf
CCTA (1)
Xiaorong Yang, Qingtian Zeng, Nengfu Xie, Lihua Jiang
2010 conf
CCTA (1)
Lihua Jiang, Wensheng Wang, Xiaorong Yang, Nengfu Xie, Youping Cheng
2010 conf
CCTA (1)
Xiaorong Yang, Wensheng Wang, Qingtian Zeng, Nengfu Xie
2010 conf
CCTA (1)
Lihua Jiang, Wensheng Wang, Xiaorong Yang, Nengfu Xie, Youping Cheng
2009 conf
CCTA
Nengfu Xie, Wensheng Wang
2008 conf
CCTA (2)
Nengfu Xie, Wensheng Wang
2007 conf
CCTA
Nengfu Xie, Wensheng Wang, Yong Yang
2005 conf
Web Intelligence
Nengfu Xie, Cungen Cao, Hong Yu Guo
2005 conf
SKG
Nengfu Xie, Wenyin Liu
2004 B conf
KES
Nengfu Xie, Cungen Cao, Bingxian Ma, Chunxia Zhang, Jinxin Si
2004 B conf
KES
Jinxin Si, Cungen Cao, Yuefei Sui, Xiaoli Yue, Nengfu Xie
tests/unit/test_decompile_medium_level.py
← Index tests/unit/test_decompile_medium_level.py python
# tests/unit/test_decompile_medium_level.py
"""Unit tests (mocked BN) for bninja/analysis/medium_level.py
   and bninja/analysis/medium_level_normalization.py."""
# tests/unit/test_decompile_medium_level.py
import sys
from unittest.mock import MagicMock, patch

# Installa gli stubs BN
from tests.unit.conftest_binja_stubs import install_binja_stubs
install_binja_stubs()

# ── Definisci MockMLILInstruction PRIMA di importare il modulo ──
class MockMLILInstruction:
    def __init__(self, operation, address=0, operands=None):
        self.operation = operation
        self.address = address
        self.operands = operands or []

# ── Patcha il modulo BN in modo che isinstance() funzioni ──
sys.modules["binaryninja"].MediumLevelILInstruction = MockMLILInstruction
sys.modules["binaryninja"].SSAVariable = type("SSAVariable", (), {})
sys.modules["binaryninja"].Variable = type("Variable", (), {})
sys.modules["binaryninja"].ILIntrinsic = type("ILIntrinsic", (), {})

# Ora importa il modulo — vede già i tipi corretti
from redb.extractors.decompiler.bninja.analysis.medium_level_normalization import (
    MediumLevelNormalization,
)	

class MockMLILFunction:
    def __init__(self, instructions):
        self._instructions = instructions

    @property
    def instructions(self):
        return iter(self._instructions)

    @property
    def basic_blocks(self):
        # one block containing all instructions, good enough for MinHasher
        block = MagicMock()
        block.__iter__ = lambda self_: iter([])  # not used by MediumLevelAnalysis
        return [block]


class MockFunction:
    def __init__(self, name="func", start=0x1000, mlil=None):
        self.name = name
        self.start = start
        self.mlil = mlil



class TestMediumLevelNormalization:
    def setup_method(self):
        from redb.extractors.decompiler.bninja.analysis.medium_level_normalization import (
            MediumLevelNormalization,
        )
        self.norm = MediumLevelNormalization()

    def test_normalize_skeleton_single_instruction(self):
        il = MockMLILInstruction(operation=42, operands=[])
        result = self.norm.normalize_instruction_all_levels(il)
        assert result == [42]

    def test_normalize_skeleton_nested(self):
        inner = MockMLILInstruction(operation=7, operands=[])
        outer = MockMLILInstruction(operation=1, operands=[inner])
        result = self.norm.normalize_instruction_all_levels(outer)
        assert result == [1, 7]

    def test_normalize_skeleton_with_list_operand(self):
        inner_a = MockMLILInstruction(operation=10, operands=[])
        inner_b = MockMLILInstruction(operation=11, operands=[])
        outer = MockMLILInstruction(operation=2, operands=[[inner_a, inner_b]])
        result = self.norm.normalize_instruction_all_levels(outer)
        assert result == [2, 10, 11]

    def test_normalize_skeleton_none(self):
        result = self.norm.normalize_instruction_all_levels(None)
        # collect on None should leave ops empty
        assert result == []

    def test_normalize_typed_appends_leaf_types(self):
        # operand is a plain int -> "CONST"
        il = MockMLILInstruction(operation=3, operands=[42])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [3, "CONST"]

    def test_normalize_typed_bool_before_int(self):
        # bool must be detected before int (since bool is an int subclass)
        il = MockMLILInstruction(operation=4, operands=[True])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [4, "BOOL"]

    def test_normalize_typed_float(self):
        il = MockMLILInstruction(operation=5, operands=[1.5])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [5, "FLOAT_CONST"]

    def test_normalize_typed_str(self):
        il = MockMLILInstruction(operation=6, operands=["hello"])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [6, "STR"]

    def test_normalize_typed_unknown_falls_back_to_typename(self):
        class Weird:
            pass
        il = MockMLILInstruction(operation=8, operands=[Weird()])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [8, "WEIRD"]

    def test_normalize_typed_nested_mlil(self):
        inner = MockMLILInstruction(operation=99, operands=[7])
        outer = MockMLILInstruction(operation=1, operands=[inner])
        result = self.norm.normalize_instr_with_operands(outer)
        assert result == [1, 99, "CONST"]

    def test_normalize_typed_list_mixed(self):
        inner = MockMLILInstruction(operation=50, operands=[])
        il = MockMLILInstruction(operation=2, operands=[[inner, 99]])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [2, 50, "CONST"]


class TestMediumLevelAnalysis:
    def _make_analysis(self, instructions=None, mlil=True, start=0x1000):
        from redb.extractors.decompiler.bninja.analysis.medium_level import (
            MediumLevelAnalysis,
        )
        mlil_func = MockMLILFunction(instructions or []) if mlil else None
        func = MockFunction(name="testfunc", start=start, mlil=mlil_func)
        bv = MagicMock()
        return MediumLevelAnalysis(func, bv, MagicMock())

    def test_collect_returns_empty_when_no_mlil(self):
        a = self._make_analysis(mlil=False)
        sk, sk_addr, ty, ty_addr = a._collect_mlil_skeleton_and_typed()
        assert sk == [] and sk_addr == [] and ty == [] and ty_addr == []

    def test_collect_skeleton_and_typed_basic(self):
        instrs = [
            MockMLILInstruction(operation=1, address=0x1000, operands=[]),
            MockMLILInstruction(operation=2, address=0x1004, operands=[42]),
        ]
        a = self._make_analysis(instructions=instrs, start=0x1000)
        sk, sk_addr, ty, ty_addr = a._collect_mlil_skeleton_and_typed()

        assert sk == [[1], [2]]
        assert ty == [[1], [2, "CONST"]]
        assert sk_addr == [(0, [1]), (4, [2])]
        assert ty_addr == [(0, [1]), (4, [2, "CONST"])]

    def test_collect_negative_offset_clamped_to_zero(self):
        instrs = [
            MockMLILInstruction(operation=1, address=0x900, operands=[]),
        ]
        a = self._make_analysis(instructions=instrs, start=0x1000)
        _, sk_addr, _, ty_addr = a._collect_mlil_skeleton_and_typed()
        assert sk_addr[0][0] == 0
        assert ty_addr[0][0] == 0

    def test_log_error_records_entry(self):
        a = self._make_analysis()
        a.log_error("boom", "fname", 0x1234, ValueError("x"), "loc")
        assert len(a.errors) == 1
        err = a.errors[0]
        assert err["function_name"] == "fname"
        assert err["function_address"] == "4660"  # hex 0x1234
        assert err["error_location"] == "loc"
        assert err["error_message"] == "boom"
        assert err["error_type"] == "ValueError"
        assert "timestamp" in err

    @patch(
        "redb.extractors.decompiler.bninja.analysis.medium_level.MinHasher"
    )
    def test_analyze_returns_expected_keys(self, mock_minhasher):
        mock_minhasher.return_value.calculateMinHash.return_value = [1, 2, 3]

        instrs = [
            MockMLILInstruction(operation=1, address=0x1000, operands=[]),
            MockMLILInstruction(operation=2, address=0x1004, operands=[42]),
            MockMLILInstruction(operation=3, address=0x1008, operands=[]),
        ]
        a = self._make_analysis(instructions=instrs, start=0x1000)
        result, errors = a.analyze()

        expected_keys = {
            "function_address",
            "body_mlil_skeleton_vector",
            "sha256_mlil_skeleton",
            "tlsh_mlil_skeleton",
            "minhash_mlil_skeleton",
            "body_mlil_typed_vector",
            "sha256_mlil_typed",
            "tlsh_mlil_typed",
            "minhash_mlil_typed",
        }
        assert set(result.keys()) == expected_keys
        assert result["function_address"] == 0x1000
        assert result["minhash_mlil_skeleton"] == [1, 2, 3]
        assert result["minhash_mlil_typed"] == [1, 2, 3]
        assert errors == []

    @patch(
        "redb.extractors.decompiler.bninja.analysis.medium_level.MinHasher"
    )
    def test_analyze_empty_mlil(self, mock_minhasher):
        mock_minhasher.return_value.calculateMinHash.return_value = []
        a = self._make_analysis(mlil=False)
        result, errors = a.analyze()
        assert result["body_mlil_skeleton_vector"] == []
        assert result["body_mlil_typed_vector"] == []
        assert errors == []

    @patch(
        "redb.extractors.decompiler.bninja.analysis.medium_level.MinHasher"
    )
    def test_analyze_sha256_differs_skeleton_vs_typed(self, mock_minhasher):
        mock_minhasher.return_value.calculateMinHash.return_value = []

        instrs = [
            MockMLILInstruction(operation=1, address=0x1000, operands=[42]),
            MockMLILInstruction(operation=2, address=0x1004, operands=["foo"]),
            MockMLILInstruction(operation=3, address=0x1008, operands=[True]),
        ]
        a = self._make_analysis(instructions=instrs)
        result, _ = a.analyze()
        # skeleton ignores operand leaves, typed includes them -> different hashes
        assert result["sha256_mlil_skeleton"] != result["sha256_mlil_typed"]


class TestMinHasherMLILKinds:
    def _make_func(self, instrs):
        # MinHasher iterates basic_blocks then over each block
        block = MagicMock()
        block.__iter__ = lambda self_: iter(instrs)
        f = MagicMock()
        f.basic_blocks = [block]
        return f

    def test_mlil_skeleton_uses_medium_normalizer(self):
        from redb.extractors.decompiler.bninja.similarity.minhasher import (
            MinHasher, TokenKind,
        )
        instrs = [
            MockMLILInstruction(operation=i, operands=[]) for i in range(5)
        ]
        func = self._make_func(instrs)
        hasher = MinHasher(seed=42, il_function=func, kind=TokenKind.MLIL)
        result = hasher.calculateMinHash()
        # 5 instructions -> 3 trigrams -> non-empty signature
        assert result != []

    def test_typed_mlil_differs_from_skeleton(self):
        from redb.extractors.decompiler.bninja.similarity.minhasher import (
            MinHasher, TokenKind,
        )
        instrs = [
            MockMLILInstruction(operation=1, operands=[42]),
            MockMLILInstruction(operation=2, operands=["s"]),
            MockMLILInstruction(operation=3, operands=[True]),
            MockMLILInstruction(operation=4, operands=[1.5]),
        ]
        func = self._make_func(instrs)
        skel = MinHasher(seed=42, il_function=func, kind=TokenKind.MLIL).calculateMinHash()
        typed = MinHasher(seed=42, il_function=func, kind=TokenKind.TYPED_MLIL).calculateMinHash()
        # Same seed, same instructions, but typed has extra leaf tokens
        # -> hashes should generally differ
        assert skel != typed

    def test_mlil_too_few_instructions(self):
        from redb.extractors.decompiler.bninja.similarity.minhasher import (
            MinHasher, TokenKind,
        )
        instrs = [MockMLILInstruction(operation=1, operands=[])] * 2
        func = self._make_func(instrs)
        hasher = MinHasher(seed=42, il_function=func, kind=TokenKind.MLIL)
        assert hasher.calculateMinHash() == []

    def test_unsupported_kind_raises(self):
        from redb.extractors.decompiler.bninja.similarity.minhasher import MinHasher
        func = self._make_func([])
        hasher = MinHasher(seed=42, il_function=func, kind="bogus")
        with pytest.raises(ValueError):
            hasher.calculateMinHash()