Chandramouli N. Amarnath

37 papers A 6B 7C 6Misc 1Journal 10Unranked 6
YearRankTypeTitle / Venue / Authors
2026 J jnl
IEEE Access
Mohamed Mejri, Chandramouli N. Amarnath, Abhijit Chatterjee
2025 C conf
IOLTS
Anurup Saha, Kwondo Ma, Chandramouli N. Amarnath, Moinuddin Qureshi, Abhijit Chatterjee
2025 B conf
ETS
Anurup Saha, Chandramouli N. Amarnath, Kwondo Ma, Abhijit Chatterjee
2025 A conf
DATE
Anurup Saha, Chandramouli N. Amarnath, Kwondo Ma, Abhijit Chatterjee
2025 J jnl
IEEE Trans. Comput. Aided Des. Integr. Circuits Syst.
Chandramouli N. Amarnath, Mohamed Mejri, Jackson Isenberg, Abhijit Chatterjee
2025 B conf
ETS
Maksim Jenihhin, Jaan Raik, Artur Jutman, Natalia Cherezova, Raimund Ubar, Liviu Miclea, Szilárd Enyedi, I. Stefan, Ovidiu Stan, Cosmina Corches, Z. Peng, Petru Eles, Rolf Drechsler, S. Eggersglüß, Görschwin Fey, Andreas Glowatz, Daniel Tille, Georges G. E. Gielen, Anthony Coyette, Wim Dobbelaere, Ronny Vanhooren, P.-Y. Chuang, Erik Jan Marinissen, Giorgio Di Natale, M. Barragan, Paolo Maistri, S. Mir, Vatajelu I. Vatajelu, Paolo Bernardi, S. Di Carlo, Paolo Prinetto, Matteo Sonza Reorda, Massimo Violante, Haralampos-G. Stratigopoulos, M. K. Michael, Stelios Neophytou, Stavros Hadjitheophanous, Kyriakos Christou, M. Skitsas, Alberto Bosio, Bastien Deveautour, P. Girard, Marcello Traiola, Arnaud Virazel, F. Fernandes Dos Santos, Angeliki Kritikakou, Gioele Casagranda, Marzio Vallero, Flavio Vella, Paolo Rech, Letícia Maria Bolzani Poehls, Milos Krstic, Marko S. Andjelkovic, F. Vargas, Grigor Tshagharyan, Gurgen Harutyunyan, Valery A. Vardanian, Samvel K. Shoukourian, Yervant Zorian, Jennifer Dworak, Kundan Nepal, Theodore W. Manikas, Mottaqiallah Taouil, Moritz Fieback, Anteneh Gebregiorgis, Rajendra Bishnoi, Said Hamdioui, Abhijit Chatterjee, A. Saha, Suhasini Komarraju, K. Ma, Chandramouli N. Amarnath, Mehdi Baradaran Tahoori, Mahta Mayahinia, Maryam Rajabalipanah, Katayoon Basharkhah, N. Nosrati, Zahra Jahanpeima, Zain Navabi, Hans-Joachim Wunderlich, Sybille Hellebrand
2025 J jnl
IEEE Trans. Comput. Aided Des. Integr. Circuits Syst.
Suhasini Komarraju, Akhil Tammana, Chandramouli N. Amarnath, Abhijit Chatterjee
2025
Chandramouli N. Amarnath
2025 J jnl
IEEE Trans. Emerg. Top. Comput.
Kwondo Ma, Anurup Saha, Chandramouli N. Amarnath, Abhijit Chatterjee
2025 J jnl
CoRR
Tyler C. Landle, Jordan Rapp, Dean Blank, Chandramouli N. Amarnath, Abhijit Chatterjee, Alexandros Daglis, Umakishore Ramachandran
2024 J jnl
CoRR
Mohamed Mejri, Chandramouli N. Amarnath, Abhijit Chatterjee
2024 conf
MWSCAS
Mohamed Mejri, Chandramouli N. Amarnath, Abhijit Chatterjee
2024 B conf
ETS
Suhasini Komarraju, Mohamed Mejri, Akhil Tammana, Gowsika Dharmaraj, Chandramouli N. Amarnath, Abhijit Chatterjee
2024 conf
LATS
Mohamed Mejri, Chandramouli N. Amarnath, Abhijit Chatterjee
2024 C conf
IOLTS
Anurup Saha, Kwondo Ma, Chandramouli N. Amarnath, Abhijit Chatterjee
2024 J jnl
IEEE Trans. Comput. Aided Des. Integr. Circuits Syst.
Chandramouli N. Amarnath, Mohamed Mejri, Kwondo Ma, Abhijit Chatterjee
2024 Misc conf
VTS
Mohamed Mejri, Chandramouli N. Amarnath, Abhijit Chatterjee
2024 J jnl
CoRR
Mohamed Mejri, Chandramouli N. Amarnath, Abhijit Chatterjee
2024 A conf
DATE
Kwondo Ma, Anurup Saha, Chandramouli N. Amarnath, Abhijit Chatterjee
2024 B conf
ETS
Anurup Saha, Kwondo Ma, Chandramouli N. Amarnath, Abhijit Chatterjee
2024 J jnl
CoRR
Mohamed Mejri, Chandramouli N. Amarnath, Abhijit Chatterjee
2024 B conf
ASPDAC
Anurup Saha, Chandramouli N. Amarnath, Kwondo Ma, Abhijit Chatterjee
2024 conf
MWSCAS
Kwondo Ma, Anurup Saha, Suhasini Komarraju, Chandramouli N. Amarnath, Abhijit Chatterjee
2023 C conf
IOLTS
Chandramouli N. Amarnath, Abhijit Chatterjee
2023 B conf
ETS
Anurup Saha, Chandramouli N. Amarnath, Abhijit Chatterjee
2023 conf
LATS
Chandramouli N. Amarnath, Abhijit Chatterjee
2023 B conf
ETS
Kwondo Ma, Chandramouli N. Amarnath, Abhijit Chatterjee
2023 A conf
ITC
Suhasini Komarraju, Akhil Tammana, Chandramouli N. Amarnath, Abhijit Chatterjee
2023 conf
ISQED
Kwondo Ma, Chandramouli N. Amarnath, Abhijit Chatterjee, Jacob A. Abraham
2022 A conf
ITC
Kwondo Ma, Anurup Saha, Chandramouli N. Amarnath, Abhijit Chatterjee
2022 conf
MWSCAS
Kwondo Ma, Mohamed Mejri, Chandramouli N. Amarnath, Abhijit Chatterjee
2022 C conf
IOLTS
Chandramouli N. Amarnath, Mohamed Mejri, Kwondo Ma, Abhijit Chatterjee
2021 C conf
IOLTS
Chandramouli N. Amarnath, Md Imran Momtaz, Abhijit Chatterjee
2021 A conf
ITC
Chandramouli N. Amarnath, Md Imran Momtaz, Abhijit Chatterjee
2021 J jnl
CoRR
Chandramouli N. Amarnath, Aishwarya H. Balwani, Kwondo Ma, Abhijit Chatterjee
2020 A conf
ITC
Md Imran Momtaz, Chandramouli N. Amarnath, Abhijit Chatterjee
2020 C conf
IOLTS
Chandramouli N. Amarnath, Md Imran Momtaz, Abhijit Chatterjee
redb/extractors/decompiler/bninja/analysis/cfg.py
← Index redb/extractors/decompiler/bninja/analysis/cfg.py python
from binaryninja.enums import LowLevelILOperation as LLIL_OP

