James Cunningham

35 papers A* 1B 2C 1Misc 1Journal 12Unranked 18
YearRankTypeTitle / Venue / Authors
2025 J jnl
IEEE Trans. Control. Syst. Technol.
Tamás G. Molnár, Suresh K. Kannan, James Cunningham, Kyle Dunlap, Kerianne L. Hobbs, Aaron D. Ames
2025 J jnl
ACM Trans. Access. Comput.
Alex Lucas, James Cunningham, Jacob Harrison, Franziska Schroeder, Andrew P. McPherson
2024 J jnl
CoRR
Tamás G. Molnár, Suresh K. Kannan, James Cunningham, Kyle Dunlap, Kerianne L. Hobbs, Aaron D. Ames
2024 J jnl
CoRR
James Cunningham, Conrad S. Tucker
2024 J jnl
Expert Syst. Appl.
James Cunningham, Conrad S. Tucker
2023 J jnl
IEEE Trans. Smart Grid
James Cunningham, Alexander J. Aved, David Ferris, Philip Morrone, Conrad S. Tucker
2022 B conf
COMPSAC
Akshay Kumar Dileep, Ajay Bansal, James Cunningham
2022 conf
MIE
James Cunningham, Nigel Davies, Sarah Devaney, Søren Holm, Mike Harding, Victoria Neumann, John D. Ainsworth
2022 B conf
ICPR
James Cunningham, Jim Davis, Kyle Tarplee, Juan Vasquez
2021 J jnl
Frontiers Blockchain
James Cunningham, Gail Davidge, Nigel Davies, Sarah Devaney, Søren Holm, Mike Harding, Gary Leeming, Victoria Neumann, John D. Ainsworth
2021 J jnl
Internet Res.
Nikolaos Goumagias, Jason Whalley, Özge Dilaver, James Cunningham
2021 conf
AIED (2)
James Cunningham, Raktim Mukhopadhyay, Rishabh Ranjit Kumar Jain, Jeffrey Matayoshi, Eric Cosyn, Hasan Uzun
2021 J jnl
Inf.
Sheran Dass, Kevin Gary, James Cunningham
2020 J jnl
J. Comput. Inf. Sci. Eng.
Christian E. López, James Cunningham, Omar M. Ashour, Conrad S. Tucker
2019 conf
ISVC (2)
Aswathnarayan Radhakrishnan, James Cunningham, Jim Davis, Roman Ilin
2019 J jnl
CoRR
Diego Arenas, Jon Atkins, Clare Austin, David Beavan, Alvaro Cabrejas Egea, Stephen Carlysle-Davies, Ian Carter, Rob Clarke, James Cunningham, Tom Doel, Oliver Forrest, Evelina Gabasova, James Geddes, James Hetherington, Radka Jersakova, Franz J. Király, Catherine Lawrence, Jules Manser, Martin T. O'Reilly, James Robinson, Helen Sherwood-Taylor, Serena Tierney, Catalina A. Vallejos, Sebastian J. Vollmer, Kirstie J. Whitaker
2018 conf
EMBC
James Cunningham, Yi Zheng, Thyagarajan Subramanian, Mohamed Almekkawy
2018 conf
ISBI
James Cunningham, Yi Zheng, Thyagarajan Subramanian, Mohamed Almekkawy
2018 conf
BioRob
James Cunningham, Anita Hapsari, Pierre Guilleminot, Ali Shafti, A. Aldo Faisal
2018 J jnl
CoRR
James Cunningham, Anita Hapsari, Pierre Guilleminot, Ali Shafti, A. Aldo Faisal
2017 conf
NER
Mohamed Almekkawy, James Cunningham, Yi Song, Hadeel Albahar, Thyagarajan Subramanian
2017 conf
ISBI
James Cunningham, Justice Lee, Thyagarajan Subramanian, Mohamed Almekkawy
2016 conf
SIGGRAPH ASIA Computer Animation Festival
James Cunningham, Oliver Hilbert
2016 conf
SIGGRAPH Computer Animation Festival
James Cunningham
2015 conf
HCI (5)
Zach Roberts, Blake Arnsdorff, James Cunningham, Dan Chiappe
2015 C conf
ISTAS
Fiona Edwards Murphy, Michelle Donovan, James Cunningham, Tristan Jezequel, Enrique García, Alex Jaeger, John C. McCarthy, Emanuel M. Popovici
2014 conf
SIGGRAPH ASIA Computer Animation Festival
James Cunningham
2014 conf
SIGGRAPH ASIA Computer Animation Festival
James Cunningham
2013 conf
SIGGRAPH Computer Animation Festival
James Cunningham
2012 conf
SIGGRAPH Computer Animation Festival
James Cunningham
2011 conf
SIGGRAPH Computer Animation Festival
James Cunningham
2011 conf
SIGGRAPH Computer Animation Festival
James Cunningham
2010 A* conf
SIGGRAPH ASIA (Computer Animation Festival)
Oliver Hilbert, Leon Woud, James Cunningham
2005 conf
Bled eConference
James Cunningham
1998 Misc conf
SIGUCCS
James Cunningham, Bryan Lubbers
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)));