Carlos Molina

25 papers A 9C 3Journal 11Unranked 2
YearRankTypeTitle / Venue / Authors
2023 J jnl
Sensors
Claudia Meza, Jesus Juega, Jaume Francisco, Alba Santos, Laura Duran, Maite Rodriguez, Jose Alvarez-Sabin, Laia Sero, Xavier Ustrell, Saima Bashir, Joaquín Serena, Yolanda Silva, Carlos Molina, Jorge Pagola
2023 conf
MIE
Carlos Molina, Belén Prados-Suárez
2014 C conf
FIE
Carlos Molina, Reynaldo Belfort, Rafael Pol, Oscar Chacon, Luis Rivera, Daniel Ramos, Eduardo I. Ortiz-Rivera
2013 conf
ICEIS (1)
Belén Prados-Suárez, Carlos Molina, Miguel A. Prados de Reyes, Maria Carmen Peña Yáñez
2013 C conf
FQAS
Carlos Molina, Belén Prados-Suárez, Miguel A. Prados de Reyes, Maria Carmen Peña Yáñez
2011 A conf
INTERSPEECH
Carlos Molina, Sungbok Lee, Shrikanth S. Narayanan, Néstor Becerra Yoma
2010 J jnl
IEEE Trans. Speech Audio Process.
Carlos Molina, Néstor Becerra Yoma, Fernando Huenupán, Claudio Garretón, Jorge Wuth
2009 J jnl
Speech Commun.
Carlos Molina, Néstor Becerra Yoma, Jorge Wuth, Hiram Vivanco
2009 A conf
INTERSPEECH
Carlos Molina, Néstor Becerra Yoma, Jorge Wuth, Hiram Vivanco
2008 J jnl
Pattern Recognit. Lett.
Fernando Huenupán, Néstor Becerra Yoma, Carlos Molina, Claudio Garretón
2008 J jnl
Speech Commun.
Néstor Becerra Yoma, Claudio Garretón, Carlos Molina, Fernando Huenupán
2008 A conf
INTERSPEECH
Carlos Molina, Néstor Becerra Yoma, Fernando Huenupán, Claudio Garretón
2007 A conf
INTERSPEECH
Claudio Garretón, Néstor Becerra Yoma, Fernando Huenupán, Carlos Molina
2007 A conf
INTERSPEECH
Fernando Huenupán, Néstor Becerra Yoma, Carlos Molina, Claudio Garretón
2007 A conf
INTERSPEECH
Carlos Molina, Néstor Becerra Yoma, Fernando Huenupán, Claudio Garretón
2006 J jnl
Signal Process.
Néstor Becerra Yoma, Carlos Molina
2006 A conf
INTERSPEECH
Claudio Garretón, Néstor Becerra Yoma, Carlos Molina, Fernando Huenupán
2006 J jnl
IEEE Trans. Speech Audio Process.
Néstor Becerra Yoma, Carlos Molina, Jorge F. Silva, Carlos Busso
2005 J jnl
IEEE Signal Process. Lett.
Néstor Becerra Yoma, Jorge Carrasco, Carlos Molina
2004 A conf
INTERSPEECH
Ivan Brito, Néstor Becerra Yoma, Carlos Molina
2004 A conf
INTERSPEECH
Néstor Becerra Yoma, Ivan Brito, Carlos Molina
2003 J jnl
BMC Bioinform.
Ramana V. Davuluri, Hao Sun, Saranyan K. Palaniswamy, Nicole Matthews, Carlos Molina, Mike Kurtz, Erich Grotewold
2000 J jnl
Eur. Trans. Telecommun.
Enrique Aleman-Llanes, David Muñoz-Rodríguez, Carlos Molina
1998 C conf
ISCC
Enrique Aleman-Llanes, David Muñoz-Rodríguez, Carlos Molina
1998 J jnl
IEEE Commun. Lett.
Alejandro Aguirre, David Muñoz-Rodríguez, Carlos Molina, Kalyan Basu
redb/extractors/js_extractors/js_deobfuscator.py
← Index redb/extractors/js_extractors/js_deobfuscator.py python
"""Subprocess-driven JavaScript deobfuscator with jsbeautifier fallback.

Owns the heavy lifting that was previously embedded inside
`JSDeobfuscationExtractor` (`_run_deobfuscator` + `_try_jsbeautifier`). Exposed
as a single module-level entry point `deobfuscate(source, log)` so it can be
called from `JSContext.deobfuscated` (cached per sample) without dragging
extractor state through the call.

Configuration (env vars):
    JS_DEOBFUSCATOR_PATH    Path or name of the external tool (default: webcrack).
    JS_DEOBFUSCATE_TIMEOUT  Seconds before the external tool is killed
                            (process-group SIGTERM, then SIGKILL). Default: 60.

If the external tool produces non-empty output and exits 0, that wins. Otherwise
the source is run through jsbeautifier (which only normalises formatting, but
already exposes strings hidden by minification). If neither path produces
output, returns (None, None).

`FileNotFoundError` for the external tool is treated as routine — the analysis
server is either provisioned with the tool or it isn't — and demoted to a
debug-level log.
"""

