Vincenzo Manca

109 papers A 1B 9Misc 1Journal 52Unranked 40
YearRankTypeTitle / Venue / Authors
2024 J jnl
Inf.
Vincenzo Manca
2024 J jnl
Inf.
Vincenzo Manca
2024 J jnl
Inf.
Vincenzo Manca
2024 J jnl
Algorithms
Vincenzo Manca
2023 book
Vincenzo Manca, Vincenzo Bonnici
2021 J jnl
Theor. Comput. Sci.
Giuditta Franco, Vincenzo Manca, Marco Andreolli, Silvia Lampis
2021 J jnl
Theor. Comput. Sci.
Vincenzo Manca, Giuseppe Scollo
2021 J jnl
CoRR
Vincenzo Bonnici, Giuditta Franco, Vincenzo Manca
2021 J jnl
Theor. Comput. Sci.
Vincenzo Bonnici, Giuditta Franco, Vincenzo Manca
2020 J jnl
CoRR
Vincenzo Bonnici, Giuditta Franco, Vincenzo Manca
2019 J jnl
J. Membr. Comput.
Vincenzo Manca
2019 J jnl
J. Membr. Comput.
Vincenzo Manca
2018 conf
Enjoying Natural Computing
Vincenzo Manca
2018 J jnl
Entropy
Vincenzo Bonnici, Vincenzo Manca
2018 ch.
Computational Matter
Giuditta Franco, Vincenzo Manca
2017 J jnl
Theor. Comput. Sci.
Vincenzo Manca
2016 ch.
Machine Learning for Health Informatics
Vincenzo Manca
2015 conf
BIRS-IMLKE
Vincenzo Manca
2015 J jnl
Nat. Comput.
Alberto Castellini, Vincenzo Manca, Mauro Zucchelli
2015 conf
Int. Conf. on Membrane Computing
Ricardo Henrique Gracini Guiraldelli, Vincenzo Manca
2015 conf
Int. Conf. on Membrane Computing
Vincenzo Manca
2015 J jnl
Bioinform.
Alberto Castellini, Daniele Paltrinieri, Vincenzo Manca
2015 J jnl
Bioinform.
Luca Marchetti, Vincenzo Manca
2015 J jnl
CoRR
Ricardo Henrique Gracini Guiraldelli, Vincenzo Manca
2014 J jnl
Bioinform.
Aliccia Bollig-Fischer, Luca Marchetti, Cristina Mitrea, Jiusheng Wu, Adéle Kruger, Vincenzo Manca, Sorin Draghici
2014 J jnl
Nat. Comput.
Vincenzo Manca, Giovanni Pardini
2014 B conf
IEEE Congress on Evolutionary Computation
Luca Marchetti, Vincenzo Manca, Ivan Zelinka
2014 conf
UCNC
Alberto Castellini, Giuditta Franco, Vincenzo Manca, Riccardo Ortolani, Antonio Vella
2013 J jnl
Int. J. Comput. Math.
Vincenzo Manca, Luca Marchetti
2012 conf
GECCO (Companion)
Alberto Castellini, Vincenzo Manca, Mauro Zucchelli, Mirko Busato
2012 conf
Int. Conf. on Membrane Computing
Roberto Pagliarini, Oana Agrigoroaiei, Gabriel Ciobanu, Vincenzo Manca
2012 conf
Int. Conf. on Membrane Computing
Vincenzo Manca
2012 conf
BIOSIGNALS
Vincenzo Manca, Luca Marchetti
2012 J jnl
Biosyst.
Vincenzo Manca, Luca Marchetti
2012 conf
ICARIS
Alberto Castellini, Vincenzo Manca, Mauro Zucchelli
2011 conf
Int. Conf. on Membrane Computing
Luca Marchetti, Vincenzo Manca
2011 conf
Computation, Cooperation, and Life
Vincenzo Manca
2011 J jnl
Int. J. Nanotechnol. Mol. Comput.
Vincenzo Manca
2011 J jnl
Nat. Comput.
Giuditta Franco, Vincenzo Manca
2011 conf
IWINAC (1)
Rosario Lombardo, Vincenzo Manca
2011 conf
Int. Conf. on Membrane Computing
Vincenzo Manca, Rosario Lombardo
2011 J jnl
Int. J. Found. Comput. Sci.
Vincenzo Manca, Luca Marchetti
2011 J jnl
Int. J. Nat. Comput. Res.
Vincenzo Manca, Luca Marchetti, Roberto Pagliarini
2011 J jnl
ERCIM News
Giuditta Franco, Vincenzo Manca
2010 J jnl
Nat. Comput.
Marian Gheorghe, Vincenzo Manca, Francisco José Romero-Campero
2010 conf
Int. Conf. on Membrane Computing
Vincenzo Manca, Luca Marchetti
2010 J jnl
Nat. Comput.
Alberto Castellini, Giuditta Franco, Vincenzo Manca
2010 J jnl
Scholarpedia
Vincenzo Manca
2010 J jnl
J. Log. Algebraic Methods Program.
Vincenzo Manca, Luca Marchetti
2009 J jnl
Nat. Comput.
Vincenzo Manca, Roberto Pagliarini, Simone Zorzan
2009 J jnl
Int. J. Comput. Commun. Control
Roberto Pagliarini, Giuditta Franco, Vincenzo Manca
2009 conf
Workshop on Membrane Computing
Vincenzo Manca
2009 A conf
GECCO
Alberto Castellini, Vincenzo Manca
2009 conf
Algorithmic Bioprocesses
Vincenzo Manca
2009 conf
Workshop on Membrane Computing
Alberto Castellini, Vincenzo Manca, Yasuhiro Suzuki
2009 conf
IWINAC (1)
Vincenzo Manca, María Dolores Jiménez-López
2009 conf
Workshop on Membrane Computing
Giuditta Franco, Vincenzo Manca, Roberto Pagliarini
2009 B conf
IEEE Congress on Evolutionary Computation
Vincenzo Manca, Luca Marchetti
2008 J jnl
Biosyst.
Vincenzo Manca, Luca Bianco
2008 conf
Workshop on Membrane Computing
Vincenzo Manca
2008 conf
Workshop on Membrane Computing
Alberto Castellini, Vincenzo Manca
2008 J jnl
Biosyst.
Federico Fontana, Vincenzo Manca
2008 J jnl
J. Log. Algebraic Methods Program.
Giuseppe Scollo, Giuditta Franco, Vincenzo Manca
2008 J jnl
Theor. Comput. Sci.
Vincenzo Manca
2008 conf
Workshop on Membrane Computing
Vincenzo Manca, Roberto Pagliarini, Simone Zorzan
2007 B conf
DNA
Vincenzo Manca
2007 J jnl
Theor. Comput. Sci.
Federico Fontana, Vincenzo Manca
2007 ch.
NICSO
Alberto Castellini, Vincenzo Manca, Luca Marchetti
2007 B conf
IEEE Congress on Evolutionary Computation
Luca Bianco, Vincenzo Manca, Luca Marchetti, Michele Petterlini
2007 conf
IWNC
Alberto Castellini, Giuditta Franco, Vincenzo Manca
2006 conf
RelMiCS
Giuseppe Scollo, Giuditta Franco, Vincenzo Manca
2006 J jnl
Theor. Comput. Sci.
Henning Bordihn, Henning Fernau, Markus Holzer, Vincenzo Manca, Carlos Martín-Vide
2006 conf
Workshop on Membrane Computing
Vincenzo Manca
2006 conf
Workshop on Membrane Computing
Giuditta Franco, Pietro Hiram Guzzi, Vincenzo Manca, Tommaso Mazza
2006 ch.
Applications of Membrane Computing
Luca Bianco, Federico Fontana, Giuditta Franco, Vincenzo Manca
2006 J jnl
Int. J. Found. Comput. Sci.
Luca Bianco, Federico Fontana, Vincenzo Manca
2006 J jnl
Theory Comput. Syst.
Paolo Bottoni, Anna Labella, Vincenzo Manca, Victor Mitrana
2006 J jnl
Int. J. Comput. Math.
Luca Bianco, Vincenzo Manca
2005 conf
CSB Workshops
Federico Fontana, Luca Bianco, Vincenzo Manca
2005 J jnl
Soft Comput.
Giuditta Franco, Vincenzo Manca
2005 B conf
DNA
Giuditta Franco, Vincenzo Manca, Cinzia Giagulli, Carlo Laudanna
2005 conf
Workshop on Membrane Computing
Luca Bianco, Vincenzo Manca
2005 J jnl
Fundam. Informaticae
Francesco Bernardini, Marian Gheorghe, Vincenzo Manca
2005 J jnl
Fundam. Informaticae
Vincenzo Manca
2005 conf
Workshop on Membrane Computing
Federico Fontana, Luca Bianco, Vincenzo Manca
2005 conf
ICNC (2)
Luca Bianco, Federico Fontana, Vincenzo Manca
2005 Misc conf
SYNASC
Luca Bianco, Vincenzo Manca, Simone Zorzan
2004 conf
Aspects of Molecular Computing
Vincenzo Manca
2004 B conf
DNA
Giuditta Franco, Cinzia Giagulli, Carlo Laudanna, Vincenzo Manca
2004 conf
Workshop on Membrane Computing
Vincenzo Manca, Luca Bianco, Federico Fontana
2003 conf
Workshop on Membrane Computing
Giuditta Franco, Vincenzo Manca
2002 J jnl
Fundam. Informaticae
Vincenzo Manca
2002 conf
WMC-CdeA
Francesco Bernardini, Vincenzo Manca
2001 B conf
DNA
Vincenzo Manca, Claudio Zandron
2001 J jnl
Theor. Comput. Sci.
Vincenzo Manca
2001 conf
Where Mathematics, Computer Science, Linguistics and Biology Meet
Vincenzo Manca
2001 conf
Words, Semigroups, and Transductions
Vincenzo Manca
2001 J jnl
J. Autom. Lang. Comb.
Vincenzo Manca, Carlos Martín-Vide, Gheorghe Paun
2000 ch.
Finite Versus Infinite
Vincenzo Manca
1999 conf
Grammatical Models of Multi-Agent Systems
Vincenzo Manca, Domenico Marco Martina
1999 conf
Jewels are Forever
Vincenzo Manca, Carlos Martín-Vide, Gheorghe Paun
1998 J jnl
Comput. Sci. J. Moldova
Vincenzo Manca, Gheorghe Paun
1992 J jnl
Theor. Comput. Sci.
Vincenzo Manca, Antonino Salibra
1990 B conf
MFCS
Vincenzo Manca, Antonino Salibra
1990 J jnl
Theor. Comput. Sci.
Vincenzo Manca, Antonino Salibra, Giuseppe Scollo
1989 B conf
MFCS
Vincenzo Manca, Antonino Salibra, Giuseppe Scollo
1986 conf
ADT
Vincenzo Manca
1984 J jnl
Notre Dame J. Formal Log.
Vincenzo Manca, Antonino Salibra
1981 J jnl
Fundam. Informaticae
Vincenzo Manca
redb/extractors/decompiler/bninja/analysis/cfg_features.py
← Index redb/extractors/decompiler/bninja/analysis/cfg_features.py python
import struct
from collections import deque
from typing import Optional

