/** * Tencent Turing Captcha TDC Deep Proxy Runtime Probe * --------------------------------------------------- * 依据 AGENTS.md §4.3 与 §2.3 规范,通过深度 Proxy 探针拦截并记录 TDC 执行时 * 实际读取的全部环境属性清单与调用时序,彻底告别盲目补环境。 */ const fs = require("fs"); const path = require("path"); const vm = require("vm"); function createDeepProxy(target, prefix, logSet) { return new Proxy(target, { get(obj, prop, receiver) { if (typeof prop === "symbol" || prop === "inspect" || prop.startsWith("_")) { return Reflect.get(obj, prop, receiver); } const BUILTIN_TYPES = new Set([ "String", "Number", "Boolean", "Array", "Object", "Function", "RegExp", "Date", "Math", "JSON", "Error", "TypeError", "Uint8Array", "Uint8ClampedArray", "parseInt", "parseFloat", "encodeURIComponent", "decodeURIComponent", "setTimeout", "clearTimeout", "setInterval", "clearInterval" ]); if (BUILTIN_TYPES.has(String(prop))) { return Reflect.get(obj, prop, receiver); } const fullName = `${prefix}.${String(prop)}`; logSet.add(`GET: ${fullName}`); const val = Reflect.get(obj, prop, receiver); if (val !== null && typeof val === "object" && !(val instanceof RegExp)) { return createDeepProxy(val, fullName, logSet); } if (typeof val === "function") { const fnWrapper = function (...args) { logSet.add(`CALL: ${fullName}(${args.map((a) => JSON.stringify(a)).join(", ")})`); return val.apply(this === receiver ? obj : this, args); }; fnWrapper.prototype = val.prototype; return fnWrapper; } return val; }, set(obj, prop, value, receiver) { const fullName = `${prefix}.${String(prop)}`; logSet.add(`SET: ${fullName}`); return Reflect.set(obj, prop, value, receiver); }, }); } function probeTdc(tdcFilePath, options = {}) { const tdcCode = fs.readFileSync(tdcFilePath, "utf-8"); const accesses = new Set(); // Mock Realistic Environment (based on macOS Chrome success capture) const realScreen = { width: options.screenWidth || 2560, height: options.screenHeight || 1440, availWidth: options.screenWidth || 2560, availHeight: options.screenAvailHeight || 1345, colorDepth: 24, pixelDepth: 24, }; const realNavigator = { userAgent: options.userAgent || "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/155.0.0.0 Safari/537.36", platform: "MacIntel", languages: ["zh-CN", "zh", "fr", "de", "en"], language: "zh-CN", hardwareConcurrency: 10, cookieEnabled: true, }; const fakeCanvas = { getContext: (type) => { if (type.includes("webgl")) { return { getExtension: (name) => { if (name === "WEBGL_debug_renderer_info") { return { UNMASKED_VENDOR_WEBGL: 37445, UNMASKED_RENDERER_WEBGL: 37446 }; } return null; }, getParameter: (param) => { if (param === 37445) return "Google Inc. (Apple)"; if (param === 37446) { return "ANGLE (Apple, ANGLE Metal Renderer: Apple M4, Unspecified Version)"; } return ""; }, getSupportedExtensions: () => ["WEBGL_debug_renderer_info"], }; } return { getImageData: () => ({ data: new Uint8ClampedArray(16) }), toDataURL: () => "data:image/png;base64,GgoAAAANSUhEUgAAASwAAACWCAYAAATf3v8bh+ryWcfSBSLkmN3N1PQinPL7Bi3TG0qE2CogAAAABJRU5ErkJggg==", }; }, toDataURL: () => "data:image/png;base64,GgoAAAANSUhEUgAAASwAAACWCAYAAATf3v8bh+ryWcfSBSLkmN3N1PQinPL7Bi3TG0qE2CogAAAABJRU5ErkJggg==", }; const fakeDoc = { referrer: options.referrer || "https://1ms.run/console/personal/benefits/check-in", characterSet: "UTF-8", documentElement: { clientWidth: 360, clientHeight: 360 }, createElement: (tag) => { if (tag.toLowerCase() === "canvas") return fakeCanvas; return { appendChild: () => {}, style: {}, setAttribute: () => {} }; }, getElementById: () => null, cookie: "", }; const fakeLoc = { href: "https://turing.captcha.gtimg.com/1/template/drag_ele.html?rand=1519713624347", hostname: "turing.captcha.gtimg.com", protocol: "https:", }; const baseWindow = { screen: realScreen, navigator: realNavigator, document: fakeDoc, location: fakeLoc, innerWidth: 360, innerHeight: 360, devicePixelRatio: 2, Date: Date, Math: Math, String: String, Number: Number, Boolean: Boolean, Array: Array, Object: Object, Function: Function, RegExp: RegExp, JSON: JSON, Error: Error, TypeError: TypeError, Uint8Array: Uint8Array, Uint8ClampedArray: Uint8ClampedArray, parseInt: parseInt, parseFloat: parseFloat, encodeURIComponent: encodeURIComponent, decodeURIComponent: decodeURIComponent, setTimeout: setTimeout, clearTimeout: clearTimeout, setInterval: setInterval, clearInterval: clearInterval, addEventListener: () => {}, removeEventListener: () => {}, }; // Attach window.top to simulate running in an iframe baseWindow.top = {}; baseWindow.window = baseWindow; baseWindow.self = baseWindow; const proxiedWindow = createDeepProxy(baseWindow, "window", accesses); // Execute in isolated V8 Context const sandbox = vm.createContext(proxiedWindow); console.log(`Running TDC inside Semantic Probe...`); vm.runInContext(tdcCode, sandbox); console.log(`TDC loaded. Calling TDC.getData(!0)...`); let collect = null; let eks = null; if (sandbox.TDC && sandbox.TDC.getData) { collect = sandbox.TDC.getData(true); if (sandbox.TDC.getInfo) { const info = sandbox.TDC.getInfo(); eks = info ? info.info : null; } } const result = { success: !!collect, collect: collect, eks: eks, collectLen: collect ? collect.length : 0, collectPreview: collect ? collect.slice(0, 80) : null, eksPreview: eks ? eks.slice(0, 80) : null, accessCount: accesses.size, accesses: Array.from(accesses).sort(), }; return result; } if (require.main === module) { const tdcFile = process.argv[2] || "tcaptcha/core_js/tdc_sample.js"; const report = probeTdc(tdcFile); console.log("\n--- TDC Execution Result ---"); console.log(`Success: ${report.success}`); console.log(`Collect Length: ${report.collectLen}`); console.log(`Collect Preview: ${report.collectPreview}`); console.log(`EKS Preview: ${report.eksPreview}`); console.log(`Total Environment Accesses: ${report.accessCount}`); console.log("\n--- Top 35 Environment Accesses Logged by Probe ---"); report.accesses.slice(0, 35).forEach((a) => console.log(a)); const outReport = tdcFile.replace(/\.js$/, ".probe_report.json"); fs.writeFileSync(outReport, JSON.stringify(report, null, 2), "utf-8"); console.log(`\nDetailed probe report written to ${outReport}`); } module.exports = { probeTdc };