Wataru Nakamura

20 papers A* 1B 1C 3Journal 7Unranked 8
YearRankTypeTitle / Venue / Authors
2026 J jnl
IEICE Trans. Fundam. Electron. Commun. Comput. Sci.
Wataru Nakamura, Kenta Takahashi
2025 C conf
ISC
Wataru Nakamura, Yusei Suzuki, Masakazu Fujio, Kenta Takahashi
2025 C conf
ICBC
Ken Naganuma, Shingo Akata, Masayuki Yoshino, Noboru Kunihiro, Non Kawana, Wataru Nakamura, Kenta Takahashi, Takayuki Suzuki
2025 J jnl
IEICE Trans. Fundam. Electron. Commun. Comput. Sci.
Wataru Nakamura, Kenta Takahashi
2024 J jnl
CoRR
Kenta Takahashi, Wataru Nakamura
2024 conf
APSIPA
Kenta Takahashi, Wataru Nakamura
2024 conf
CyberSciTech
Yoshiko Yasumura, Masakazu Fujio, Wataru Nakamura, Kenta Takahashi
2024 conf
CANDAR
Wataru Nakamura, Kenta Takahashi
2023 conf
APSIPA ASC
Wataru Nakamura, Kenta Takahashi
2021 conf
ICRCA
Wataru Nakamura, Tomoaki Hashimoto
2021 A* conf
CCS
Shuichi Katsumata, Takahiro Matsuda, Wataru Nakamura, Kazuma Ohara, Kenta Takahashi
2021 J jnl
CoRR
Shuichi Katsumata, Takahiro Matsuda, Wataru Nakamura, Kazuma Ohara, Kenta Takahashi
2021 B conf
ARES
Masakazu Fujio, Kenta Takahashi, Yosuke Kaga, Wataru Nakamura, Yoshiko Yasumura, Rie Shigetomi Yamaguchi
2021 conf
CANDAR
Yoshiko Yasumura, Masakazu Fujio, Wataru Nakamura, Yosuke Kaga, Kenta Takahashi
2019 conf
APSIPA
Wataru Nakamura, Yosuke Kaga, Masakazu Fujio, Kenta Takahashi
2017 J jnl
IEEE J. Solid State Circuits
Yusuke Oike, Kentaro Akiyama, Luong D. Hung, Wataru Niitsuma, Akihiko Kato, Mamoru Sato, Yuri Kato, Wataru Nakamura, Hiroshi Shiroshita, Yorito Sakano, Yoshiaki Kitano, Takuya Nakamura, Takayuki Toyama, Hayato Iwamoto, Takayuki Ezaki
2017 J jnl
IEICE Trans. Fundam. Electron. Commun. Comput. Sci.
Wataru Nakamura, Hirosuke Yamamoto, Terence Chan
2016 C conf
ISITA
Wataru Nakamura, Hirosuke Yamamoto, Terence Chan
2016 conf
VLSI Circuits
Yusuke Oike, Kentaro Akiyama, Luong D. Hung, Wataru Niitsuma, Akihiko Kato, Mamoru Sato, Yuri Kato, Wataru Nakamura, Hiroshi Shiroshita, Yorito Sakano, Yoshiaki Kitano, Takuya Nakamura, Takayuki Toyama, Hayato Iwamoto, Takayuki Ezaki
2006 J jnl
NeuroImage
Satoru Yokoyama, Hideyuki Okamoto, Tadao Miyamoto, Kei Yoshimoto, Jungho Kim, Kazuki Iwata, Hyeonjeong Jeong, Shinya Uchida, Naho Ikuta, Yuko Sassa, Wataru Nakamura, Kaoru Horie, Shigeru Sato, Ryuta Kawashima
redb/extractors/js_extractors/scripts/js-xray-runner.js
← Index redb/extractors/js_extractors/scripts/js-xray-runner.js javascript
#!/usr/bin/env node
// Bridge between the Python JS pipeline and @nodesecure/js-x-ray.
//
// Usage: node js-xray-runner.js <path-to-js-file>
//   stdout  one JSON object: {"obfuscator": <name|null>, "warnings": [...]}
//   stderr  human-readable error on failure
//   exit 0  analysis ran (the file may still be benign — see "obfuscator")
//   exit 1  the file could not be read or analysed
//
// Each warning is emitted as {kind, value} so the Python side can tag
// supporting signals (encoded-literal, short-identifiers, suspicious-literal,
// unsafe-stmt) without having to mirror js-x-ray's whole schema.
//
// js-x-ray ≥7 ships as an ES module, which CommonJS `require()` cannot load
// from a `.js` script — the dynamic `import()` below is what makes the
// bridge work without renaming the file to `.mjs` or adding `"type":
// "module"` to package.json (which would break tools that still
// `require()` from this directory).

