js 破解某些web应用的反调试逻辑
最近想看某个网站的逻辑, 用了混淆和反调试, 各种阻碍, 不得不想办法绕过它:
function _0x1b1e27(_0x5d8113) { function _0x44deab(_0xb1966e) { var _0x51479f = _0x5611; if (typeof _0xb1966e === _0x51479f(0xf4)) return function(_0x28565d) {} [_0x51479f(0xc4)]('while\x20(true)\x20{}')[_0x51479f(0xf9)]('counter'); else ('' + _0xb1966e / _0xb1966e)[_0x51479f(0x109)] !== -0x7c9 * 0x3 + 0x865 + 0xef7 * 0x1 || _0xb1966e % (-0x1881 + 0x79 * -0x41 + 0x374e) === -0x262e + 0xea + 0x212 * 0x12 ? function() { return !![]; } [_0x51479f(0xc4)]('debu' + _0x51479f(0xab))[_0x51479f(0xc9)](_0x51479f(0xe0)) : function() { return ![]; } [_0x51479f(0xc4)](_0x51479f(0xe1) + _0x51479f(0xab))[_0x51479f(0xf9)]('stateObject'); _0x44deab(++_0xb1966e); } try { if (_0x5d8113) return _0x44deab; else _0x44deab(-0x8a9 * -0x2 + 0x2e4 + 0xd * -0x18e); } catch (_0x4c0048) {} }
很难读懂,人工翻译它, 初版:
function getDebugger(outArg) { function innerFunc(inArg) { if (typeof inArg === 'string'){ return function(a) {}['constructor']('while (true) {}')["apply"]('counter'); } else{ function(){ return true;}['constructor']('debugger')['call']('action') } innerFunc(++inArg); } try { if (outArg) return innerFunc; else innerFunc(0); } catch (err) {} }
先分析这个语句:function(){ return true;}['constructor']('debugger')['call']('action')
这个语句function() { return true; }['constructor'] 相当于Function对象
然后是Function('debugger') 相当于function anonymous(\n) {\ndebugger\n}
然后是anonymous['call']('action') 相当于触发debugger, 经过这个分析
第二次改写:
function getDebugger(outArg) { function innerFunc(inArg) { if (typeof inArg === 'string'){ return eval('while (true) {}'); } else{ eval('debugger'); } innerFunc(++inArg); } try { if (outArg) return innerFunc; else innerFunc(0); } catch (err) {} }
看到这个逻辑就比较清晰了,
inArg是字符串,那么就死循环, 卡死
非字符串,那么就是触发调试
看到这个地方, 有一个破解方式,将innerFunc改为空方法, getDebugger(true)=function(){}
实际情况, 这个方法还是_0x开头,不是getDebugger。
我想到了错误使用错误堆栈来获取调用者, 然后在hook这个调用者:

获取到方法名,就好解决了, 直接eval(`${funcName}=function(){}`)
实际测试,debugger次数没有那么频繁了,但依旧存在!
理想很丰满现实很骨感, 这个hook确实生效了, 但是曾经拿到过这个闭包的方法引用依旧存在,
所以换种方案:
省了过程,直接上价值1个亿的代码(手动狗头):
var oldconstructor = Function.prototype.constructor; var proconstructor = function(a) { if (a === 'debugger' || a.startsWith('while ')) return function() {} else return oldconstructor.apply(this, Array.from(arguments)); } proconstructor.prototype = oldconstructor.prototype; Function.prototype.constructor = proconstructor;
妈妈再也不担心我调试不了, 哈哈。。。。。。

浙公网安备 33010602011771号