import blake3
import mmh3


# ---------------------------------------------------------------------------
# Task 1.1: Core Graph Utilities
# ---------------------------------------------------------------------------

def bfs_order(successors: list[list[int]], n: int) -> list[int]:
    """
    BFS traversal from node 0 (entry block), returns node indices in visit order.
    Unreachable nodes appended at the end.
    """
    if n == 0:
        return []

    visited = set()
    order = []
    queue = deque([0])
    visited.add(0)

    while queue:
        idx = queue.popleft()
        order.append(idx)
        for target in successors[idx]:
            if target not in visited:
                visited.add(target)
                queue.append(target)

    # Append unreachable blocks (dead code)
    for i in range(n):
        if i not in visited:
            order.append(i)

    return order


def bfs_max_depth(successors: list[list[int]], n: int) -> int:
    """
    Maximum BFS depth from entry block (node 0).
    Replaces the per-block depth column with a single scalar.
    """
    if n == 0:
        return 0

    depth = {0: 0}
    max_d = 0
    queue = deque([0])

    while queue:
        node = queue.popleft()
        for s in successors[node]:
            if s not in depth:
                depth[s] = depth[node] + 1
                if depth[s] > max_d:
                    max_d = depth[s]
                queue.append(s)

    return max_d


# ---------------------------------------------------------------------------
# Task 1.2: Back-Edge Detection (Iterative DFS)
# ---------------------------------------------------------------------------

