Catalina Curceanu

18 papers Journal 18
YearRankTypeTitle / Venue / Authors
2025 J jnl
Entropy
Luca De Paolis, Elisabetta Pace, Chiara Maria Mazzanti, Mariangela Morelli, Francesca Di Lorenzo, Lucio Tonello, Catalina Curceanu, Alberto Clozza, Maurizio Grandi, Ivan Davoli, Angelo Gemignani, Paolo Grigolini, Maurizio Benfatto
2024 J jnl
Entropy
Simone Manti, Massimiliano Bazzi, Nicola Bortolotti, Cesidio Capoccia, Michael Cargnelli, Alberto Clozza, Luca De Paolis, Carlo Fiorini, Carlo Guaraldo, Mihail Antoniu Iliescu, Matthias Laubenstein, Johann Marton, Fabrizio Napolitano, Kristian Piscicchia, Alessio Porcelli, Alessandro Scordo, Francesco Sgaramella, Diana Laura Sirghi, Florin Sirghi, Oton Vazquez Doce, Johann Zmeskal, Catalina Curceanu
2023 J jnl
Entropy
Kristian Piscicchia, Alessio Porcelli, Angelo Bassi, Massimiliano Bazzi, Mario Bragadireanu, Michael Cargnelli, Alberto Clozza, Luca De Paolis, Raffaele Del Grande, Maaneli Derakhshani, Diósi Lajos, Sandro Donadi, Carlo Guaraldo, Mihail Antoniu Iliescu, Matthias Laubenstein, Simone Manti, Johann Marton, Marco Miliucci, Fabrizio Napolitano, Alessandro Scordo, Francesco Sgaramella, Diana Laura Sirghi, Florin Sirghi, Oton Vazquez Doce, Johann Zmeskal, Catalina Curceanu
2023 J jnl
Entropy
Maurizio Benfatto, Elisabetta Pace, Ivan Davoli, Roberto Francini, Fabio De Matteis, Alessandro Scordo, Alberto Clozza, Luca De Paolis, Catalina Curceanu, Paolo Grigolini
2023 J jnl
Sensors
Leonardo Abbene, Antonino Buttacavoli, Fabio Principato, Gaetano Gerardi, Manuele Bettelli, Andrea Zappettini, Massimiliano Bazzi, Mario Bragadireanu, Michael Cargnelli, Marco Carminati, Alberto Clozza, Griseld Deda, Raffaele Del Grande, Luca De Paolis, Laura Fabbietti, Carlo Fiorini, Carlo Guaraldo, Mihail Antoniu Iliescu, Masahiko Iwasaki, Aleksander Khreptak, Simone Manti, Johann Marton, Marco Miliucci, Pawel Moskal, Fabrizio Napolitano, Szymon Niedzwiecki, Hiroaky Ohnishi, Kristian Piscicchia, Yuta Sada, Francesco Sgaramella, Hexi Shi, Michal Silarski, Diana Laura Sirghi, Florin Sirghi, Magdalena Skurzok, Antonio Spallone, Kairo Toho, Marlene Tüchler, Oton Vazquez Doce, Chihiro Yoshida, Johann Zmeskal, Alessandro Scordo, Catalina Curceanu
2023 J jnl
Symmetry
Fabrizio Napolitano, Andrea Addazi, Angelo Bassi, Massimiliano Bazzi, Mario Bragadireanu, Michael Cargnelli, Alberto Clozza, Luca De Paolis, Raffaele Del Grande, Maaneli Derakhshani, Sandro Donadi, Carlo Fiorini, Carlo Guaraldo, Mihail Antoniu Iliescu, Matthias Laubenstein, Simone Manti, Antonino Marciano, Johann Marton, Marco Miliucci, Edoardo Milotti, Kristian Piscicchia, Alessio Porcelli, Alessandro Scordo, Francesco Sgaramella, Diana Laura Sirghi, Florin Sirghi, Oton Vazquez Doce, Johann Zmeskal, Catalina Curceanu
2022 J jnl
Symmetry
Fabrizio Napolitano, Sergio Bartalucci, Sergio Bertolucci, Massimiliano Bazzi, Mario Bragadireanu, Cesidio Capoccia, Michael Cargnelli, Alberto Clozza, Luca De Paolis, Raffaele Del Grande, Carlo Fiorini, Carlo Guaraldo, Mihail Antoniu Iliescu, Matthias Laubenstein, Johann Marton, Marco Miliucci, Edoardo Milotti, Federico Nola, Kristian Piscicchia, Alessio Porcelli, Alessandro Scordo, Francesco Sgaramella, Hexi Shi, Diana Laura Sirghi, Florin Sirghi, Oton Vazquez Doce, Johann Zmeskal, Catalina Curceanu
2021 J jnl
Entropy
Maurizio Benfatto, Elisabetta Pace, Catalina Curceanu, Alessandro Scordo, Alberto Clozza, Ivan Davoli, Massimiliano Lucci, Roberto Francini, Fabio De Matteis, Maurizio Grandi, Rohisha Tuladhar, Paolo Grigolini
2021 J jnl
Medical Image Anal.
Roman Y. Shopa, Konrad Klimaszewski, P. Kopka, Pawel Kowalski, Wojciech Krzemien, Lech Raczynski, Wojciech Wislicki, Neha Chug, Catalina Curceanu, Eryk Czerwinski, Meysam Dadgar, Kamil Dulski, Aleksander Gajos, Beatrix C. Hiesmayr, Krzysztof Kacprzak, Lukasz Kaplon, Daria Kisielewska, Grzegorz Korcyl, Nikodem Krawczyk, Ewelina Kubicz, Szymon Niedzwiecki, Juhi Raj, Sushil Sharma, Shivani, Ewa L. Stepien, Faranak Tayefi, Pawel Moskal
2021 J jnl
IEEE Trans. Instrum. Meas.
Mihail Antoniu Iliescu, Marco Miliucci, Aidin Amirkhani, Massimiliano Bazzi, Catalina Curceanu, Carlo Fiorini, Florin Sirghi, Johann Zmeskal
2021 J jnl
Symmetry
Edoardo Milotti, Sergio Bartalucci, Sergio Bertolucci, Massimiliano Bazzi, Mario Bragadireanu, Michael Cargnelli, Alberto Clozza, Catalina Curceanu, Luca De Paolis, Raffaele Del Grande, Carlo Guaraldo, Mihail Antoniu Iliescu, Matthias Laubenstein, Johann Marton, Marco Miliucci, Fabrizio Napolitano, Kristian Piscicchia, Alessandro Scordo, Hexi Shi, Diana Laura Sirghi, Florin Sirghi, Laura Sperandio, Oton Vazquez Doce, Johann Zmeskal
2021 J jnl
IEEE Trans. Instrum. Meas.
Pawel Moskal, Tomasz Bednarski, Szymon Niedzwiecki, Michal Silarski, Eryk Czerwinski, Tomasz Kozik, J. Chhokar, Mateusz Bala, Catalina Curceanu, Raffaele Del Grande, Meysam Dadgar, Kamil Dulski, Aleksander Gajos, Marek Gorgol, Neha Gupta-Sharma, Beatrix C. Hiesmayr, Bozena Jasinska, Krzysztof Kacprzak, Lukasz Kaplon, Hanieh Karimi, Daria Kisielewska, Konrad Klimaszewski, Grzegorz Korcyl, Pawel Kowalski, Nikodem Krawczyk, Wojciech Krzemien, Ewelina Kubicz, Muhsin Mohammed, Marek Palka, Monika Pawlik-Niedzwiecka, Lech Raczynski, Juhi Raj, Sushil Sharma, Shivani, Roman Y. Shopa, Magdalena Skurzok, Ewa L. Stepien, Wojciech Wislicki, Bozena Zgardzinska
2020 J jnl
Symmetry
Catalina Curceanu, Carlo Guaraldo, Diana Laura Sirghi, Aidin Amirkhani, Ata Baniahmad, Massimiliano Bazzi, Giovanni Bellotti, Damir Bosnar, Mario Bragadireanu, Michael Cargnelli, Marco Carminati, Alberto Clozza, Luca De Paolis, Raffaele Del Grande, Carlo Fiorini, Mihail Antoniu Iliescu, Masahiko Iwasaki, Pietro King, Paolo Levi Sandri, Johann Marton, Marco Miliucci, Pawel Moskal, Szymon Niedzwiecki, Shinji Okada, Kristian Piscicchia, Alessandro Scordo, Michal Silarski, Florin Sirghi, Magdalena Skurzok, Antonio Spallone, Marlene Tüchler, Gianlorenzo Utica, Oton Vazquez Doce, Johann Zmeskal
2020 J jnl
Entropy
Kristian Piscicchia, Johann Marton, Sergio Bartalucci, Massimiliano Bazzi, Sergio Bertolucci, Mario Bragadireanu, Michael Cargnelli, Alberto Clozza, Raffaele Del Grande, Luca De Paolis, Carlo Fiorini, Carlo Guaraldo, Mihail Antoniu Iliescu, Matthias Laubenstein, Marco Miliucci, Edoardo Milotti, Fabrizio Napolitano, Andreas Pichler, Alessandro Scordo, Hexi Shi, Diana Laura Sirghi, Florin Sirghi, Laura Sperandio, Oton Vazquez Doce, Johann Zmeskal, Catalina Curceanu
2018 J jnl
IEEE Trans. Medical Imaging
Grzegorz Korcyl, Piotr Bialas, Catalina Curceanu, Eryk Czerwinski, Kamil Dulski, B. Flak, Aleksander Gajos, Bartosz Glowacz, Marek Gorgol, Beatrix C. Hiesmayr, Bozena Jasinska, Krzysztof Kacprzak, M. Kajetanowicz, Daria Kisielewska, Pawel Kowalski, Tomasz Kozik, Nikodem Krawczyk, Wojciech Krzemien, Ewelina Kubicz, Muhsin Mohammed, Szymon Niedzwiecki, Monika Pawlik-Niedzwiecka, Marek Palka, Lech Raczynski, P. Rajda, Zbigniew Rudy, Piotr Salabura, Neha Gupta-Sharma, Sushil Sharma, Roman Y. Shopa, Magdalena Skurzok, Michal Silarski, Pawel Strzempek, Anna Wieczorek, Wojciech Wislicki, Radek Zaleski, Bozena Zgardzinska, Marcin Zielinski, Pawel Moskal
2018 J jnl
Entropy
Edoardo Milotti, Sergio Bartalucci, Sergio Bertolucci, Massimiliano Bazzi, Mario Bragadireanu, Michael Cargnelli, Alberto Clozza, Catalina Curceanu, Luca De Paolis, Jean-Pierre Egger, Carlo Guaraldo, Mihail Antoniu Iliescu, Matthias Laubenstein, Johann Marton, Marco Miliucci, Andreas Pichler, Dorel Pietreanu, Kristian Piscicchia, Alessandro Scordo, Hexi Shi, Diana Laura Sirghi, Florin Sirghi, Laura Sperandio, Oton Vazquez Doce, Eberhard Widmann, Johann Zmeskal
2017 J jnl
Entropy
Kristian Piscicchia, Angelo Bassi, Catalina Curceanu, Raffaele Del Grande, Sandro Donadi, Beatrix C. Hiesmayr, Andreas Pichler
2017 J jnl
Entropy
Catalina Curceanu, Hexi Shi, Sergio Bartalucci, Sergio Bertolucci, Massimiliano Bazzi, Carolina Berucci, Mario Bragadireanu, Michael Cargnelli, Alberto Clozza, Luca De Paolis, Sergio Di Matteo, Jean-Pierre Egger, Carlo Guaraldo, Mihail Antoniu Iliescu, Johann Marton, Matthias Laubenstein, Edoardo Milotti, Marco Miliucci, Andreas Pichler, Dorel Pietreanu, Kristian Piscicchia, Alessandro Scordo, Diana Laura Sirghi, Florin Sirghi, Laura Sperandio, Oton Vazquez Doce, Eberhard Widmann, Johann Zmeskal
redb/extractors/js_extractors/js_context.py
← Index redb/extractors/js_extractors/js_context.py python
"""Per-sample shared state for the JavaScript extractor pipeline.

A `JSContext` is built exactly once per JS sample (in `workers.py`) and threaded
into every extractor that runs against that sample. It owns the disk read, the
decoded source text, the line-split cache, the Shannon text-entropy figure, the
shared `scan_source()` results, and the pyjsparser AST. Each of those is
computed lazily through `cached_property` so an extractor that doesn't need a
particular artefact does not pay for it.

Without this object, every JS extractor instance redoes the same disk read,
decode, scan, and (for any consumer) AST parse. With it, every extractor
shares one set of results.

`JSExtractor.__init__` accepts the context via a `context=` kwarg; if absent
(e.g. unit tests instantiating an extractor directly with `source=...`) it
builds a fresh context from the constructor arguments. Either path produces a
fully-populated context, so extractor code can always rely on
`self._context.scan` / `self._context.ast` / etc.
"""

