JS 反调试的学习
in Code with 0 comment
JS 反调试的学习
in Code with 0 comment

由于工作需要,临时客串了半个前端人员(鄙人才疏学浅),协助处理一下前端混淆JS,抓取某站数据 (哈哈~~邪恶的笑声)。

JS常见反调试手段:压缩JS文件、源码中添加debugger、加密请求参数。

压缩JS文件就不说了,这个严格来说不算(之前遇到过使用16进制重命名变量的)。

JS防止调试

这里说一下防止 debug,常见手段是随机在脚本处插入 debugger 代码,防止前端人员调试,或者插入一段定时代码,代码就不停执行 debugger,下面是一段伪代码:

setInterval(function () {
    debugger;
}, 50);

更高级的写法:

(function() {}['constructor']('debugger')())

对于JS,有时候一些代码看起来是如此的另类,通过字符串,就能调用成员,后缀加 () 就是调用方法了,例如:

var w = window;
var cmdArr = ['console', 'log'];
w[cmdArr[0]][cmdArr[1]]('hello, world!');
// output: hello, world!

说完了防止 debug 和JS一些高级写法后,接下来说一下破解手段:

  1. 使用 Fiddler 做JS拦截(俗话说的好,Fiddler 学的好的,都已经进监狱了)。
  2. 使用 ReRes 将JS替换为本地路径。

关于 Fiddler JS拦截,请查看这篇文章:Fiddler - 超好用的http抓包工具使用介绍。

ReRes 的使用,请点击名称进入 Github 页面。

另外 JS 防止调试,还有一种变态的做法,就是 消耗PC资源,通过不停的调用 console.log 和 console.clear 来疯狂出信息,然后清空,过一小会儿,你就会发现你的PC资源过高(当然你的 PC 强到离谱,当我没说)。

加密请求参数

经过上面的步骤后,我们基本可以正常调试 JS 了。在这先说一下,如何高效的利用 Chrome Dev Tools:

  1. 通常我们抓取数据都是通过查看 Network 面板中的请求数据,通过点击 Initiator 项(在标题栏),就可以直接定位到请求代码了。
  2. 通过 Sources 面板,右侧的调试工具,如 XHR/fetch Breakpoints 监视 XHR 请求、通过 Event Listener Breakpoints 监听事件,可以监听如 Mouse(鼠标相关操作,如点击), Timer (监听定时器,如setTimeout 代码段)。
这里就罗列两种,后续如果发现最新好玩,还会继续补上

一般情况下,都是采用 匿名自执行函数 写法,例如:

(function (msg) {
    console.log(msg);
})('hello');

通过事先加密一段字符串(字符串通过加入特殊符号,如 ASCII 不可见码),通过上面的形式,传入到函数内,在函数内解密字符串,并解析出请求地址(有时候还会在里面加入 debugger 防调试代码)。一般采用的都是 XOR加密。

先上一段有意思的代码:

(function (c2) {
    var E2 = 2;
    while (E2 !== 14) {
        switch (E2) {
            case 1:
                var N2 = 0, P2 = 0;
                E2 = 5;
                break;
            case 9:
                a2 += String.fromCharCode(e2.charCodeAt(N2) ^ c2.charCodeAt(P2));
                E2 = 8;
                break;
            case 2:
                var a2 = '', e2 = decodeURI("1'-$&zf%7B%7F(%20(c+:");
                E2 = 1;
                break;
            case 5:
                E2 = N2 < e2.length ? 4 : 7;
                break;
            case 4:
                E2 = P2 === c2.length ? 3 : 9;
                break;
            case 3:
                P2 = 0;
                E2 = 9;
                break;
            case 7:
                a2 = a2.split('(');
                console.log(a2);
                return a2;
                break;
            case 8:
                N2++, P2++;
                E2 = 5;
                break;
        }
    }
})('POILBI');

上面代码中,其中还有一部分可以继续加工,如:String.fromCharCode(), decodeURI() 方法。代码中 POILBI为加密KEY,1'-$&zf%7B%7F(%20(c+: 为通过 XOR加密 加密后的数据,说完这两点想必你已经知道这段代码是做什么的了,其实这就是一段经过混淆后的加 XOR加密 代码,代码使用了 switch 的语法来改写 while 循环,解密后的代码如下:

function encrypt(src, key) {
    var res = '';   // a2
    var srcIndex = 0;  // N2
    var keyIndex = 0;  // P2
    while (srcIndex < src.length) {
        if (keyIndex == key.length) {
            keyIndex = 0;
            res += String.fromCharCode(src.charCodeAt(srcIndex) ^ key.charCodeAt(keyIndex));
        } else {
            res += String.fromCharCode(src.charCodeAt(srcIndex) ^ key.charCodeAt(keyIndex));
        }
        keyIndex++;
        srcIndex++;
    }
    return res;
}
var src = decodeURI("1'-$&zf%7B%7F(%20(c+:");  // e2
var key = 'POILBI';
console.log(encrypt(src, key));
// output: ahdhd3646dba3ds

最后

好了,关于 JS 反调试的学习,就先告一段落,以后有新东西,将会继续写。JS 反调试是一件很枯燥耗时的事情,需要你整个人投入进去,并调整好心态。

The article has been posted for too long and comments have been automatically closed.