# Support both package and standalone imports
try:
    from . import cfg_features
except ImportError:
    from redb.extractors.decompiler.bninja.analysis import cfg_features


# ---------------------------------------------------------------------------
# Task 2.2: Build LLIL operation maps at import time using real enum values
# ---------------------------------------------------------------------------

# Prime product map: LLIL operation integer value -> small prime
cfg_features.LLIL_OP_PRIMES = {
    # SET_REG, SET_REG_SPLIT
    LLIL_OP.LLIL_SET_REG.value: 2,
    LLIL_OP.LLIL_SET_REG_SPLIT.value: 2,
    # SET_FLAG
    LLIL_OP.LLIL_SET_FLAG.value: 3,
    # LOAD
    LLIL_OP.LLIL_LOAD.value: 5,
    # STORE
    LLIL_OP.LLIL_STORE.value: 7,
    # PUSH, POP
    LLIL_OP.LLIL_PUSH.value: 11,
    LLIL_OP.LLIL_POP.value: 13,
    # CALL, TAILCALL, SYSCALL
    LLIL_OP.LLIL_CALL.value: 17,
    LLIL_OP.LLIL_TAILCALL.value: 17,
    LLIL_OP.LLIL_SYSCALL.value: 19,
    # RET, NORET
    LLIL_OP.LLIL_RET.value: 23,
    LLIL_OP.LLIL_NORET.value: 23,
    # IF, GOTO
    LLIL_OP.LLIL_IF.value: 29,
    LLIL_OP.LLIL_GOTO.value: 31,
    # ADD, SUB
    LLIL_OP.LLIL_ADD.value: 37,
    LLIL_OP.LLIL_SUB.value: 41,
    # AND, OR, XOR
    LLIL_OP.LLIL_AND.value: 43,
    LLIL_OP.LLIL_OR.value: 47,
    LLIL_OP.LLIL_XOR.value: 53,
    # LSL, LSR, ASR, ROL, ROR
    LLIL_OP.LLIL_LSL.value: 59,
    LLIL_OP.LLIL_LSR.value: 61,
    LLIL_OP.LLIL_ASR.value: 67,
    LLIL_OP.LLIL_ROL.value: 71,
    LLIL_OP.LLIL_ROR.value: 73,
    # MUL, DIVU, DIVS, MODU, MODS
    LLIL_OP.LLIL_MUL.value: 79,
    LLIL_OP.LLIL_DIVU.value: 83,
    LLIL_OP.LLIL_DIVS.value: 83,
    LLIL_OP.LLIL_MODU.value: 89,
    LLIL_OP.LLIL_MODS.value: 89,
    # NEG, NOT
    LLIL_OP.LLIL_NEG.value: 97,
    LLIL_OP.LLIL_NOT.value: 101,
    # CMP_E, CMP_NE, CMP_SLT, CMP_ULT, CMP_SLE, CMP_ULE
    # CMP_SGT, CMP_UGT, CMP_SGE, CMP_UGE
    LLIL_OP.LLIL_CMP_E.value: 103,
    LLIL_OP.LLIL_CMP_NE.value: 103,
    LLIL_OP.LLIL_CMP_SLT.value: 107,
    LLIL_OP.LLIL_CMP_ULT.value: 107,
    LLIL_OP.LLIL_CMP_SLE.value: 109,
    LLIL_OP.LLIL_CMP_ULE.value: 109,
    LLIL_OP.LLIL_CMP_SGT.value: 113,
    LLIL_OP.LLIL_CMP_UGT.value: 113,
    LLIL_OP.LLIL_CMP_SGE.value: 127,
    LLIL_OP.LLIL_CMP_UGE.value: 127,
    # NOP
    LLIL_OP.LLIL_NOP.value: 1,
    # SX, ZX, LOW_PART, BOOL_TO_INT
    LLIL_OP.LLIL_SX.value: 131,
    LLIL_OP.LLIL_ZX.value: 137,
    LLIL_OP.LLIL_LOW_PART.value: 139,
    LLIL_OP.LLIL_BOOL_TO_INT.value: 149,
    # JUMP, JUMP_TO
    LLIL_OP.LLIL_JUMP.value: 151,
    LLIL_OP.LLIL_JUMP_TO.value: 151,
}

