M. Anton Ertl

39 papers A* 5A 1B 9C 2Journal 7Unranked 14
YearRankTypeTitle / Venue / Authors
2024 C ed.
MPLR
M. Anton Ertl, Christoph M. Kirsch
2024 A conf
ECOOP
M. Anton Ertl, Bernd Paysan
2018 B conf
CC
Patrick Thier, M. Anton Ertl, Andreas Krall
2018 conf
ManLang
M. Anton Ertl
2008 conf
Emerging Uses and Paradigms for Dynamic Binary Translation
Erik R. Altman, Bruce R. Childers, Robert S. Cohn, Jack W. Davidson, Koen De Bosschere, Bjorn De Sutter, M. Anton Ertl, Michael Franz, Yuan Xiang Gu, Matthias Hauswirth, Thomas Heinz, Wei-Chung Hsu, Jens Knoop, Andreas Krall, Naveen Kumar, Jonas Maebe, Robert Muth, Xavier Rival, Erven Rohou, Roni Rosner, Mary Lou Soffa, Jens Tröger, Christopher A. Vick
2008 J jnl
ACM Trans. Archit. Code Optim.
Yunhe Shi, Kevin Casey, M. Anton Ertl, David Gregg
2007 J jnl
ACM Trans. Program. Lang. Syst.
Kevin Casey, M. Anton Ertl, David Gregg
2006 conf
Euro-Par
Bernd Burgstaller, Bernhard Scholz, M. Anton Ertl
2006 A* conf
PLDI
M. Anton Ertl, Kevin Casey, David Gregg
2006 J jnl
Concurr. Comput. Pract. Exp.
David Gregg, M. Anton Ertl
2005 J jnl
Sci. Comput. Program.
M. Anton Ertl
2005 B conf
CC
Kevin Casey, David Gregg, M. Anton Ertl
2005 B conf
VEE
Yunhe Shi, David Gregg, Andrew Beatty, M. Anton Ertl
2004 conf
IVME
M. Anton Ertl, David Gregg
2004 conf
IEEE PACT
M. Anton Ertl, David Gregg
2003 conf
Domain-Specific Program Generation
David Gregg, M. Anton Ertl
2003 A* conf
PLDI
M. Anton Ertl, David Gregg
2003 ed.
IVME
David Gregg, M. Anton Ertl
2003 J jnl
J. Instr. Level Parallelism
M. Anton Ertl, David Gregg
2003 C conf
SCOPES
Kevin Casey, David Gregg, M. Anton Ertl, Andrew Nisbet
2002 B conf
CC
M. Anton Ertl, David Gregg
2002 J jnl
Softw. Pract. Exp.
M. Anton Ertl, David Gregg, Andreas Krall, Bernd Paysan
2001 conf
HPCN Europe
David Gregg, M. Anton Ertl, Andreas Krall
2001 conf
Euro-Par
M. Anton Ertl, David Gregg
2000 conf
USENIX ATC, FREENIX Track
Christian Czezatke, M. Anton Ertl
1999 A* conf
POPL
M. Anton Ertl
1998 B conf
CC
Martin Maierhofer, M. Anton Ertl
1996 B conf
CC
M. Anton Ertl, Andreas Krall
1995 B conf
PACT
Jian Wang, Andreas Krall, M. Anton Ertl
1995 conf
Constraint Processing, Selected Papers
M. Anton Ertl, Andreas Krall
1995 A* conf
PLDI
M. Anton Ertl
1995 J jnl
J. Comput. Sci. Technol.
Jian Wang, Andreas Krall, M. Anton Ertl
1994 B conf
CC
M. Anton Ertl, Andreas Krall
1994 conf
Programming Languages and System Architectures
Wolfgang Ambrosch, M. Anton Ertl, Felix Beer, Andreas Krall
1994 A* conf
MICRO
Jian Wang, Andreas Krall, M. Anton Ertl, Christine Eisenbeis
1994 conf
IFIP PACT
Jian Wang, Andreas Krall, M. Anton Ertl, Christine Eisenbeis
1993 conf
WLP
M. Anton Ertl, Andreas Krall
1992 B conf
CC
M. Anton Ertl, Andreas Krall
1991 conf
PLILP
M. Anton Ertl, Andreas Krall
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)