diff --git a/tools/tdc_keytrace.js b/tools/tdc_keytrace.js index 7161294..f0488a0 100644 --- a/tools/tdc_keytrace.js +++ b/tools/tdc_keytrace.js @@ -87,7 +87,20 @@ globalThis.__SCAN = function (E) { } catch (e) { /* ignore */ } }; -src = src.replace(needle, "M=(globalThis.__PC.push(H),globalThis.__SCAN(E),G[z[H++]]())"); +const TARGET_PC = parseInt(process.env.TARGET_PC || "9109", 10); +globalThis.__XTEA = null; +globalThis.__HOOK = function (H, E) { + if (H === TARGET_PC && !globalThis.__XTEA) { + const cell = E[7]; + globalThis.__XTEA = { + at: H, + r7_cell: (Array.isArray(cell) ? JSON.stringify(cell).slice(0, 400) : String(cell)), + r7_val: (cell && typeof cell[0] === "object") ? JSON.stringify(cell[0]).slice(0, 400) : String(cell && cell[0]), + prev_pcs: globalThis.__PC.slice(-300), + }; + } +}; +src = src.replace(needle, "M=(globalThis.__PC.push(H),globalThis.__HOOK(H,E),G[z[H++]]())"); globalThis.window = globalThis; globalThis.document = { cookie: "", referrer: "", createElement: () => ({ getContext: () => null, toDataURL: () => "", style: {} }), getElementById: () => null }; @@ -111,7 +124,8 @@ try { process.stderr.write("[keytrace] 调用 TDC.getData(true) 驱动...\n"); globalThis.__PC.push(-1); const c = globalThis.TDC.getData(true); - process.stderr.write(`[keytrace] getData 返回长度=${c ? c.length : 0}\n`); + globalThis.__COLLECT = c; + process.stderr.write(`[keytrace] getData 返回长度=${c ? c.length : 0} 头部=${String(c).slice(0,90)}\n`); } else { process.stderr.write("[keytrace] 未找到 TDC.getData\n"); } @@ -122,4 +136,9 @@ let out = globalThis.__HITS[0] || null; if (out) { process.stderr.write(`[keytrace] 命中寄存器 r${out.reg}, 密钥=${JSON.stringify(out.key)}, ASCII=${out.ascii}, 命中时 PC=@${out.pc}\n`); } -process.stdout.write(JSON.stringify(out)); +const pcs=globalThis.__PC; +const uniq=new Set(pcs); +const inRange=[...uniq].filter(x=>x>=9000&&x<=9600); +process.stdout.write(JSON.stringify({ key_hit: out, xtea: globalThis.__XTEA, + pc_total: pcs.length, pc_unique: uniq.size, min: Math.min(...pcs), max: Math.max(...pcs), + has_9109: uniq.has(9109), range9000_9600: inRange.sort((a,b)=>a-b).slice(0,40) })); diff --git a/tools/tdc_probe.js b/tools/tdc_probe.js index ae1b76b..7ac51a5 100644 --- a/tools/tdc_probe.js +++ b/tools/tdc_probe.js @@ -80,7 +80,17 @@ function createVirtualDate(initialTime) { } function probeTdc(tdcFilePath, options = {}) { - const tdcCode = options.tdcCode || fs.readFileSync(tdcFilePath, "utf-8"); + let tdcCode = options.tdcCode || fs.readFileSync(tdcFilePath, "utf-8"); + + // ---- 神谕钩子(自包含, 写在沙箱内的 window 上): 记录 PC, 并在进入 XTEA 例程时 dump 密钥寄存器 ---- + const TARGET_PC = parseInt(process.env.XTEA_PC || "9109", 10); + const HOOK = "window.__PC=window.__PC||[];window.__H=function(H,E){window.__PC.push(H);" + + "if(H===" + TARGET_PC + "&&!window.__XT){var c=E[7];window.__XT={at:H," + + "r7:Array.isArray(c)?JSON.stringify(c).slice(0,300):String(c),prev:window.__PC.slice(-260)};}};"; + const NEEDLE = "M=G[z[H++]]()"; + if (tdcCode.includes(NEEDLE)) { + tdcCode = HOOK + tdcCode.replace(NEEDLE, "M=(window.__H(H,E),G[z[H++]]())"); + } const accesses = new Set(); let mouseHandler = null; @@ -295,6 +305,8 @@ function probeTdc(tdcFilePath, options = {}) { eksPreview: eks ? eks.slice(0, 80) : null, accessCount: accesses.size, accesses: Array.from(accesses).sort(), + __pc_len: (sandbox.__PC || []).length, + __xtea: sandbox.__XT || null, }; return result;