# Category map: LLIL operation integer value -> category index
_ARITHMETIC = {
    LLIL_OP.LLIL_ADD, LLIL_OP.LLIL_ADC, LLIL_OP.LLIL_SUB, LLIL_OP.LLIL_SBB,
    LLIL_OP.LLIL_MUL, LLIL_OP.LLIL_MULU_DP, LLIL_OP.LLIL_MULS_DP,
    LLIL_OP.LLIL_DIVU, LLIL_OP.LLIL_DIVU_DP, LLIL_OP.LLIL_DIVS,
    LLIL_OP.LLIL_DIVS_DP, LLIL_OP.LLIL_MODU, LLIL_OP.LLIL_MODS,
    LLIL_OP.LLIL_NEG,
}
_LOGIC = {
    LLIL_OP.LLIL_AND, LLIL_OP.LLIL_OR, LLIL_OP.LLIL_XOR, LLIL_OP.LLIL_NOT,
    LLIL_OP.LLIL_LSL, LLIL_OP.LLIL_LSR, LLIL_OP.LLIL_ASR,
    LLIL_OP.LLIL_ROL, LLIL_OP.LLIL_RLC, LLIL_OP.LLIL_ROR, LLIL_OP.LLIL_RRC,
}
_TRANSFER = {
    LLIL_OP.LLIL_SET_REG, LLIL_OP.LLIL_SET_REG_SPLIT, LLIL_OP.LLIL_SET_FLAG,
    LLIL_OP.LLIL_GOTO, LLIL_OP.LLIL_IF, LLIL_OP.LLIL_JUMP, LLIL_OP.LLIL_JUMP_TO,
    LLIL_OP.LLIL_RET, LLIL_OP.LLIL_NORET, LLIL_OP.LLIL_PUSH, LLIL_OP.LLIL_POP,
}
_CALL = {
    LLIL_OP.LLIL_CALL, LLIL_OP.LLIL_TAILCALL, LLIL_OP.LLIL_SYSCALL,
}
_COMPARISON = {
    LLIL_OP.LLIL_CMP_E, LLIL_OP.LLIL_CMP_NE,
    LLIL_OP.LLIL_CMP_SLT, LLIL_OP.LLIL_CMP_ULT,
    LLIL_OP.LLIL_CMP_SLE, LLIL_OP.LLIL_CMP_ULE,
    LLIL_OP.LLIL_CMP_SGE, LLIL_OP.LLIL_CMP_UGE,
    LLIL_OP.LLIL_CMP_SGT, LLIL_OP.LLIL_CMP_UGT,
    LLIL_OP.LLIL_TEST_BIT, LLIL_OP.LLIL_FLAG_COND,
}
_MEMORY = {
    LLIL_OP.LLIL_LOAD, LLIL_OP.LLIL_STORE,
}

