0%

调试与反调试

调试与反调试

相信各位如果从事爬虫开发、反爬虫开发、逆向工程师及相关岗位的开发,一定逃不开调试、反调试。那调试与反调是什么呢?以下为浏览器为例

调试:自然就是为了分析获取某关键加密参数,便对于目标网站的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. 拦截:

预防调试

主要目的为防止调试者继续或者进入下一步调试,常见的方式有引入僵尸代码、控制流等方式。

阻断调试

较于拦截,阻断调试更加简单粗暴。常常伴随着无限循环。常见的实现方式有

1
2
3
4
5
6
7
# while
while (ture)
while (大于0的数)
while (!![])

# for
for (; ;)

递归

多函数死循环互调等实现内存爆破

破坏调试

相对于阻断调试,会更加极端的手段,一方面对调试者信息进行采集、攻击调试者。例如删除文件、重置电脑、甚至释放病毒等

总结

本节详细了解了检测与反调试,检测核心原理为区分代码运行环境是否一致、是否合理从而区分为正常运行还是调试运行。检测到后进行反调试,反调试一般主要体现在预防、阻断、破坏。而绕过的方案自然从检测入手,模拟环境、模拟运行时,从而进行绕过。