Xavier Varona

16 papers B 2Misc 2Journal 2Unranked 10
YearRankTypeTitle / Venue / Authors
2007 conf
IbPRIA (2)
Eva Cerezo, Isabelle Hupont, Cristina Manresa-Yee, Xavier Varona, Sandra Baldassarri, Francisco José Perales López, Francisco J. Serón
2006 conf
ICPR (1)
Ignasi Rius, Xavier Varona, Jordi Gonzàlez, Juan José Villanueva
2006 J jnl
Virtual Real.
Ronan Boulic, Xavier Varona, Luis Unzueta, Manuel Peinado, Angel Suescun Cruces, Francisco José Perales López
2006 conf
AMDO
Ignasi Rius, Xavier Varona, F. Xavier Roca, Jordi Gonzàlez
2006 conf
AMDO
Cristina Manresa-Yee, Xavier Varona, Francisco José Perales López
2006 conf
AMDO
Jose Maria Buades Rubio, Francisco José Perales López, Manuel González Hidalgo, Xavier Varona
2005 J jnl
Comput. Graph.
Xavier Varona, Jose Maria Buades Rubio, Francisco José Perales López
2004 conf
SIGGRAPH Posters
Francisco José Perales López, Jose Maria Buades Rubio, Ramon Mas, Xavier Varona, Manuel González Hidalgo, Angel Suescun Cruces, Iker Aguinaga, Maxim Foursa, G. Zissis, M. Touman, R. Mendoza
2004 conf
AMDO
Jordi Gonzàlez, Xavier Varona, F. Xavier Roca, Juan José Villanueva
2004 conf
AMDO
Jose Maria Buades Rubio, Francisco José Perales López, Xavier Varona
2003 Misc conf
IbPRIA
Xavier Varona, Jordi Gonzàlez, F. Xavier Roca, Juan José Villanueva
2003 Misc conf
IbPRIA
Jordi Gonzàlez, Xavier Varona, F. Xavier Roca, Juan José Villanueva
2002 conf
AMDO
Jordi Gonzàlez, Xavier Varona, F. Xavier Roca, Juan José Villanueva
2000 conf
AMDO
Xavier Varona, Jordi Gonzàlez, F. Xavier Roca, Juan José Villanueva
2000 B conf
ICPR
Albert Pujol, Felipe Lumbreras, Xavier Varona, Juan José Villanueva
2000 B conf
ICPR
Xavier Varona, Jordi Gonzàlez, F. Xavier Roca, Juan José Villanueva
tests/unit/test_decompile_scores.py
← Index tests/unit/test_decompile_scores.py python
"""Unit tests for bninja/analysis/scores.py — ObfuscationScores."""
import sys
import pytest
from unittest.mock import MagicMock

# Install binaryninja stubs before importing
from tests.unit.conftest_binja_stubs import (
    install_binja_stubs,
    HighLevelILOperation,
)
bn_mock = install_binja_stubs()

from redb.extractors.decompiler.bninja.analysis.scores import (
    ObfuscationScores,
    get_dominated_by,
    uses_mba,
)
import binaryninja.highlevelil as hlil_mod


# ============================================================================
# Helper: Mock HLIL instruction
# ============================================================================

class MockHLILInstruction(hlil_mod.HighLevelILInstruction):
    """Mock HLIL instruction with operation and operands."""
    def __init__(self, operation, operands=None):
        self.operation = operation
        self.operands = operands or []


class MockHLILBasicBlock:
    """Mock HLIL basic block for flattened score testing."""
    def __init__(self, incoming_edges=None, dominator_tree_children=None):
        self.incoming_edges = incoming_edges or []
        self.dominator_tree_children = dominator_tree_children or []


# ============================================================================
# 5a. ObfuscationScores
# ============================================================================


class TestFlattenedScore:
    def test_flattened_score_no_back_edges(self):
        """Linear CFG with no back edges -> score 0.0."""
        block = MockHLILBasicBlock(incoming_edges=[], dominator_tree_children=[])
        func = MagicMock()
        func.basic_blocks = [block]
        scores = ObfuscationScores(func)
        assert scores.flattened_score() == 0.0

    def test_flattened_score_with_loop(self):
        """CFG with a back edge -> score > 0.0."""
        block = MockHLILBasicBlock(dominator_tree_children=[])
        # Create a back edge: an incoming edge whose source is in the dominated set
        edge = MagicMock()
        edge.source = block  # source IS the dominator -> back edge
        block.incoming_edges = [edge]
        func = MagicMock()
        func.basic_blocks = [block]
        scores = ObfuscationScores(func)
        assert scores.flattened_score() > 0.0

    def test_flattened_score_fully_flat(self):
        """Flattened CFG: one block dominates all -> ratio close to 1.0."""
        children = [MockHLILBasicBlock() for _ in range(4)]
        root = MockHLILBasicBlock(dominator_tree_children=children)
        # Back edge from root incoming
        edge = MagicMock()
        edge.source = root
        root.incoming_edges = [edge]
        all_blocks = [root] + children
        func = MagicMock()
        func.basic_blocks = all_blocks
        scores = ObfuscationScores(func)
        assert scores.flattened_score() == pytest.approx(1.0)


class TestMBAScore:
    def test_mba_score_no_mixed_ops(self):
        """Instructions with only arithmetic -> score 0.0."""
        instr = MockHLILInstruction(HighLevelILOperation.HLIL_ADD, operands=[])
        func = MagicMock()
        func.instructions = [instr]
        scores = ObfuscationScores(func)
        assert scores.MBA_score() == 0.0

    def test_mba_score_mixed_ops(self):
        """Instructions with arithmetic + logic -> score > 0.0."""
        inner_logic = MockHLILInstruction(HighLevelILOperation.HLIL_XOR, operands=[])
        outer_arith = MockHLILInstruction(
            HighLevelILOperation.HLIL_ADD, operands=[inner_logic]
        )
        func = MagicMock()
        func.instructions = [outer_arith]
        scores = ObfuscationScores(func)
        assert scores.MBA_score() > 0.0

    def test_mba_score_all_mixed(self):
        """Every instruction has both -> score 1.0."""
        inner_logic = MockHLILInstruction(HighLevelILOperation.HLIL_NOT, operands=[])
        outer_arith = MockHLILInstruction(
            HighLevelILOperation.HLIL_SUB, operands=[inner_logic]
        )
        func = MagicMock()
        func.instructions = [outer_arith]
        scores = ObfuscationScores(func)
        assert scores.MBA_score() == 1.0


class TestGetDominatedBy:
    def test_get_dominated_by(self):
        child1 = MockHLILBasicBlock(dominator_tree_children=[])
        child2 = MockHLILBasicBlock(dominator_tree_children=[])
        root = MockHLILBasicBlock(dominator_tree_children=[child1, child2])
        result = get_dominated_by(root)
        assert root in result
        assert child1 in result
        assert child2 in result
        assert len(result) == 3


class TestUsesMBA:
    def test_uses_mba_arithmetic_only(self):
        instr = MockHLILInstruction(HighLevelILOperation.HLIL_ADD, operands=[])
        assert uses_mba(instr) is False

    def test_uses_mba_logic_only(self):
        instr = MockHLILInstruction(HighLevelILOperation.HLIL_XOR, operands=[])
        assert uses_mba(instr) is False

    def test_uses_mba_mixed(self):
        inner = MockHLILInstruction(HighLevelILOperation.HLIL_AND, operands=[])
        outer = MockHLILInstruction(HighLevelILOperation.HLIL_ADD, operands=[inner])
        assert uses_mba(outer) is True