def count_back_edges(successors: list[list[int]], n: int) -> int:
    """
    Count natural loops via iterative DFS back-edge detection.
    A back edge is an edge to a GRAY (in-stack) node.

    Iterative to avoid stack overflow on functions with 1000+ blocks
    (common in obfuscated malware, VM dispatchers, unrolled loops).
    """
    if n == 0:
        return 0

    WHITE, GRAY, BLACK = 0, 1, 2
    color = [WHITE] * n
    back_edges = 0

    stack = [(0, iter(successors[0]))]
    color[0] = GRAY

    while stack:
        u, children = stack[-1]
        try:
            v = next(children)
            if color[v] == GRAY:
                back_edges += 1
            elif color[v] == WHITE:
                color[v] = GRAY
                stack.append((v, iter(successors[v])))
        except StopIteration:
            color[u] = BLACK
            stack.pop()

    return back_edges


# ---------------------------------------------------------------------------
# Task 1.3: Topology Hash
# ---------------------------------------------------------------------------

def compute_topology_hash(
    successors: list[list[int]],
    bfs: list[int],
    n: int,
) -> bytes:
    """
    BLAKE3 hash of BFS-ordered canonical adjacency.
    Pure graph shape — ignores all block content.
    Two functions with identical control flow structure produce identical hashes.

    Returns 16 bytes (128-bit).
    """
    if n == 0:
        return b'\x00' * 16

    # Remap: original index -> BFS position
    remap = {original: position for position, original in enumerate(bfs)}

    canonical = bytearray()
    for position in range(n):
        original_idx = bfs[position]
        remapped_succs = sorted(
            remap[s] for s in successors[original_idx] if s in remap
        )
        # Pack: node_index (2 bytes) + num_successors (1 byte) + successor indices (2 bytes each)
        canonical.extend(struct.pack('<HB', position, len(remapped_succs)))
        for s in remapped_succs:
            canonical.extend(struct.pack('<H', s))

    return blake3.blake3(bytes(canonical)).digest(length=16)