const fs = require("fs");
const path = require("path");

function fail(msg) {
  process.stderr.write(msg + "\n");
  process.exit(1);
}

async function main() {
  const target = process.argv[2];
  if (!target) fail("usage: js-xray-runner.js <file>");

  let source;
  try {
    source = fs.readFileSync(target, "utf8");
  } catch (e) {
    fail(`read failed: ${e.message}`);
  }

  // The legacy `runASTAnalysis` function is deprecated (removed in v8); the
  // current API is the `AstAnalyser` class. Both produce a result with the
  // same `warnings` shape, so the rest of the bridge is unchanged.
  let AstAnalyser;
  try {
    ({ AstAnalyser } = await import("@nodesecure/js-x-ray"));
  } catch (e) {
    fail(`@nodesecure/js-x-ray not installed (run \`npm install\` in ${path.dirname(__filename)}): ${e.message}`);
  }

  // js-x-ray defaults to module-mode parsing, which rejects scripts that
  // (legally) use reserved words as identifiers, top-level `return`, etc.
  // A lot of real-world JS malware is script-style (WScript/HTA bodies,
  // pasted snippets) — retrying in script mode catches those without
  // pulling in a more lenient parser. Both attempts share the same
  // analyser; only the parse mode flips. If both fail, the original error
  // (module-mode) is reported because that's the more informative one for
  // genuinely broken sources.
  let result;
  const analyser = new AstAnalyser();
  let firstErr;
  try {
    result = await analyser.analyse(source, { module: true });
  } catch (e) {
    firstErr = e;
    try {
      result = await analyser.analyse(source, { module: false });
    } catch (e2) {
      fail(`js-x-ray analysis failed: ${firstErr.message}`);
    }
  }

  const warnings = (result.warnings || []).map((w) => ({
    kind: w.kind,
    value: w.value !== undefined ? w.value : null,
  }));

  // js-x-ray flags the obfuscator family in a warning whose kind is
  // "obfuscated-code" and whose value names the family (jsfuck, obfuscator.io,
  // freejsobfuscator, morse, jjencode, ...). Absent => not detected.
  const obfWarning = warnings.find((w) => w.kind === "obfuscated-code");
  const obfuscator = obfWarning ? obfWarning.value : null;

  // js-x-ray runs its own AST internally with a modern parser, so its
  // identifier-length average is the only path the Python pipeline has to
  // that signal on ES2015+ sources — pyjsparser is ES5.1-only and silently
  // drops to 0 the moment it hits destructuring, classes, optional chaining,
  // etc. Surfacing this lets the heuristic's `avg_identifier_length<2`
  // strong signal fire on real obfuscator.io output. `null` when the value
  // is missing or non-numeric (defensive — older js-x-ray builds may differ).
  const idsLengthAvg =
    typeof result.idsLengthAvg === "number" && !Number.isNaN(result.idsLengthAvg)
      ? result.idsLengthAvg
      : null;

  process.stdout.write(JSON.stringify({ obfuscator, warnings, idsLengthAvg }));
}

main().catch((e) => fail(e.message || String(e)));