from __future__ import annotations

import math
from collections import Counter
from dataclasses import dataclass
from functools import cached_property
from typing import Any, Dict, List, Optional

import chardet

from redb.extractors.js_extractors.js_patterns import scan_source


def decode_source(raw_bytes: bytes) -> str:
    """Decode raw JS bytes to text, honouring BOMs and falling back to chardet.

    Mirrors the historical `JSExtractor._decode_source` logic so existing tests
    continue to round-trip identically.
    """
    if not raw_bytes:
        return ""

    if raw_bytes[:3] == b"\xef\xbb\xbf":
        return raw_bytes[3:].decode("utf-8", errors="replace")
    if raw_bytes[:2] in (b"\xff\xfe", b"\xfe\xff"):
        return raw_bytes.decode("utf-16", errors="replace")

    try:
        return raw_bytes.decode("utf-8")
    except UnicodeDecodeError:
        pass

    try:
        detected = chardet.detect(raw_bytes)
        if detected and detected.get("encoding"):
            return raw_bytes.decode(detected["encoding"], errors="replace")
    except Exception:
        pass

    return raw_bytes.decode("latin-1", errors="replace")


def _text_entropy(text: str) -> float:
    """Shannon entropy of the character distribution of `text`, rounded to 4dp."""
    if not text:
        return 0.0
    counter = Counter(text)
    length = len(text)
    entropy = 0.0
    for count in counter.values():
        p = count / length
        if p > 0:
            entropy -= p * math.log2(p)
    return round(entropy, 4)


