🕒

对抗调试干扰策略与实战

无限Debugger

注意: 本文探究的所有情况都是无限debugger在加密逻辑之前。因为无限debugger在加密逻辑之后不用管

1. 简单介绍

无限debugger,还有一个非常靓丽的名字。叫debugger地狱
最关键的一点: 无限debugger不可能无限,否则浏览器会卡死
实现debugger的方案: Function,关键字,eval制作虚拟机
共分为三种模式
  1. 不可混淆
debugger;
  1. [可混淆]
eval("debugger;")
  1. [可重度混淆]
Function("debugger").call()/apply()/bind() xxx.constructor("debugger").call("action") Function.constructor("debugger").call("action") (function(){return !![];}["constructor"]("debugger")["call"]("action")) eval('(function() {}["constructor"]("debugger")["call"]("action"));')
 
三种方式可能有交又和融合,迄今为止没有遇到过第四种情况
无限Debugger 只是很频繁的执行Debugger 而不是真正意义的无限
 
简单实现一个所谓的无限Debugger
function a(){debugger;} setInterval(a,5000)

2. 如何解决无限Debugger?

  1. 重写setInterval方法 (业务代码和 setInterval 有关时)
    1. setInterval_back = setInterval setInterval = function(a, b){ if (a.toString().indexOf('debugger')==-1){ return setInterval_back(a,b) } }
      但是会有一个问题 也就是hook的问题
       
  1. 置空setInterval 方法(业务代码和 setInterval 无关时)
    1. setInterval= function(){}
 
  1. 注入hook脚本
    1. Function层面解决Debugger
      代码1:
      Function.prototype.constructor = function(){ if (arguments==="debugger"){} else{ return Function.prototype.constructor_bc.apply(this,arguments) } }
      代码2:
      Function.prototype.__constructor_back = Function.prototype.constructor; Function.prototype.constructor = function() { if(arguments && typeof arguments[0]==='string'){ //alert("new function: "+ arguments[0]); if("debugger" === arguments[0]){ //arguments[0]="console.log(\"anti debugger\");"; //arguments[0]=";"; return } } return Function.prototype.__constructor_back.apply(this,arguments); }
  1. 本地替换JS
    1. 用 fiddler Autoresponse 删掉 debugger
    2. 浏览器开发者工具替换修改js(Sources面板 --> Overrides)
  1. 手动过掉Debugger
    1. 如果是关键字型的debugger 可以右键 never
 
 

3. 总结

  1. 如果是 Function 原理的 debugger,可以重写 函数构造器
  1. 如果是关键字型的debugger 可以右键 never
  1. 如果是eval型的构造器,可以重构 eval函数
  1. 如果是定时器,并且 2失效了,可以重构定时器
  1. 在以上方式都失效时,向上找堆栈,在进入无限debugger之前打上断点将触发无限debugger的函数置空(最麻烦,但是适用性最广)
 
 
 
 
 
如果找到瑞数尾缀参数
详细看下图