Venky Shankararaman

68 papers B 7C 30Misc 1Journal 8Unranked 21
YearRankTypeTitle / Venue / Authors
2024 conf
DG.O
Alvina Lee Hui Shan, Venky Shankararaman, Eng Lieh Ouh
2023 conf
AMCIS
Swapna Gottipati, Kyong Jin Shim, Venky Shankararaman
2023 C conf
ICCE
Swapna Gottipati, Kyong Jin Shim, Venky Shankararaman
2023 B conf
IEEE Big Data
Alvina Lee Hui Shan, Venky Shankararaman, Eng Lieh Ouh
2023 conf
HICSS
Alvina Lee Hui Shan, Venky Shankararaman, Ouh Eng Lieh
2023 conf
AMCIS
Swapna Gottipati, Venky Shankararaman, Komirisetti Chalapathi Rao, Vennila Vetrivillalan
2023 B conf
IEEE Big Data
Alvina Lee Hui Shan, Venky Shankararaman, Eng Lieh Ouh
2022 conf
TALE
Ta Nguyen Binh Duong, Lwin Khin Shar, Venky Shankararaman
2022 C conf
EDUCON
Kyong Jin Shim, Swapna Gottipati, Venky Shankararaman
2022 B conf
IEEE Big Data
Alvina Lee Hui Shan, Venky Shankararaman, Eng Lieh Ouh
2022 conf
DG.O
Alvina Lee Hui Shan, Venky Shankararaman, Eng Lieh Ouh
2021 J jnl
IEEE Softw.
Alan Megargel, Venky Shankararaman
2021 C conf
FIE
Venky Shankararaman, Paul M. Leidig, Greg Anderson, Mark Thouin
2021 conf
AMCIS
Swapna Gottipati, Venky Shankararaman, Kyong Jin Shim, Chan Yuen Yip
2021 C conf
FIE
Devyn Wei Hung Tan, Swapna Gottipati, Kyong Jin Shim, Venky Shankararaman
2021 B conf
EDOC
Alan Megargel, Christopher M. Poskitt, Venky Shankararaman
2021 C conf
FIE
Ong De Lin, Swapna Gottipati, Siaw Ling Lo, Venky Shankararaman
2021 conf
PACIS
Paul M. Leidig, Hannu Salmela, Greg Anderson, Jeffry S. Babb, Lesley A. Gardner, Jay F. Nunamaker Jr., Brenda Scholtz, Venky Shankararaman, Raja Sooriamurthi, Mark F. Thouin, Carina de Villiers
2021 J jnl
Commun. Assoc. Inf. Syst.
Swapna Gottipati, Venky Shankararaman
2021 conf
AMCIS
Siaw Ling Lo, Swapna Gottipati, Venky Shankararaman
2020 conf
AMCIS
Joelle Elmaleh, Venky Shankararaman
2020 C conf
FIE
Swapna Gottipati, Venky Shankararaman, Mallika Nitin Gokarn
2020 C conf
FIE
Swapna Gottipati, Venky Shankararaman, Mark N. G. Wei Jie
2019 C conf
ICCE
Mallika Nitin Gokarn, Swapna Gottipati, Venky Shankararaman
2019 C conf
FIE
Mallika Nitin Gokarn, Swapna Gottipati, Venky Shankararaman
2019 C conf
FIE
Swapna Gottipati, Venky Shankararaman, Renjini Ramesh
2018 C conf
ICCE
Venky Shankararaman, Swapna Gottipati, Seshan Ramaswami, Chirag Chhablani
2018 J jnl
Educ. Inf. Technol.
Swapna Gottipati, Venky Shankararaman
2018 C conf
ICCE
Swapna Gottipati, Venky Shankararaman, Jeff Rongsheng Lin
2018 C conf
FIE
Venky Shankararaman, Swapna Gottipati, Alan Megargel
2018 C conf
FIE
Siddhant Pyasi, Swapna Gottipati, Venky Shankararaman
2018 J jnl
Res. Pract. Technol. Enhanc. Learn.
Swapna Gottipati, Venky Shankararaman, Jeff Rongsheng Lin
2018 C conf
FIE
Swapna Gottipati, Venky Shankararaman
2017 C conf
FIE
Swapna Gottipati, Venky Shankararaman, Sandy Gan
2017 C conf
ICCE
Swapna Gottipati, Venky Shankararaman
2017 C conf
FIE
Venky Shankararaman, Swapna Gottipati
2017 C conf
ICCE
Venky Shankararaman, Swapna Gottipati, Jeff Rongsheng Lin, Sandy Gan
2017 C conf
EDUCON
Joelle Elmaleh, Venky Shankararaman
2017 conf
COMPSAC (1)
Swapna Gottipati, Venky Shankararaman, Melvrick Goh
2016 J jnl
Educ. Inf. Technol.
Venky Shankararaman, Joelle Ducrot
2016 C conf
EDUCON
Venky Shankararaman, Swapna Gottipati
2016 C conf
EDUCON
Swapna Gottipati, Venky Shankararaman
2016 C conf
ICCE
Min Yan Beh, Swapna Gottipati, David Lo, Venky Shankararaman
2015 conf
CBI (2)
Venky Shankararaman, Swapna Gottipati
2015 C conf
FIE
Gokarn Ila Nitin, Swapna Gottipati, Venky Shankararaman
2015 C conf
ICCE
Melvrick Goh, Swapna Gottipati, Venky Shankararaman
2015 ed.
QuASoQ/WAWSE/CMSE@APSEC
Horst Lichter, Toni Anwar, Thanwadee Sunetnanta, Matthias Vianden, Alpana Dubey, L. Elisa Celis, Emanuel S. Grant, Venky Shankararaman
2015 C conf
FIE
Joelle Ducrot, Venky Shankararaman
2015 conf
QuASoQ/WAWSE/CMCE@APSEC
Venky Shankararaman
2015 conf
ITHET
Law Sheng Xun, Swapna Gottipati, Venky Shankararaman
2014 C conf
ICCE
Swapna Gottipati, Venky Shankararaman
2014 C conf
FIE
Ilse Baumgartner, Venky Shankararaman
2014 conf
CBI (2)
Venky Shankararaman, Lum Eng Kit
2014 conf
CSEE&T
Venky Shankararaman, Joelle Ducrot
2014 C conf
EDUCON
Ilse Baumgartner, Venky Shankararaman
2014 conf
CSEE&T
Emanuel S. Grant, Venky Shankararaman
2013 C conf
EDUCON
Ilse Baumgartner, Venky Shankararaman
2013 conf
AMCIS
Venky Shankararaman, Lum Eng Kit
2012 conf
AMCIS
Venky Shankararaman, Lum Eng Kit, Simon Dale
2011 conf
IVM/FTMDD/RTSOABIS/MSVVEIS
Venky Shankararaman, Lum Eng Kit
2011 B conf
CEC
Venky Shankararaman, Pervez Kazmi
2004 J jnl
IT Prof.
Wing Lam, Venky Shankararaman
2000 Misc conf
CATA
Venky Shankararaman, Dimitrios G. Goulis, Vivian Ambrosiadou, B. Robinson, G. Shamtan
1999 conf
MIE
Vivian Ambrosiadou, Dimitris Goulis, Venky Shankararaman, George Shamtani
1999 J jnl
Knowl. Eng. Rev.
Björn Helfesrieder, Venky Shankararaman
1998 B conf
SMC
Björn Helfesrieder, Venky Shankararaman
1998 B conf
REFSQ
Wing Lam, Venky Shankararaman, Sara Jones
1997 J jnl
Comput. Educ.
Biffah Hanciles, Venky Shankararaman, Jose Munoz
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()