@dataclass
class JSContext:
    """Shared raw materials for one JS sample, consumed by every JS extractor.

    Cheap attributes (raw_bytes, source) are populated eagerly by the factory.
    Expensive ones (scan, ast) are cached_property — computed on first access
    and reused across every extractor that holds the same context.

    `content_type` is the magika label (e.g. `"javascript"`) carried alongside
    the source so the new code_text_content writer (and any future generic
    text-content writer) can record it without re-running magika. Defaults to
    `"javascript"` because by construction this context type is JS-specific;
    workers.py supplies the actual magika value when it builds the context.
    """

    filepath: str
    raw_bytes: bytes
    source: str
    log: Any = None
    content_type: str = "javascript"
    # Populated by JSStringsExtractor.extract() (the decoded/reconstructed
    # strings — hex/unicode/charcode/base64/concat unpacked into plaintext).
    # Read post-loop by the IOC plumbing in workers.py so any IOCs hidden
    # behind those encodings get scraped from the decoded form. Stays None
    # if JSStringsExtractor didn't run for this sample.
    decoded_strings: Optional[list] = None

    @cached_property
    def lines(self) -> List[str]:
        return self.source.splitlines() if self.source else []

    @cached_property
    def text_entropy(self) -> float:
        return _text_entropy(self.source)

    @cached_property
    def scan(self) -> Dict[str, Dict[str, object]]:
        """Result of running scan_source() exactly once over self.source."""
        return scan_source(self.source) if self.source else {}

    @cached_property
    def ast(self) -> Optional[Any]:
        """Lazy pyjsparser AST. Returns None if the parser is missing or fails.

        Extractors should treat None AST as "fall back to regex" — every
        AST-consuming extractor already handles that path.
        """
        if not self.source:
            return None
        try:
            import pyjsparser
            return pyjsparser.parse(self.source)
        except ImportError:
            if self.log is not None:
                self.log.debug("pyjsparser not installed, AST analysis skipped")
        except Exception as e:
            if self.log is not None:
                self.log.warning(f"AST parsing failed for {self.filepath}: {e}")
        return None

    @cached_property
    def deobfuscated(self) -> "tuple[Optional[str], Optional[str]]":
        """Run the configured JS deobfuscator (with jsbeautifier fallback) once
        per sample and cache the result. Returns `(text, normalizer_used)` or
        `(None, None)` if neither path produced output.

        Computed lazily on first access — samples whose pipeline never reads
        this don't pay the subprocess cost.
        """
        from redb.extractors.js_extractors.js_deobfuscator import deobfuscate
        return deobfuscate(self.source, self.log)

    @cached_property
    def scan_deobfuscated(self) -> Dict[str, Dict[str, object]]:
        """Result of running scan_source() exactly once over the deobfuscated
        text, keyed by PATTERNS only (FEATURE_PATTERNS are not consulted by
        the dual-pass consumers). Empty dict when there is no deobfuscated
        text or it equals the raw source.

        Two extractors consume the post-deobf API surface:
        `JSSuspiciousAPIsExtractor` (for revealed_by_deobf rows) and
        `JSDeobfuscationExtractor` (for the new_apis_found diff). Caching here
        means we scan the deobfuscated text once instead of twice per sample.
        """
        from redb.extractors.js_extractors.js_patterns import PATTERNS
        deobf_text, _ = self.deobfuscated
        if not deobf_text or deobf_text == self.source:
            return {}
        return scan_source(deobf_text, patterns=(PATTERNS,))

    @cached_property
    def xray(self):
        """Run @nodesecure/js-x-ray once per sample and cache the result.

        Returns an `XRayResult` (always — the function collapses every failure
        path to an empty result so callers don't have to special-case missing
        Node, missing package, timeouts, or parse errors). The
        `JSFeaturesExtractor` reads it for the obfuscator family name and for
        corroborating warning kinds; the heuristic falls back cleanly when
        `xray.obfuscator is None`.
        """
        from redb.extractors.js_extractors.js_xray import run
        return run(self.source, self.log)

    @classmethod
    def from_path(
        cls,
        filepath: str,
        log: Any = None,
        source: Optional[str] = None,
        raw_bytes: Optional[bytes] = None,
        content_type: str = "javascript",
    ) -> "JSContext":
        """Build a context from disk. `raw_bytes` and `source` are optional
        overrides — useful when the caller has already read or decoded the file.
        `content_type` is the magika label workers.py dispatched on; it lands
        on the context for the code_text_content writer to record.
        """
        if raw_bytes is None:
            with open(filepath, "rb") as f:
                raw_bytes = f.read()
        if source is None:
            source = decode_source(raw_bytes)
        return cls(
            filepath=filepath,
            raw_bytes=raw_bytes,
            source=source,
            log=log,
            content_type=content_type,
        )