Jack Li

24 papers A 4B 3Misc 2Journal 1Unranked 13
YearRankTypeTitle / Venue / Authors
2017 A conf
ICDCS
Tao Zhu, Jack Li, Josh Kimball, Junhee Park, Chien-An Lai, Calton Pu, Qingyang Wang
2017 A conf
ICDCS
Calton Pu, Joshua Kimball, Chien-An Lai, Tao Zhu, Jack Li, Junhee Park, Qingyang Wang, Deepal Jayasinghe, Pengcheng Xiong, Simon Malkowski, Qinyi Wu, Gueyoung Jung, Younggyun Koh, Galen S. Swint
2016
Jack Li
2016 B conf
CLOUD
Jack Li, Calton Pu, Yuan Chen, Daniel Gmach, Dejan S. Milojicic
2016 B conf
CLOUD
Junhee Park, Qingyang Wang, Jack Li, Chien-An Lai, Tao Zhu, Calton Pu
2015 A conf
Middleware
Jack Li, Calton Pu, Yuan Chen, Vanish Talwar, Dejan S. Milojicic
2014 conf
IEEE CLOUD
Chien-An Lai, Qingyang Wang, Josh Kimball, Jack Li, Junhee Park, Calton Pu
2014 conf
TRIOS
Qingyang Wang, Yasuhiko Kanemasa, Jack Li, Chien-An Lai, Chien-An Cho, Yuji Nomura, Calton Pu
2014 conf
IEEE CLOUD
Jack Li, Qingyang Wang, Chien-An Lai, Junhee Park, Daisaku Yokoyama, Calton Pu
2014 J jnl
IEEE Trans. Serv. Comput.
Deepal Jayasinghe, Simon Malkowski, Jack Li, Qingyang Wang, Zhikui Wang, Calton Pu
2013 conf
IEEE CLOUD
Qingyang Wang, Yasuhiko Kanemasa, Jack Li, Deepal Jayasinghe, Toshihiro Shimizu, Masazumi Matsubara, Motoyuki Kawaba, Calton Pu
2013 A conf
ICDCS
Qingyang Wang, Yasuhiko Kanemasa, Jack Li, Deepal Jayasinghe, Toshihiro Shimizu, Masazumi Matsubara, Motoyuki Kawaba, Calton Pu
2013 conf
TRIOS@SOSP
Qingyang Wang, Yasuhiko Kanemasa, Jack Li, Chien-An Lai, Masazumi Matsubara, Calton Pu
2013 conf
BigData Congress
Jack Li, Qingyang Wang, Deepal Jayasinghe, Junhee Park, Tao Zhu, Calton Pu
2013 conf
IEEE SCC
Yasuhiko Kanemasa, Qingyang Wang, Jack Li, Masazumi Matsubara, Calton Pu
2013 conf
IEEE SCC
Junhee Park, Qingyang Wang, Deepal Jayasinghe, Jack Li, Yasuhiko Kanemasa, Masazumi Matsubara, Daisaku Yokoyama, Masaru Kitsuregawa, Calton Pu
2012 conf
IEEE CLOUD
Deepal Jayasinghe, Galen S. Swint, Simon Malkowski, Jack Li, Qingyang Wang, Junhee Park, Calton Pu
2012 Misc conf
IRI
Junhee Park, Eva K. Lee, Qingyang Wang, Jack Li, Qifeng Lin, Calton Pu
2012 conf
IEEE MS
Pengcheng Xiong, Jialie Shen, Qingyang Wang, Deepal Jayasinghe, Jack Li, Calton Pu
2012 Misc conf
NSDI
Jiaxing Zhang, Hucheng Zhou, Rishan Chen, Xuepeng Fan, Zhenyu Guo, Haoxiang Lin, Jack Li, Wei Lin, Jingren Zhou, Lidong Zhou
2012 conf
IEEE SCC
Jack Li, Qingyang Wang, Deepal Jayasinghe, Simon Malkowski, Pengcheng Xiong, Calton Pu, Yasuhiko Kanemasa, Motoyuki Kawaba
2012 B conf
SRDS
Qingyang Wang, Yasuhiko Kanemasa, Jack Li, Deepal Jayasinghe, Motoyuki Kawaba, Calton Pu
2011 conf
ICAC
Simon Malkowski, Markus Hedwig, Jack Li, Calton Pu, Dirk Neumann
2011 conf
IEEE CLOUD
Deepal Jayasinghe, Simon Malkowski, Qingyang Wang, Jack Li, Pengcheng Xiong, Calton Pu
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)));