import os
import signal
import subprocess
import tempfile
from typing import Optional, Tuple

DEFAULT_DEOBFUSCATOR = "webcrack"
DEFAULT_TIMEOUT_SECS = 60


def _run_external(
    source: str, deobfuscator_path: str, timeout: int, log
) -> Tuple[Optional[str], int]:
    """Run the configured external deobfuscator over `source` and capture stdout.

    Returns (text, returncode). `text` is `None` and `returncode` is `-1` when
    the binary is missing, the run timed out, or any other unexpected failure
    occurred. Missing-binary is logged at debug; timeouts and unexpected errors
    surface at warning/error.
    """
    try:
        with tempfile.NamedTemporaryFile(
            suffix=".js", mode="w", delete=False, encoding="utf-8"
        ) as tmp:
            tmp.write(source)
            tmp_path = tmp.name

        try:
            process = subprocess.Popen(
                [deobfuscator_path, tmp_path],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                preexec_fn=os.setsid,
            )

            try:
                stdout, _ = process.communicate(timeout=timeout)
                return stdout.decode("utf-8", errors="replace"), process.returncode
            except subprocess.TimeoutExpired:
                # Kill the entire process group so spawned helpers (e.g. node
                # subprocesses webcrack itself launches) get cleaned up too.
                try:
                    os.killpg(os.getpgid(process.pid), signal.SIGTERM)
                    process.wait(timeout=5)
                except Exception:
                    try:
                        os.killpg(os.getpgid(process.pid), signal.SIGKILL)
                    except Exception:
                        pass
                log.warning(f"Deobfuscation timed out after {timeout}s")
                return None, -1
        finally:
            try:
                os.unlink(tmp_path)
            except Exception:
                pass
    except FileNotFoundError:
        log.debug(f"Deobfuscator binary not found at {deobfuscator_path}")
        return None, -1
    except Exception as e:
        log.error(f"Error running deobfuscator: {e}")
        return None, -1


def _try_jsbeautifier(source: str, log) -> Tuple[Optional[str], Optional[str]]:
    """Fallback path: format the source with jsbeautifier. Returns
    `(text, "jsbeautifier")` or `(None, None)` if jsbeautifier isn't installed
    or the call raised."""
    try:
        import jsbeautifier
        opts = jsbeautifier.default_options()
        opts.indent_size = 2
        return jsbeautifier.beautify(source, opts), "jsbeautifier"
    except ImportError:
        log.debug("jsbeautifier not available")
        return None, None
    except Exception as e:
        log.warning(f"jsbeautifier failed: {e}")
        return None, None


def deobfuscate(source: str, log) -> Tuple[Optional[str], Optional[str]]:
    """Run the configured external deobfuscator, falling back to jsbeautifier.

    Returns `(text, normalizer_used)` on success, or `(None, None)` when neither
    path produced non-empty output. `normalizer_used` is the basename of the
    external tool (e.g. `"webcrack"`) or the literal `"jsbeautifier"`.
    """
    if not source:
        return None, None

    deobfuscator_path = os.getenv("JS_DEOBFUSCATOR_PATH", DEFAULT_DEOBFUSCATOR)
    timeout = int(os.getenv("JS_DEOBFUSCATE_TIMEOUT", str(DEFAULT_TIMEOUT_SECS)))

    text, returncode = _run_external(source, deobfuscator_path, timeout, log)
    if text and returncode == 0 and text.strip():
        return text, os.path.basename(deobfuscator_path)

    return _try_jsbeautifier(source, log)