Namkyeong Lee

42 papers A* 13A 3Journal 26
YearRankTypeTitle / Venue / Authors
2026 J jnl
CoRR
Heewoong Noh, Gyoung S. Na, Namkyeong Lee, Chanyoung Park
2026 A* conf
AAAI
Namkyeong Lee, Edward De Brouwer, Ehsan Hajiramezanali, Tommaso Biancalani, Chanyoung Park, Gabriele Scalia
2025 A* conf
ICML
Yunhak Oh, Junseok Lee, Yeongmin Kim, Sangwoo Seo, Namkyeong Lee, Chanyoung Park
2025 J jnl
CoRR
Yunhak Oh, Junseok Lee, Yeongmin Kim, Sangwoo Seo, Namkyeong Lee, Chanyoung Park
2025 J jnl
CoRR
Heewoong Noh, Namkyeong Lee, Gyoung S. Na, Kibum Kim, Chanyoung Park
2025 J jnl
CoRR
Junmo Kim, Namkyeong Lee, Jiwon Kim, Kwangsoo Kim
2025 J jnl
J. Data-centric Mach. Learn. Res.
Siddhartha Laghuvarapu, Namkyeong Lee, Chufan Gao, Jimeng Sun
2025 J jnl
CoRR
Namkyeong Lee, Edward De Brouwer, Ehsan Hajiramezanali, Chanyoung Park, Gabriele Scalia
2025 A* conf
ICLR
Sungwon Kim, Yoonho Lee, Yunhak Oh, Namkyeong Lee, Sukwon Yun, Junseok Lee, Sein Kim, Carl Yang, Chanyoung Park
2025 J jnl
CoRR
Sungwon Kim, Yoonho Lee, Yunhak Oh, Namkyeong Lee, Sukwon Yun, Junseok Lee, Sein Kim, Carl Yang, Chanyoung Park
2025 A* conf
ICML
Sungwon Kim, Namkyeong Lee, Yunyoung Doh, Seungmin Shin, Guimok Cho, Seung-Won Jeon, Sangkook Kim, Chanyoung Park
2025 J jnl
CoRR
Sungwon Kim, Namkyeong Lee, Yunyoung Doh, Seungmin Shin, Guimok Cho, Seung-Won Jeon, Sangkook Kim, Chanyoung Park
2024 J jnl
CoRR
Namkyeong Lee, Yunhak Oh, Heewoong Noh, Gyoung S. Na, Minkai Xu, Hanchen Wang, Tianfan Fu, Chanyoung Park
2024 A conf
CIKM
Kanghoon Yoon, Yeonjun In, Namkyeong Lee, Kibum Kim, Chanyoung Park
2024 J jnl
CoRR
Kanghoon Yoon, Yeonjun In, Namkyeong Lee, Kibum Kim, Chanyoung Park
2024 J jnl
CoRR
Bohao Xu, Yingzhou Lu, Yoshitaka Inoue, Namkyeong Lee, Tianfan Fu, Jintai Chen
2024 A* conf
NeurIPS
Heewoong Noh, Namkyeong Lee, Gyoung S. Na, Chanyoung Park
2024 J jnl
CoRR
Heewoong Noh, Namkyeong Lee, Gyoung S. Na, Chanyoung Park
2024 A conf
CIKM
Namkyeong Lee, Siddhartha Laghuvarapu, Chanyoung Park, Jimeng Sun
2024 J jnl
CoRR
Namkyeong Lee, Siddhartha Laghuvarapu, Chanyoung Park, Jimeng Sun
2023 A* conf
ICML
Namkyeong Lee, Dongmin Hyun, Gyoung S. Na, Sungwon Kim, Junseok Lee, Chanyoung Park
2023 J jnl
CoRR
Namkyeong Lee, Dongmin Hyun, Gyoung S. Na, Sungwon Kim, Junseok Lee, Chanyoung Park
2023 J jnl
Bioinform.
Junseok Lee, Sungwon Kim, Dongmin Hyun, Namkyeong Lee, Yejin Kim, Chanyoung Park
2023 A* conf
NeurIPS
Namkyeong Lee, Heewoong Noh, Sungwon Kim, Dongmin Hyun, Gyoung S. Na, Chanyoung Park
2023 J jnl
CoRR
Namkyeong Lee, Heewoong Noh, Sungwon Kim, Dongmin Hyun, Gyoung S. Na, Chanyoung Park
2023 A* conf
AAAI
Sein Kim, Namkyeong Lee, Junseok Lee, Dongmin Hyun, Chanyoung Park
2023 J jnl
CoRR
Namkyeong Lee, Heewoong Noh, Sungwon Kim, Dongmin Hyun, Gyoung S. Na, Chanyoung Park
2023 A* conf
KDD
Namkyeong Lee, Kanghoon Yoon, Gyoung S. Na, Sein Kim, Chanyoung Park
2023 J jnl
CoRR
Namkyeong Lee, Kanghoon Yoon, Gyoung S. Na, Sein Kim, Chanyoung Park
2023 J jnl
CoRR
Namkyeong Lee, Heewoong Noh, Gyoung S. Na, Tianfan Fu, Jimeng Sun, Chanyoung Park
2023 A* conf
KDD
Sein Kim, Namkyeong Lee, Donghyun Kim, Min-Chul Yang, Chanyoung Park
2023 J jnl
CoRR
Sein Kim, Namkyeong Lee, Donghyun Kim, Min-Chul Yang, Chanyoung Park
2023 A* conf
KDD
Sungwon Kim, Junseok Lee, Namkyeong Lee, Wonjoong Kim, Seungyoon Choi, Chanyoung Park
2023 J jnl
CoRR
Sungwon Kim, Junseok Lee, Namkyeong Lee, Wonjoong Kim, Seungyoon Choi, Chanyoung Park
2022 A* conf
AAAI
Namkyeong Lee, Junseok Lee, Chanyoung Park
2022 A* conf
SIGIR
Junseok Lee, Yunhak Oh, Yeonjun In, Namkyeong Lee, Dongmin Hyun, Chanyoung Park
2022 J jnl
CoRR
Junseok Lee, Yunhak Oh, Yeonjun In, Namkyeong Lee, Dongmin Hyun, Chanyoung Park
2022 J jnl
CoRR
Sein Kim, Namkyeong Lee, Junseok Lee, Dongmin Hyun, Chanyoung Park
2022 A conf
CIKM
Namkyeong Lee, Dongmin Hyun, Junseok Lee, Chanyoung Park
2022 J jnl
CoRR
Namkyeong Lee, Dongmin Hyun, Junseok Lee, Chanyoung Park
2022 J jnl
Inf. Sci.
Namkyeong Lee, Junseok Lee, Chanyoung Park
2021 J jnl
CoRR
Namkyeong Lee, Junseok Lee, Chanyoung Park
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)