绕过断点
调试 JS 代码时,单步执行(F11)可跟踪所有操作。例如这段代码,每次调用 alert 时都会被断住:
debugger
alert(11)
alert(22)
alert(33)
alert(44)
有没有什么办法能让单步执行失效,一次执行多个操作?
事实上有一些巧妙的办法。例如通过数组回调执行这些 alert 函数:
debugger
[11, 22, 33, 44].forEach(alert)
这样只有 forEach 之前和之后会被断住,中间所有 alert 调用都不会被断住。
由此可见,通过 内置回调 执行 原生函数,调试器是无法断住的!
利用这个特性,我们可将一些重要的操作隐藏起来,从而能在调试者眼皮下悄悄执行。
应用案例
主流浏览器的调试器允许拦截特定事件,例如触发 mousemove 时断点;
addEventListener('mousemove', e => {
console.log(e)
})
因此调试者很容易找到事件回调函数,从而分析相应的处理逻辑。
如何防止事件回调被断点?这就需要前面讲解的黑科技了。我们对上述代码稍微修改,将自己的回调函数改成原生函数:
addEventListener('mousemove', console.log)
这时,每次触发 mousemove 事件都不会被断住!
然而现实中的回调逻辑远比 console.log 复杂,又该如何应用?
事实上我们可以做一些调整,将事件的回调逻辑变得足够简单,简单到只需一个操作 —— 保存结果:
const Q = []
addEventListener('mousemove', Q.push.bind(Q))
由于调用函数 bind 方法后返回的新函数,其实是原生的:
function A() {}
A.bind(window) + '' // "function () { [native code] }"
而 Q.push 本身也是原生函数,因此它们两都是原生函数。
同时 addEventListener 执行回调也属于内置行为,因此整个操作都是原生函数在执行,没有任何自己的代码可供调试器断点!
本站声明:
1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/293445.html