()
| 290 | // --- install hooks ---------------------------------------------------------- |
| 291 | const hooks = []; |
| 292 | function install() { |
| 293 | const targetMods = []; |
| 294 | let installed = 0; |
| 295 | |
| 296 | for (const spec of CONFIG.targets) { |
| 297 | const addr = resolveTarget(spec); |
| 298 | if (!addr) { console.log(`${C.red}[fstalk] cannot resolve target: ${spec}${C.reset}`); continue; } |
| 299 | const modName = targetModuleName(spec); |
| 300 | if (modName) targetMods.push(modName); |
| 301 | const scope = scopeSetFor(modName); |
| 302 | const label = resolve(addr).text; |
| 303 | |
| 304 | try { |
| 305 | const h = Interceptor.attach(addr, { |
| 306 | onEnter(args) { |
| 307 | if (CONFIG.maxCalls && callsSeen >= CONFIG.maxCalls) return; |
| 308 | callsSeen++; |
| 309 | const tid = Process.getCurrentThreadId(); |
| 310 | let argStr = ""; |
| 311 | if (CONFIG.logArgs > 0) { |
| 312 | const parts = []; |
| 313 | for (let i = 0; i < CONFIG.logArgs; i++) { |
| 314 | try { parts.push(`a${i}=${args[i]}`); } catch (e) {} |
| 315 | } |
| 316 | argStr = " " + parts.join(" "); |
| 317 | } |
| 318 | console.log(`${C.green}[call+]${C.reset} ${label} ${C.dim}#${tid} @+${tms()}ms${C.reset}${C.dim}${argStr}${C.reset}`); |
| 319 | beginFollow(tid, scope); |
| 320 | }, |
| 321 | onLeave(retval) { |
| 322 | const tid = Process.getCurrentThreadId(); |
| 323 | const st = endFollow(tid); |
| 324 | const cnt = st ? ` events=${st.count}${st.dropped ? ` dropped=${st.dropped}` : ""}` : ""; |
| 325 | const ret = CONFIG.logRet ? ` ret=${retval}` : ""; |
| 326 | console.log(`${C.red}[call-]${C.reset} ${label} ${C.dim}#${tid}${ret}${cnt}${C.reset}`); |
| 327 | }, |
| 328 | }); |
| 329 | hooks.push(h); |
| 330 | installed++; |
| 331 | console.log(`${C.green}[fstalk] hooked${C.reset} ${label} ${C.dim}(${spec})${C.reset}`); |
| 332 | } catch (e) { |
| 333 | console.log(`${C.red}[fstalk] attach failed for ${spec}: ${e}${C.reset}`); |
| 334 | } |
| 335 | } |
| 336 | |
| 337 | if (installed) excludeAllButTargetsOnce(targetMods); |
| 338 | console.log(`${C.dim}[*] function-stalker ready. hooked ${installed}/${CONFIG.targets.length}, events={${Object.keys(CONFIG.trace).filter((k) => CONFIG.trace[k]).join(",")}}. type ${C.reset}${C.green}help()${C.reset}`); |
| 339 | } |
| 340 | |
| 341 | // --- REPL helpers ----------------------------------------------------------- |
| 342 | function detachAll() { |
no test coverage detected