# ---------------------------------------------------------------------------
# Task 1.4: MD-Index (Top-Down and Bottom-Up)
# ---------------------------------------------------------------------------

def compute_md_index_topdown(
    successors: list[list[int]],
    predecessors: list[list[int]],
    bfs: list[int],
) -> int:
    """
    BinDiff-style top-down MD-index.
    Hash of (in_degree, out_degree) sequence in BFS order from entry.
    Returns UInt64.
    """
    if not bfs:
        return 0

    degree_bytes = bytearray()
    for idx in bfs:
        in_deg = min(len(predecessors[idx]), 255)
        out_deg = min(len(successors[idx]), 255)
        degree_bytes.extend(struct.pack('<BB', in_deg, out_deg))

    h = blake3.blake3(bytes(degree_bytes)).digest(length=8)
    return struct.unpack('<Q', h)[0]


def compute_md_index_bottomup(
    successors: list[list[int]],
    predecessors: list[list[int]],
    n: int,
) -> int:
    """
    Bottom-up MD-index: BFS from exit blocks (no successors),
    traversing edges in reverse.
    Returns UInt64.
    """
    if n == 0:
        return 0

    exits = [i for i in range(n) if len(successors[i]) == 0]
    if not exits:
        exits = [n - 1]  # Fallback: use last block

    visited = set(exits)
    order = []
    queue = deque(exits)

    while queue:
        idx = queue.popleft()
        order.append(idx)
        for pred in predecessors[idx]:
            if pred not in visited:
                visited.add(pred)
                queue.append(pred)

    # Append unreachable blocks
    for i in range(n):
        if i not in visited:
            order.append(i)

    degree_bytes = bytearray()
    for idx in order:
        in_deg = min(len(predecessors[idx]), 255)
        out_deg = min(len(successors[idx]), 255)
        degree_bytes.extend(struct.pack('<BB', in_deg, out_deg))

    h = blake3.blake3(bytes(degree_bytes)).digest(length=8)
    return struct.unpack('<Q', h)[0]


