Oskar Andersson

22 papers C 4Misc 2Journal 6Unranked 10
YearRankTypeTitle / Venue / Authors
2024 J jnl
IEEE Trans. Very Large Scale Integr. Syst.
Zuzana Jelcicová, Evangelia Kasapaki, Oskar Andersson, Jens Sparsø
2023 C conf
ISCAS
Zuzana Jelcicová, Evangelia Kasapaki, Oskar Andersson, Jens Sparsø
2020 Misc conf
ACSSC
Zuzana Jelcicová, Adrian Mardari, Oskar Andersson, Evangelia Kasapaki, Jens Sparsø
2018 J jnl
IET Comput. Digit. Tech.
Shahzad Asif, Oskar Andersson, Joachim Neves Rodrigues, Yinan Kong
2018 J jnl
IEEE Trans. Circuits Syst. I Regul. Pap.
Babak Mohammadi, Oskar Andersson, Joseph Nguyen, Lorenzo Ciampolini, Andreia Cathelin, Joachim Neves Rodrigues
2017 Misc conf
ACSSC
Farhana Sheikh, Ankit Sharma, Oskar Andersson, Mehnaz Rahman, Dongmin Yoon, Alexios Balatsoukas-Stimming, Deepak Dasalukunte, Anthony Chun
2016 conf
ESSCIRC
Babak Mohammadi, Oskar Andersson, Joseph Nguyen, Lorenzo Ciampolini, Andreia Cathelin, Joachim Neves Rodrigues
2016 conf
A-SSCC
Babak Mohammadi, Oskar Andersson, Xiao Luo, Masoud Nouripayam, Joachim Neves Rodrigues
2016 J jnl
CoRR
Nafiseh Seyed Mazloum, Joachim Neves Rodrigues, Oskar Andersson, Anders Nejdel, Ove Edfors
2016 conf
ICECS
Alen Bardizbanyan, Oskar Andersson, Joachim Neves Rodrigues, Per Larsson-Edefors
2016 J jnl
IEEE Trans. Circuits Syst. I Regul. Pap.
Oskar Andersson, Babak Mohammadi, Pascal Meinerzhagen, Andreas Burg, Joachim Neves Rodrigues
2015 J jnl
IEEE Trans. Biomed. Circuits Syst.
Oskar Andersson, Ki H. Chon, Leif Sörnmo, Joachim Neves Rodrigues
2015 C conf
ISCAS
Oskar Andersson, Joachim Neves Rodrigues
2015 conf
SiPS
Farhana Sheikh, Oskar Andersson, Ching-En Lee, Feng Xue, Chia-Hsiang Chen, Anuja Vaidya, Ankit Sharma, Tom Tetzlaff
2014 conf
ESSCIRC
Oskar Andersson, Babak Mohammadi, Pascal Andreas Meinerzhagen, Joachim Neves Rodrigues
2013 C conf
VLSI-SoC
Christoph Thomas Muller, Steffen Malkowsky, Oskar Andersson, Babak Mohammadi, Jens Sparsø, Joachim Neves Rodrigues
2013 conf
ESSCIRC
Oskar Andersson, Babak Mohammadi, Pascal Meinerzhagen, Andreas Burg, Joachim Neves Rodrigues
2012 conf
ESSCIRC
Pascal Andreas Meinerzhagen, Oskar Andersson, Babak Mohammadi, S. M. Yasser Sherazi, Andreas Peter Burg, Joachim Neves Rodrigues
2012 conf
VLSI-SoC (Selected Papers)
Jeremy Constantin, Ahmed Yasir Dogan, Oskar Andersson, Pascal Andreas Meinerzhagen, Joachim Neves Rodrigues, David Atienza, Andreas Burg
2012 C conf
VLSI-SoC
Jeremy Constantin, Ahmed Yasir Dogan, Oskar Andersson, Pascal Andreas Meinerzhagen, Joachim Neves Rodrigues, David Atienza, Andreas Burg
2011 conf
NORCHIP
Oskar Andersson, S. M. Yasser Sherazi, Joachim Neves Rodrigues
2011 conf
ECCTD
Pascal Andreas Meinerzhagen, Oskar Andersson, S. M. Yasser Sherazi, Andreas Peter Burg, Joachim Neves Rodrigues
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