Haitham S. Hamza

88 papers B 14C 15Misc 10Journal 20Unranked 28
YearRankTypeTitle / Venue / Authors
2020 J jnl
Array
Aghabi N. Abosaif, Haitham S. Hamza
2019 B conf
IWCMC
Khaled Elsayed, Mohamed Abu Baker Ibrahim, Haitham S. Hamza
2018 ed.
SEiA@ICSE
Haitham S. Hamza, Engineer Bainomugisha, Michel Chaudron, Imed Hammouda
2017 B conf
ENASE
Tashreen Shaikh Jamaluddin, Hoda Hassan, Haitham S. Hamza
2017 J jnl
Comput. Commun.
Shaimaa M. Mohamed, Haitham S. Hamza, Imane Aly Saroit
2017 C conf
SERA
Maiada M. Shabaan, Haitham S. Hamza, Yasser M. K. Omar
2017 J jnl
Ad Hoc Sens. Wirel. Networks
Shaimaa M. Mohamed, Haitham S. Hamza, Imane Aly Saroit
2017 C conf
SEKE
Nada Mahmoud, Haitham S. Hamza, Yasser M. K. Omar
2016 J jnl
JOCN
Haitham S. Hamza
2016 conf
ANT/SEIT
Ahmad M. Nagib, Haitham S. Hamza
2015 conf
WMNC
Ehab E. Zakaria, Haitham S. Hamza, Imane Aly Saroit
2015 J jnl
Ad Hoc Sens. Wirel. Networks
Ahmed Abdel Moamen, Haitham S. Hamza
2014 B conf
PIMRC
Mohamed M. Kassem, Haitham S. Hamza, Imane Aly Saroit
2014 B conf
PIMRC
Haitham S. Hamza, Mohamed M. Kassem, Amandy Magdy, Khaled El-Sayed
2014 J jnl
Int. J. Wirel. Inf. Networks
Haitham S. Hamza, Shady S. Khalifa, Khaled El-Sayed
2014 B conf
WiOpt
Shaimaa M. Mohamed, Haitham S. Hamza, Imane Aly Saroit
2014 J jnl
Int. J. Commun. Syst.
Ahmed Abdel Moamen, Haitham S. Hamza, Imane Aly Saroit
2013 J jnl
IEEE Commun. Surv. Tutorials
Abdelbaset S. Hamza, Shady S. Khalifa, Haitham S. Hamza, Khaled El-Sayed
2013 B conf
LCN
Sara A. Abd El Hamid, Haitham S. Hamza, Imane Aly Saroit
2013 conf
ITNG
Amina A. Imam, Haitham S. Hamza, Riham Abdel-Moneim
2013 conf
WOCC
Reham Adel, Tawfik Ismail, Haitham S. Hamza
2013 conf
VTC Spring
Shady S. Khalifa, Haitham S. Hamza, Khaled El-Sayed
2013 B conf
PIMRC
Shady S. Khalifa, Haitham S. Hamza, Khaled El-Sayed
2013 conf
ITNG
Haitham S. Hamza, Amr Kamel, Khaled Mohamed Shams
2013 C conf
SEKE
Khaled Mohamed Shams, Haitham S. Hamza, Amr Kamel
2013 C conf
SEKE
Mohamed Elshaarawy, Haitham S. Hamza, Ismail Abdel Hamid Taha
2012 J jnl
J. Supercomput.
Haitham S. Hamza
2012 conf
SPLC (1)
Haitham S. Hamza, Jabier Martinez, Anil Kumar Thurimella, Jitender S. Deogun
2011 conf
ITNG
Haitham S. Hamza, Dina Darwish
2011 J jnl
Photonic Netw. Commun.
Haitham S. Hamza
2011 C conf
SEKE
Mohamed A. Zaatar, Haitham S. Hamza, Abd El Fatah Hegazy
2011 J jnl
Photonic Netw. Commun.
Haitham S. Hamza, Tawfik Ismail, Khaled El-Sayed
2011 B conf
SPLC
Haitham S. Hamza, Jabier Martinez, Andreas Rummler
2011 Misc conf
IRI
Mohamed Maher, Haitham S. Hamza, Ramadan Moawad Mohamed
2011 conf
ITNG
Wafaa Saber Hamed, Haitham S. Hamza, Imane Aly Saroit
2010 B conf
SPLC
Haitham S. Hamza, Jabier Martinez
2010 J jnl
Int. J. Commun. Syst.
Yu Lin, Haitham S. Hamza
2010 C conf
SEKE
Ahmed Raafat Abuzeid, Haitham S. Hamza, Ismail Abdel Hamid Taha
2010 conf
SPLC Workshops
Haitham S. Hamza, Jabier Martinez, Carmen Alonso
2010 conf
SPLASH/OOPSLA Companion
Haitham S. Hamza, Jabier Martinez, Joseba Laka Mugartza
2010 J jnl
IEEE Commun. Lett.
Haitham S. Hamza
2010 J jnl
Photonic Netw. Commun.
Haitham S. Hamza
2009 conf
ITNG
Haitham S. Hamza
2009 conf
ITNG
Haitham S. Hamza, Dina Darwish
2009 J jnl
Photonic Netw. Commun.
Haitham S. Hamza
2008 J jnl
Egypt. Comput. Sci. J.
Haitham S. Hamza, Shasha Wu
2007 C conf
BROADNETS
Haitham S. Hamza, Jitender S. Deogun
2007 J jnl
Photonic Netw. Commun.
Haitham S. Hamza, Jitender S. Deogun
2007 conf
ICC
Eric D. Manley, Haitham S. Hamza, Jitender S. Deogun
2007 J jnl
IEEE/ACM Trans. Netw.
Haitham S. Hamza, Jitender S. Deogun
2006 conf
ICC
Haitham S. Hamza, Jitender S. Deogun
2006 C conf
BROADNETS
Haitham S. Hamza, Jitender S. Deogun
2006 B conf
Networking
Yu Lin, Haitham S. Hamza, Jitender S. Deogun
2006 conf
Hot Interconnects
Haitham S. Hamza, Jitender S. Deogun
2006 B conf
Networking
Haitham S. Hamza, Jitender S. Deogun
2006 B conf
GLOBECOM
Haitham S. Hamza, Jitender S. Deogun
2006 B conf
GLOBECOM
Haitham S. Hamza, Jitender S. Deogun
2006 conf
ICC
Yu Lin, Haitham S. Hamza, Jitender S. Deogun
2006 C conf
AICCSA
Haitham S. Hamza, Mohamed E. Fayad
2006 conf
Hot Interconnects
Haitham S. Hamza, Jitender S. Deogun
2005 C conf
SEKE
Haitham S. Hamza
2005 Misc conf
IRI
Yi Chen, Haitham S. Hamza, Mohamed E. Fayad
2005 C conf
IPCCC
Haitham S. Hamza, Jitender S. Deogun
2005 C conf
AICCSA
Haitham S. Hamza, Mohamed E. Fayad
2005 conf
OOPSLA Companion
Haitham S. Hamza
2005 Misc conf
HiPC
Jitender S. Deogun, Saket Das, Haitham S. Hamza, Steve Goddard
2005 C conf
BROADNETS
Haitham S. Hamza, Jitender S. Deogun
2005 conf
OOPSLA Companion
Haitham S. Hamza
2005 C conf
Communication Systems and Applications
Haitham S. Hamza, Shasha Wu, Jitender S. Deogun
2005 B conf
ITiCSE
Haitham S. Hamza
2005 conf
OOPSLA Companion
Haitham S. Hamza, Yi Chen
2005 conf
MACS@ICSE
Haitham S. Hamza
2005 J jnl
ACM SIGSOFT Softw. Eng. Notes
Haitham S. Hamza
2005 C conf
SEKE
Haitham S. Hamza, Mohamed E. Fayad
2005 conf
COMPSAC (2)
Nader Mohamed, Haitham S. Hamza
2005 Misc conf
IRI
Mohamed Fayad, Haitham S. Hamza, Huáscar A. Sánchez
2005 Misc conf
HiPC
Haitham S. Hamza, Jitender S. Deogun
2004 J jnl
J. Object Technol.
Haitham S. Hamza, Mohamed E. Fayad
2004 Misc conf
IRI
Ahmed M. Mahdy, Haitham S. Hamza, Mohamed E. Fayad, Marshall Cline
2004 Misc conf
SenSys
Haitham S. Hamza, Shasha Wu
2004 conf
OOPSLA Companion
Haitham S. Hamza
2003 Misc conf
IRI
Mohamed E. Fayad, Haitham S. Hamza, Huáscar A. Sánchez
2003 conf
OOPSLA Companion
Haitham S. Hamza, Mohamed E. Fayad
2003 conf
OOIS
Haitham S. Hamza, Ahmed M. Mahdy, Mohamed E. Fayad, Marshall Cline
2003 conf
OOPSLA Companion
Haitham S. Hamza, Ahmed M. Mahdy, Mohamed E. Fayad, Marshall Cline
2003 Misc conf
EuroPLoP
Haitham S. Hamza, Mohamed E. Fayad
2003 Misc conf
IRI
Mohamed E. Fayad, Haitham S. Hamza, Jayashree Rajagopalan
2002 conf
OOPSLA Companion
Haitham S. Hamza
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