# ---------------------------------------------------------------------------
# Task 1.5: Prime Product
# ---------------------------------------------------------------------------

# Small primes assigned to LLIL opcode categories.
# Keys are the integer values of binaryninja.LowLevelILOperation enum members.
# We use integer keys so this module doesn't import binaryninja.
#
# Mapping rationale: same operation class -> same prime.
# Using LLIL (not native asm) makes this architecture-independent.
#
# Populated at import time by cfg.py using the real LowLevelILOperation enum values.
# Unknown ops map to prime 1 (identity element) in compute_prime_product().
LLIL_OP_PRIMES: dict[int, int] = {}


def compute_prime_product(llil_operations: list[int]) -> int:
    """
    Product of small primes assigned to each LLIL opcode.
    Position-independent: block reordering doesn't change the result.
    Mod 2^64 for fixed-size storage.

    Args:
        llil_operations: flat list of LLIL operation enum integer values
                         for all instructions in the function.
    Returns:
        UInt64 prime product, or 0 if no instructions.
    """
    if not llil_operations:
        return 0

    product = 1
    for op in llil_operations:
        prime = LLIL_OP_PRIMES.get(op, 1)
        product = (product * prime) % (2**64)

    return product


# ---------------------------------------------------------------------------
# Task 1.6: ACFG Block Features
# ---------------------------------------------------------------------------

# Instruction category indices for ACFG feature vectors
CAT_ARITHMETIC = 0
CAT_LOGIC = 1
CAT_TRANSFER = 2
CAT_CALL = 3
CAT_COMPARISON = 4
CAT_MEMORY = 5
CAT_OTHER = 6

# Maps LLIL operation integer values to category indices.
# Populated at import time by cfg.py using the real LowLevelILOperation enum.
LLIL_OP_CATEGORIES: dict[int, int] = {}


def build_block_features(
    block_llil_ops: list[list[int]],
    successors: list[list[int]],
    n: int,
) -> list[list[int]]:
    """
    Extract Gemini-style ACFG features per block.

    Args:
        block_llil_ops: per-block list of LLIL operation integer values.
                        block_llil_ops[i] is the list of ops for block i.
                        Empty list if LLIL unavailable for that block.
        successors: index-based adjacency list.
        n: number of blocks.

    Returns:
        List of [instr_count, arithmetic, logic, transfer, call, comparison,
                 memory, successor_count] per block. All values capped at 65535.
    """
    features = []
    for i in range(n):
        cats = [0, 0, 0, 0, 0, 0, 0]
        ops = block_llil_ops[i] if i < len(block_llil_ops) else []
        for op in ops:
            cat = LLIL_OP_CATEGORIES.get(op, CAT_OTHER)
            cats[cat] += 1

        instr_count = len(ops)
        features.append([
            min(instr_count, 65535),
            min(cats[CAT_ARITHMETIC], 65535),
            min(cats[CAT_LOGIC], 65535),
            min(cats[CAT_TRANSFER], 65535),
            min(cats[CAT_CALL], 65535),
            min(cats[CAT_COMPARISON], 65535),
            min(cats[CAT_MEMORY], 65535),
            min(len(successors[i]), 65535),
        ])

    return features


# ---------------------------------------------------------------------------
# Task 1.7: CFG Feature TLSH
# ---------------------------------------------------------------------------

