// 修正跨 realm 陷阱:沙箱不注入外层内置,让 context 自带 intrinsic。 const fs = require("fs"), vm = require("vm"), path = require("path"); const src = fs.readFileSync(path.join("out/captcha_net", "js_07_rm_static_captcha_js_encrypt_ee7d2a41_js.js"), "utf-8"); // 只放非内置的宿主能力;String/Object/Promise/Uint8Array 等由 context 自己生成 const sandbox = { console, setTimeout, clearTimeout, setImmediate, queueMicrotask, Buffer, btoa: (s) => Buffer.from(s, "binary").toString("base64"), atob: (s) => Buffer.from(s, "base64").toString("binary"), }; vm.createContext(sandbox); // 此时 sandbox 拥有自己的 intrinsic (String/Object/Uint8Array/Promise...) sandbox.window = sandbox; sandbox.self = sandbox; sandbox.global = sandbox; try { vm.runInContext(src, sandbox, { filename: "encrypt.js", timeout: 30000 }); } catch (e) { console.log("[run-err]", e.message); } const f = sandbox.webpackJsonp[0][1]["088e"]; const rq = (id) => id === "b639" ? { Buffer } : id === "dd40" ? (x) => x : {}; const m = { exports: {} }; try { f(m, m.exports, rq); } catch (e) { console.log("[factory-err]", e.message); } const Jose = sandbox.Jose; const j = (typeof Jose === "function") ? new Jose() : Jose; console.log("Jose ok:", !!j, "call:", typeof j.call); // 在沙箱内构造 Uint8Array(同 realm) const KEY = "c7b645db-65e8-401f-b38c-4c07c5fff247"; vm.runInContext('(function(){globalThis.__makeU8=function(s){return new Uint8Array(Array.prototype.map.call(s,c=>c.charCodeAt(0)));};globalThis.__b64=function(u){var s="";for(var i=0;i { if (sandbox.__done || Date.now() - t0 > 4000) { clearInterval(iv); console.log(`${label}: done=${sandbox.__done} res=${String(sandbox.__res).slice(0, 110)}`); } }, 50); } runInBox("$encrypt U8+key", "$encrypt", "__makeU8('{\"a\":1}')"); setTimeout(() => runInBox("$encrypt str+key", "$encrypt", "'{\"a\":1}'"), 4500);