调试与反调试
相信各位如果从事爬虫开发、反爬虫开发、逆向工程师及相关岗位的开发,一定逃不开调试、反调试。那调试与反调是什么呢?以下为浏览器为例
调试:自然就是为了分析获取某关键加密参数,便对于目标网站的JS进行分析。
反调试:为了参数更加安全,更加难以破解。在合适处增加障碍增强调试难度
简单来说调试就是为了获取对应的加密参数,而反调试是为了不那么容易调试,增加调试难度。
反调试可以分为调试检测、调试陷阱,而反反调试是伪装,是绕过。
反调试常见手段
反调试无论具体实现何种方法进行反调试 如无限debugger、内存爆破、投毒、删文件、脏话等。这都离不开一入口—— *
调试检测*
,反过来思考反调试是为了区分正常用户与开发者人员都一种方式,那么如果可以检测到开发者调试那么就可以对其进行相关的操作。
调试检测
调试检测的方案有很多,只要一经出发便可反制调试者。常用的检测方案如下
控制台检测
检测控制台检测的原理
隐式的调用元素id
隐式的调用RegExp的tostring方法
console,打开控制台console运行,否则不执行
浏览器窗口内外高度差
打开内置的chrome devtools 将造成高度差不一致
格式化检测
格式化检测也很实现原理也很简单,调用RegExp匹配相关部分代码
一般情况下目标服务器下发的JS为经过压缩。而调试者为了便于调试一般会对代码进行格式化,一旦检测点被格式化便可被RegExp检测
Hook检测
函数检测:采集调用 toString 方法对内容进行校验(伪造 toString 方法即可绕过)
对象检测:通过 Object.defineProperty
方法修改属性是不可更改的(可复写 debugger 即可)
浏览器与浏览器指纹检测
浏览器与浏览器指纹检测可检测的范围更广,更细致。具体请参考浏览器的相关api。
其他
调用时间差检测
调试离不开debugger、断点,调用时间过长可视为被调试
栈检测(在浏览器中可以使用caller获取调用栈)
调试会打乱原有的调用栈
tostings检测
调试的时候难免遇到函数,习惯性的将鼠标放置在上面。hook Function toString可实现检测
一切与“正常”执行相悖的都可作为检测点,也就是经常说的埋雷
蜜罐
蜜罐 也就是咱们所常听见的蜜罐。简单来说就是给予或引导调试者进入虚假的环境
蜜罐相对较于以上被动的检测拥有更多的灵活性,相对来说更加主动,更加激进。且蜜罐更一种实现思路,具体实现具体情况具体分析
调试陷阱
当检测到开发者正在调试,那么下一步就是抵御。实现思路一般有三种
- 拦截:
预防调试
主要目的为防止调试者继续或者进入下一步调试,常见的方式有引入僵尸代码、控制流等方式。
阻断调试
较于拦截,阻断调试更加简单粗暴。常常伴随着无限循环。常见的实现方式有
1 | # |
递归
多函数死循环互调等实现内存爆破
破坏调试
相对于阻断调试,会更加极端的手段,一方面对调试者信息进行采集、攻击调试者。例如删除文件、重置电脑、甚至释放病毒等
总结
本节详细了解了检测与反调试,检测核心原理为区分代码运行环境是否一致、是否合理从而区分为正常运行还是调试运行。检测到后进行反调试,反调试一般主要体现在预防、阻断、破坏。而绕过的方案自然从检测入手,模拟环境、模拟运行时,从而进行绕过。