Valeria Efimova

25 papers C 2Journal 6Unranked 17
YearRankTypeTitle / Venue / Authors
2026 conf
VISAPP (2)
Ruslan Zaripov, Anastasiya Shpileva, Maksim Koltakov, Georgii Petrov, Viacheslav Shalamov, Valeria Efimova
2026 conf
VISAPP (1)
Stepan Kasai, Sviatoslav Stumpf, Alexey Zabashta, Valeria Efimova
2026 conf
VISAPP (3)
Egor Bazhenov, Stepan Kasai, Viacheslav Shalamov, Valeria Efimova
2026 conf
VISAPP (1)
Andrey Pimenov, Vera Terenteva, Sergey Muravyov, Valeria Efimova
2026 J jnl
CoRR
Egor Bazhenov, Stepan Kasai, Viacheslav Shalamov, Valeria Efimova
2025 conf
SPECOM (1)
Anton Yakovenko, Evgeny Bessonnitsyn, Valeria Efimova, Mark Zaslavskiy
2025 conf
VISIGRAPP (3): VISAPP
Ghfran Jabour, Sergey Muravyov, Valeria Efimova
2025 J jnl
CoRR
Boris Malashenko, Ivan Jarsky, Valeria Efimova
2025 conf
VISIGRAPP (3): VISAPP
Gleb S. Brykin, Valeria Efimova
2025 conf
VISIGRAPP (2): VISAPP
Ivan Jarsky, Maxim Kuzin, Valeria Efimova, Viacheslav Shalamov, Andrey Filchenkov
2025 conf
VISIGRAPP (3): VISAPP
Egor Prokopov, Daria Usacheva, Mariia Rumiantceva, Valeria Efimova
2024 conf
VISIGRAPP (2): VISAPP
Ivan Jarsky, Valeria Efimova, Ilya Bizyaev, Andrey Filchenkov
2024 conf
PPSN (4)
Egor Bazhenov, Ivan Jarsky, Valeria Efimova, Sergey Muravyov
2024 conf
GECCO Companion
Egor Bazhenov, Ivan Jarsky, Valeria Efimova, Sergey Muravyov
2024 conf
VISIGRAPP (3): VISAPP
Evgeny Bessonnitsyn, Artyom Chebykin, Grigorii Stafeev, Valeria Efimova
2024 conf
VISIGRAPP (2): VISAPP
Leon Useinov, Valeria Efimova, Sergey Muravyov
2024 conf
VISIGRAPP (3): VISAPP
Ivan Jarsky, Valeria Efimova, Artyom Chebykin, Viacheslav Shalamov, Andrey Filchenkov
2023 J jnl
CoRR
Maria Dziuba, Ivan Jarsky, Valeria Efimova, Andrey Filchenkov
2023 J jnl
CoRR
Valeria Efimova, Artyom Chebykin, Ivan Jarsky, Evgenii Prosvirnin, Andrey Filchenkov
2022 J jnl
CoRR
Valeria Efimova, Ivan Jarsky, Ilya Bizyaev, Andrey Filchenkov
2022 conf
AIPR
Valeria Efimova, Viacheslav Shalamov, Andrey Filchenkov
2021 C conf
ICMV
Valeria Efimova, Andrey Filchenkov
2019 C conf
ICMV
Valeria Efimova, Viacheslav Shalamov, Andrey Filchenkov
2016 conf
IDP
Valeria Efimova, Andrey Filchenkov, Anatoly Shalyto
2016 J jnl
CoRR
Valeria Efimova, Andrey Filchenkov, Anatoly Shalyto
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