cfg_features.LLIL_OP_CATEGORIES = {}
for _op in _ARITHMETIC:
    cfg_features.LLIL_OP_CATEGORIES[_op.value] = cfg_features.CAT_ARITHMETIC
for _op in _LOGIC:
    cfg_features.LLIL_OP_CATEGORIES[_op.value] = cfg_features.CAT_LOGIC
for _op in _TRANSFER:
    cfg_features.LLIL_OP_CATEGORIES[_op.value] = cfg_features.CAT_TRANSFER
for _op in _CALL:
    cfg_features.LLIL_OP_CATEGORIES[_op.value] = cfg_features.CAT_CALL
for _op in _COMPARISON:
    cfg_features.LLIL_OP_CATEGORIES[_op.value] = cfg_features.CAT_COMPARISON
for _op in _MEMORY:
    cfg_features.LLIL_OP_CATEGORIES[_op.value] = cfg_features.CAT_MEMORY

# Set of CALL operation values for counting
_CALL_OPS = {op.value for op in _CALL}


# ---------------------------------------------------------------------------
# Task 2.1 + 2.3: Rewritten CFGAnalysis
# ---------------------------------------------------------------------------

class CFGAnalysis:
    def __init__(self, function, llil_function=None):
        self.function = function
        self.llil_function = llil_function

    def extract_function_cfg(self):
        """Extract function-level CFG features as a flat dictionary."""

        if self.function is None:
            return None

        blocks = list(self.function.basic_blocks)
        if not blocks:
            return None

        n = len(blocks)

        # 1. Build index-based adjacency from Binary Ninja blocks
        addr_to_idx = {b.start: i for i, b in enumerate(blocks)}
        successors = [[] for _ in range(n)]
        predecessors = [[] for _ in range(n)]
        for i, block in enumerate(blocks):
            for edge in block.outgoing_edges:
                if edge.target is None:
                    continue
                target_idx = addr_to_idx.get(edge.target.start)
                if target_idx is not None:
                    successors[i].append(target_idx)
                    predecessors[target_idx].append(i)

        # 2. BFS order (reusable across multiple features)
        bfs = cfg_features.bfs_order(successors, n)

        # 3. Collect per-block LLIL operations (for prime product + ACFG features)
        block_llil_ops = self._collect_block_llil_ops(blocks, addr_to_idx, n)
        all_llil_ops = [op for block_ops in block_llil_ops for op in block_ops]

        # 4. Structural counts
        edge_count = sum(len(s) for s in successors)
        total_llil = sum(len(ops) for ops in block_llil_ops)
        call_count = sum(
            1 for ops in block_llil_ops for op in ops
            if op in _CALL_OPS
        )

        # 5. Compute all features
        bb_features = cfg_features.build_block_features(block_llil_ops, successors, n)

        return {
            "cfg_topology_hash": cfg_features.compute_topology_hash(successors, bfs, n),
            "block_count": n,
            "edge_count": edge_count,
            "llil_total_operations": total_llil,
            "call_count": call_count,
            "cyclomatic_complexity": edge_count - n + 2,
            "loop_count": cfg_features.count_back_edges(successors, n),
            "max_depth": cfg_features.bfs_max_depth(successors, n),
            "max_fan_out": max((len(s) for s in successors), default=0),
            "md_index_topdown": cfg_features.compute_md_index_topdown(successors, predecessors, bfs),
            "md_index_bottomup": cfg_features.compute_md_index_bottomup(successors, predecessors, n),
            "prime_product_llil": cfg_features.compute_prime_product(all_llil_ops),
            "cfg_feature_tlsh": cfg_features.compute_cfg_feature_tlsh(bb_features, bfs),
            "wl_minhash": cfg_features.compute_wl_minhash(successors, predecessors, bb_features, n),
            "bb_features": bb_features,
            "cfg_adjacency": cfg_features.pack_adjacency(successors),
        }

    def _collect_block_llil_ops(self, blocks, addr_to_idx, n):
        """
        Collect LLIL operation integers per native basic block.
        Walks the full expression tree of each instruction so that
        nested operations (e.g. ADD inside SET_REG) are captured.
        Returns list of n lists, one per block.
        """
        block_ops = [[] for _ in range(n)]

        if self.llil_function is None:
            return block_ops

        try:
            for llil_block in self.llil_function.basic_blocks:
                # Map LLIL block to native block via source_block
                if llil_block.source_block is not None:
                    native_idx = addr_to_idx.get(llil_block.source_block.start)
                    if native_idx is not None:
                        for instr in llil_block:
                            self._walk_llil_ops(instr, block_ops[native_idx])
        except Exception:
            pass  # Return empty ops — LLIL-dependent fields will be 0/null

        return block_ops

    @staticmethod
    def _walk_llil_ops(expr, ops_list):
        """Collect operation values from an LLIL expression tree iteratively."""
        stack = [expr]
        while stack:
            node = stack.pop()
            if hasattr(node, 'operation'):
                ops_list.append(node.operation.value)
            if hasattr(node, 'operands'):
                for operand in node.operands:
                    if hasattr(operand, 'operation'):
                        stack.append(operand)