def compute_cfg_feature_tlsh(
    bb_features: list[list[int]],
    bfs: list[int],
) -> Optional[str]:
    """
    TLSH hash of BFS-ordered per-block feature vectors.
    Captures both structure (BFS ordering) and instruction distribution.

    Returns TLSH hex string or None if too few bytes for TLSH (< 50).
    """
    import tlsh as _tlsh

    feature_bytes = bytearray()
    for idx in bfs:
        feats = bb_features[idx]
        feature_bytes.extend(struct.pack(
            '<HBBBBBBB',
            min(feats[0], 65535),
            min(feats[1], 255),
            min(feats[2], 255),
            min(feats[3], 255),
            min(feats[4], 255),
            min(feats[5], 255),
            min(feats[6], 255),
            min(feats[7], 255),
        ))

    if len(feature_bytes) < 50:
        return None

    try:
        h = _tlsh.hash(bytes(feature_bytes))
        return h if h and h != 'TNULL' else None
    except Exception:
        return None


# ---------------------------------------------------------------------------
# Task 1.8: WL-MinHash
# ---------------------------------------------------------------------------

# Pre-computed seeds for MinHash permutations.
NUM_WL_MINHASH_PERMS = 128
_WL_MINHASH_SEEDS = list(range(NUM_WL_MINHASH_PERMS))  # Seeds 0..127


def compute_wl_minhash(
    successors: list[list[int]],
    predecessors: list[list[int]],
    bb_features: list[list[int]],
    n: int,
    iterations: int = 3,
) -> list[int]:
    """
    Weisfeiler-Leman MinHash for fuzzy topology similarity.

    Initial labels: mmh3 hash of per-block ACFG feature tuple (content-aware).
    WL refinement: incorporate sorted neighbor labels at each iteration.
    MinHash: 128-permutation signature over shingle set.

    Returns list of 128 uint8 values, or [255]*128 sentinel for empty functions.
    """
    if n == 0:
        return [255] * NUM_WL_MINHASH_PERMS

    # Initial labels: hash of instruction category tuple per block
    labels = []
    for i in range(n):
        feats = bb_features[i] if i < len(bb_features) else [0] * 8
        # mmh3 with seed=0 for initial labels
        label = mmh3.hash(str(tuple(feats)), 0) & 0xFFFFFFFF
        labels.append(label)

    # Collect shingles: (iteration, label) pairs as strings for mmh3
    shingles: set[str] = set()

    # Iteration 0: individual block labels
    for label in labels:
        shingles.add(f"0:{label}")

    # WL iterations: refine labels by neighborhood aggregation
    for iteration in range(1, iterations + 1):
        new_labels = []
        for i in range(n):
            succ_labels = tuple(sorted(labels[s] for s in successors[i]))
            pred_labels = tuple(sorted(labels[p] for p in predecessors[i]))
            composite = f"{labels[i]}|{succ_labels}|{pred_labels}"
            new_label = mmh3.hash(composite, 0) & 0xFFFFFFFF
            new_labels.append(new_label)
            shingles.add(f"{iteration}:{new_label}")
        labels = new_labels

    if not shingles:
        return [255] * NUM_WL_MINHASH_PERMS

    # Compute MinHash signature using mmh3 with different seeds
    shingle_list = list(shingles)
    signature = []
    for seed in _WL_MINHASH_SEEDS:
        min_val = 0xFFFFFFFF
        for s in shingle_list:
            h = mmh3.hash(s, seed) & 0xFFFFFFFF
            if h < min_val:
                min_val = h
        # Compress to uint8 for storage
        signature.append(min_val & 0xFF)

    return signature


# ---------------------------------------------------------------------------
# Task 1.9: Packed Adjacency
# ---------------------------------------------------------------------------

def pack_adjacency(successors: list[list[int]]) -> list[int]:
    """
    Pack CFG edges as Array(UInt32).
    Each UInt32 = (source_index << 16) | target_index.
    Supports up to 65,535 blocks per function.
    """
    edges = []
    for src, targets in enumerate(successors):
        for tgt in targets:
            if src < 65536 and tgt < 65536:
                edges.append((src << 16) | tgt)
    return edges