初探js逆向(三)之扣函数

声明:本文只作学习研究,禁止用于非法用途,否则后果自负,如有侵权,请告知删除,谢谢!

经过简单的分析,已知某网站参数的加密位置在这里:
在这里插入图片描述
在控制台下输入f()并回车:
在这里插入图片描述
按下快捷键F8,停在此处:
在这里插入图片描述
单步执行,来到这行:
在这里插入图片描述
代码 var n = r.wordsToBytes(s(t, e));调用了两个函数,分别是r.wordsToBytes 和 s,在控制台看看t,e的值:
在这里插入图片描述
t是上面讲到的固定的实参,e则未定义,不用理会,因此我们先将s函数扣出来看看,按照上面的方法,控制台输入s并回车跟进,来到这里:
在这里插入图片描述
一直到这里,都是与s相关的代码:
在这里插入图片描述
因此,将这段代码扣出来,保存到文件(我这里命名为md5.js),注意去掉s前面的括号以及:
在这里插入图片描述

保存以后,构造一个实参,并调用s函数:

在这里插入图片描述
直接在node下面跑一下,看看报啥错:
在这里插入图片描述

提示这里的o未定义,那跟进代码里面看看o是怎么定义的:
在这里插入图片描述
分析代码不难得知,这里实际是调用了o.stringToBytes这个函数,控制台输入看看:
在这里插入图片描述
双击跟进,来到这里:
在这里插入图片描述
直接把这个 n 对象扣出来,加入到s函数代码中,然后在照着逻辑加入这么一行代码:
在这里插入图片描述
再次运行,看结果:
在这里插入图片描述
再次报错,r未定义,按照之前的方法,跟进到r相关的代码在这里:
在这里插入图片描述

发现此时又定义了一个n,是base64的码表,因此按照上面的方式进入s函数肯定是不行的,因为变量名的污染,也导致的代码的臃肿,我这里以返回值的形式赋值,代码如下:

var r = (function() {
    
    
    var n, r;
    n = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
    r = {
    
    
        rotl: function(t, e) {
    
    
            return t << e | t >>> 32 - e
        },
        rotr: function(t, e) {
    
    
            return t << 32 - e | t >>> e
        },
        endian: function(t) {
    
    
            if (t.constructor == Number)
                return 16711935 & r.rotl(t, 8) | 4278255360 & r.rotl(t, 24);
            for (var e = 0; e < t.length; e++)
                t[e] = r.endian(t[e]);
            return t
        },
        randomBytes: function(t) {
    
    
            for (var e = []; t > 0; t--)
                e.push(Math.floor(256 * Math.random()));
            return e
        },
        bytesToWords: function(t) {
    
    
            for (var e = [], n = 0, r = 0; n < t.length; n++,
            r += 8)
                e[r >>> 5] |= t[n] << 24 - r % 32;
            return e
        },
        wordsToBytes: function(t) {
    
    
            for (var e = [], n = 0; n < 32 * t.length; n += 8)
                e.push(t[n >>> 5] >>> 24 - n % 32 & 255);
            return e
        },
        bytesToHex: function(t) {
    
    
            for (var e = [], n = 0; n < t.length; n++)
                e.push((t[n] >>> 4).toString(16)),
                e.push((15 & t[n]).toString(16));
            return e.join("")
        },
        hexToBytes: function(t) {
    
    
            for (var e = [], n = 0; n < t.length; n += 2)
                e.push(parseInt(t.substr(n, 2), 16));
            return e
        },
        bytesToBase64: function(t) {
    
    
            for (var e = [], r = 0; r < t.length; r += 3)
                for (var o = t[r] << 16 | t[r + 1] << 8 | t[r + 2], i = 0; i < 4; i++)
                    8 * r + 6 * i <= 8 * t.length ? e.push(n.charAt(o >>> 6 * (3 - i) & 63)) : e.push("=");
            return e.join("")
        },
        base64ToBytes: function(t) {
    
    
            t = t.replace(/[^A-Z0-9+\/]/gi, "");
            for (var e = [], r = 0, o = 0; r < t.length; o = ++r % 4)
                0 != o && e.push((n.indexOf(t.charAt(r - 1)) & Math.pow(2, -2 * o + 8) - 1) << 2 * o | n.indexOf(t.charAt(r)) >>> 6 - 2 * o);
            return e
        }
    }
 
 
    return r;
})()

再次运行,有结果了:
在这里插入图片描述
回到浏览器,看看这个s函数的值是否正确:
在这里插入图片描述
控制台输入s(t,e):
在这里插入图片描述
扣到这里,再分析函数r.wordsToBytes,发现居然就是刚才扣的r对象,这下就省事多了,直接比对结果吧:
在这里插入图片描述
在扣出来的代码上添加输出即可:

console.log(r.wordsToBytes(s(tmp)));

运行看结果:
在这里插入图片描述
与上面的结果也是惊人的一致。

回到浏览器,看这里return的是啥:

在这里插入图片描述
这是一个三目表达式,直接在浏览器上看看逻辑:
在这里插入图片描述
可以看到,最终执行了r.bytesToHex(n),在扣出来的代码上添加输出:

console.log(r.bytesToHex(r.wordsToBytes(s(tmp))));

在这里插入图片描述
可以看到,结果出来了。

至此,代码抠取完毕。

Guess you like

Origin blog.csdn.net/qq_35606400/article/details/119802796