问题场景
想知道 window.__VINFO_DATA__.proxyhttp 在哪段代码中被读取,但不知道从哪里打断点。
方法一:Object.defineProperty getter(最直接)
在 Console 执行:
const oldValue = window.__VINFO_DATA__.proxyhttp;
Object.defineProperty(window.__VINFO_DATA__, "proxyhttp", {
configurable: true,
enumerable: true,
get() {
debugger; // 读取时触发断点
console.trace("proxyhttp get"); // 打印调用栈
return oldValue;
},
set(v) {
console.log("proxyhttp set", v);
}
});
之后任何代码执行 window.__VINFO_DATA__.proxyhttp 时都会暂停在 debugger,可以在调用栈里找到来源。
方法二:Proxy 监听指定属性
如果属性值后续会变化,用 Proxy 更灵活:
window.__VINFO_DATA__ = new Proxy(window.__VINFO_DATA__, {
get(target, prop, receiver) {
if (prop === "proxyhttp") {
debugger;
console.trace("proxyhttp get");
}
return Reflect.get(target, prop, receiver);
},
set(target, prop, value, receiver) {
if (prop === "proxyhttp") {
console.log("proxyhttp set", value);
}
return Reflect.set(target, prop, value, receiver);
}
});
Reflect.get/set 保持原始行为,不破坏已有逻辑。
方法三:监控所有属性访问
不知道哪个属性会被访问时,监听整个对象:
window.__VINFO_DATA__ = new Proxy(window.__VINFO_DATA__, {
get(target, prop, receiver) {
console.log("GET", prop);
return Reflect.get(target, prop, receiver);
}
});
会打印所有被读取的属性名,帮助定位目标属性。
检查已有描述符
在 hook 之前先检查属性的描述符,避免覆盖已有 getter:
Object.getOwnPropertyDescriptor(window.__VINFO_DATA__, "proxyhttp")
// {value: "...", writable: true, enumerable: true, configurable: true}
// 或者
// {get: f, set: f, enumerable: true, configurable: true}
如果已经有 getter,需要先保存原 getter 再包装:
const desc = Object.getOwnPropertyDescriptor(window.__VINFO_DATA__, "proxyhttp");
const originalGet = desc.get;
Object.defineProperty(window.__VINFO_DATA__, "proxyhttp", {
...desc,
get() {
debugger;
return originalGet ? originalGet.call(this) : desc.value;
}
});
适用场景
| 场景 | 推荐方案 |
|---|---|
| 监听特定属性读取 | Object.defineProperty getter |
| 属性值会动态变化 | Proxy |
| 不知道具体属性名 | 全对象 Proxy GET 打印 |
| 属性已有 getter | 保存原 getter 后包装 |
这类调试技巧常用于逆向分析第三方网页、油猴脚本开发和 SDK 调试。
