vmp套vmp之探讨某d的_fingerprint参数生成

查看 73|回复 9
作者:utf8   
vmp套vmp之探讨某d的_fingerprint参数生成
本文仅供学习交流,因使用本文内容而产生的任何风险及后果,作者不承担任何责任,一起学习吧
快速定位
直接搜索this._fingerprint = _$XS.get(this._version, this._appId),便可快速定位到这个参数的生成位置。
传入两个参数this._version = '5.1'和this._appId = '73806'。简单记一下,打上断点,步入进去。
我们进入到了这样的一个函数:
var _$XS = {
    'get': function(_$Vk, _$Vt) {
        var _$VM = {
            'gZiAS': function(_$VN, _$Vr, _$Vf) {
                return _$VN(_$Vr, _$Vf);
            }
        }
            , _$VI = arguments.length > 0x58a + 0x32a * 0xb + -0x2856 && _$h.hhZxk(void (0x428 + -0xfc3 * -0x2 + 0x1 * -0x23ae), arguments[0x59e + -0x696 * 0x2 + -0x8 * -0xf2]) ? arguments[-0x14f6 + -0x211c + 0x3614] : -0xf * -0x19f + -0x1084 + 0x7cd * -0x1
            , _$VH = _$Xl.get(_$Xf.STORAGE_KEY_VK, {
            'raw': !(-0x2 * -0x1de + -0x305 * 0x5 + 0xb5e),
            'from': _$VI
        })
            , _$VO = _$h.HsBLR(_$X7, _$VH) ? _$VH : {}
            , _$VR = _$XH(_$VO, [_$Vk, _$Vt]);
        if (_$Xj(_$VR))
            return _$VR.v;
        var _$VC = _$Xu();
        return _$XI(_$VO, [_$Vk, _$Vt], {
            'e': 0x1e13380,
            'v': _$VC,
            't': Date.now()
        }),
        function(_$VN) {
            if (!_$VN)
                return;
            var _$Vr = [];
            _$h.wtKeL(_$XO, _$VN, function(_$VX, _$VV) {
                _$VM.gZiAS(_$XO, _$VX, function(_$VD, _$Vw) {
                    _$Xj(_$VD) && _$Vr.push({
                        'v': _$VV,
                        'appid': _$Vw,
                        'data': _$VD
                    });
                });
            });
            var _$Vf = {};
            _$Vr.forEach(function(_$VX) {
                var _$VV = _$VX.v
                    , _$VD = _$VX.appid
                    , _$Vw = _$VX.data;
                _$XI(_$Vf, [_$VV, _$VD], _$Vw);
            }),
            _$Xl.set(_$Xf.STORAGE_KEY_VK, _$Vf);
        }(_$VO),
        _$VC;
    }
}
这里还是一步步取跟,看看这个函数干了什么。
函数分析
我还是按照我的风格来讲解,一步步分析代码
var _$VM = {
                'gZiAS': function(_$VN, _$Vr, _$Vf) {
                    return _$VN(_$Vr, _$Vf);
                }
            } //这里简单定义了一个对象
    , _$VI = arguments.length > 0x58a + 0x32a * 0xb + -0x2856 && _$h.hhZxk(void (0x428 + -0xfc3 * -0x2 + 0x1 * -0x23ae), arguments[0x59e + -0x696 * 0x2 + -0x8 * -0xf2]) ? arguments[-0x14f6 + -0x211c + 0x3614] : -0xf * -0x19f + -0x1084 + 0x7cd * -0x1
    , _$VH = _$Xl.get(_$Xf.STORAGE_KEY_VK, {
    'raw': !(-0x2 * -0x1de + -0x305 * 0x5 + 0xb5e),
    'from': _$VI
    })  // 这里去取了一些浏览器的值 但是我们在这里看到一个 v = "dw3gwggga2hpa338" 很像我们的_fingerprint我们直接步出这个函数,看看结果是不是
    , _$VO = _$h.HsBLR(_$X7, _$VH) ? _$VH : {}
    , _$VR = _$XH(_$VO, [_$Vk, _$Vt]);
    if (_$Xj(_$VR))  
    return _$VR.v;
    var _$VC = _$Xu();  
    return _$XI(_$VO, [_$Vk, _$Vt], {
                'e': 0x1e13380,
                'v': _$VC,
                't': Date.now()
            }),   
我们步出这个函数发现this._fingerprint = "dw3gwggga2hpa338"说明这个并且我们多次运行后面方法发现这个是不变的。但是它真的是不变的吗。
如果你详细跟了上面这个函数你就知道,这个_fingerprint会被存储在本地存储的WQ_dy1_vk中。
我们还是观察这个代码。这个v是我们的_fingerprint,向下看看发现。讲解如下:
var _$VC = _$Xu();  // 说明这个是_fingerprint生成的地方(2)
return _$XI(_$VO, [_$Vk, _$Vt], {
            'e': 0x1e13380,
            'v': _$VC,  // 这里不就表明了吗 (1)
            't': Date.now()
        }),   
还是一样,打上断点步入进去,发现。好家伙,一眼vmp,而且还是vmp套vmp。但是不要慌。还记得我之前文章写的巧用ai和vmp插桩的几点吗。我们将代码扣下来将需要插桩的分支发给ai让他给我们插好桩。这样我们就得到一份完美的插桩代码。这里还要提醒一下,需要把每个vmp的栈和执行分支也打出来。会方便很多。这个插好的代码我会放到附录供大家学习。
我们既然知道这个是存储在本地的,我们清空本地网站数据。重新步入。
执行完这个函数,我们得到一份粗略的日志。我们先简单浏览一下。我们发现一个很奇怪的字符串 0jhqw3pa2m 后面操作都有它的身影。说明这个是个重要参数。


1.png (39.64 KB, 下载次数: 0)
下载附件
2025-5-9 16:35 上传

很显然是上面那个函数,直接进入看看。
    function a0dbbcbn(_$h, _$n) {
        var _$q = a0dbbcbh();
        return a0dbbcbn = function(_$p, _$A) {
            _$p = _$p - (-0x4 * -0x59d + 0x155f + -0x2ac7);
            var _$L = _$q[_$p];
            if (a0dbbcbn.TpoVmd === undefined) {
                var _$k = function(_$H) {
                    var _$O = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';
                    var _$R = ''
                      , _$C = '';
                    for (var _$N = -0x1d7 + -0x1438 * -0x1 + 0x1261 * -0x1, _$r, _$f, _$X = 0x23ff + 0x1c9d + -0x409c; _$f = _$H.charAt(_$X++); ~_$f && (_$r = _$N % (-0x87e + -0x1 * -0x9cb + -0x149) ? _$r * (-0x4e9 * 0x1 + -0x1 * -0x6ca + 0x3 * -0x8b) + _$f : _$f,
                    _$N++ % (0x2 * 0x4f0 + -0x1f9c + 0x4 * 0x570)) ? _$R += String.fromCharCode(-0x3 * -0xca0 + 0x2 * -0x689 + -0x17cf & _$r >> (-(0x28 * 0x2e + -0x11c * 0x1 + -0x612) * _$N & -0x1543 + 0x23a3 + -0xb * 0x14e)) : 0x9ac + 0x23b4 + -0x2d60) {
                        _$f = _$O.indexOf(_$f);
                    }
                    for (var _$V = -0x1ad0 + 0x23c5 + -0x1 * 0x8f5, _$D = _$R.length; _$V
这个你直接丢给gpt分析就行,他这个很明显就是一个字符解析,而且是在传入大数组中取。那么这个值便是一个定值。但是我还是简单还原了一下:
var decodeBase64URIComponent = function(encodedStr) {
  var base64Chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';
  var decodedBinary = '', percentEncoded = '';
  for (var bitCounter = 0, buffer, currentChar, charIndex = 0;
       currentChar = encodedStr.charAt(charIndex++);
       ~currentChar && (
         buffer = bitCounter % 4 ? buffer * 64 + currentChar : currentChar,
         bitCounter++ % 4
       ) ? decodedBinary += String.fromCharCode(
            255 & buffer >> ((-2 * bitCounter) & 6)
         ) : 0) {
    currentChar = base64Chars.indexOf(currentChar);
  }
  for (var i = 0, len = decodedBinary.length; i
接着向下看,为了方便教学,我将日志一些干扰项全部删除了。日志很长,且听我慢慢分析。
我们分析日志的时候抓住几点:
[ol]
  • 入参
  • 计算
  • 结果
    [/ol]
    在下面这个日志,我们初始串 0jhqw3pa2m,经历了什么不为人知的计算。关注到了有一个比大小和乘积。而且大量使用了random函数。最后变成了["0","a","2"]
    那么我们着重观察["0","a","2"]这个结果生成的特征,从下向上看。


    2.png (167.42 KB, 下载次数: 0)
    下载附件
    2025-5-9 16:35 上传



    3.png (179.42 KB, 下载次数: 0)
    下载附件
    2025-5-9 16:35 上传



    4.png (61.75 KB, 下载次数: 0)
    下载附件
    2025-5-9 16:35 上传



    5.png (80.57 KB, 下载次数: 0)
    下载附件
    2025-5-9 16:35 上传

    我们在总结一下就是,循环这个串(指针i),每次参数随机值和这个串的长度 减 i 的乘积 和 一个数 3比大小,比他小就取出这个字符同时让这个数减一
    代码简单写一下就是:
    str_replace = []
        for(let i=0,j=input.length,flag=3;i' + a)
            if(a
    这部分完整日志如下:
    执行分支--o 69 栈r--> ["0jhqw3pa2m"]
    执行分支--o 68 栈r--> [10]
    执行分支--o 56 栈r--> [10]
    执行分支--o -5340 栈r--> []
    执行分支--o -275 栈r--> [-5340]
    执行分支--o 56 栈r--> [-5340,-275]
    执行分支--o 5615 栈r--> [-5615]
    执行分支--o 79 栈r--> [-5615,5615]
    执行分支--o 68 栈r--> [0]
    执行分支--o 29 栈r--> [0]
    执行分支--o 43 栈r--> []
    执行分支--o 47 栈r--> []
    执行分支--o 3 栈r--> [省略]
    执行分支--o 41 栈r--> [null,省略]
    执行分支--o 40 栈r--> [null,省略,0]
    执行分支--o 75 栈r--> [null,省略,0,"0jhqw3pa2m"]
    执行分支--o 70 栈r--> [null,省略,0,10]
    7074 [插桩] 调用 i.call
    7075 [插桩] 调用函数: ƒ (_$VA, _$VL) {
                return _$VA  [true]
    执行分支--o 60 栈r--> []
    执行分支--o 3 栈r--> ["0jhqw3pa2m"]
    执行分支--o 81 栈r--> ["0jhqw3pa2m",0]
    执行分支--o 68 栈r--> ["0"]
    执行分支--o 12 栈r--> ["0"]
    执行分支--o 47 栈r--> []
    执行分支--o 0 栈r--> [省略]
    执行分支--o 47 栈r--> [null,省略]
    执行分支--o 1 栈r--> [null,省略,{}]
    执行分支--o 95 栈r--> [null,省略,null,{}]
    6954 [插桩] 分支1 - 调用 i.call
    6955 [插桩] 调用函数: ƒ random() { [native code] }
    6956 [插桩] 参数: Math {abs: ƒ, acos: ƒ, acosh: ƒ, asin: ƒ, asinh: ƒ, …}
    6960 [插桩] 返回值: 0.0009489305987293584
    执行分支--o 75 栈r--> [null,省略,0.0009489305987293584]
    执行分支--o 30 栈r--> [null,省略,0.0009489305987293584,10]
    7074 [插桩] 调用 i.call
    7075 [插桩] 调用函数: ƒ (_$VA, _$VL) {
                return _$VA * _$VL;
            }
    7076 [插桩] 参数: {QuHhA: 'function', DPusW: ƒ, KzvJS: ƒ, TxipF: ƒ, Ufhnc: ƒ, …} 0.0009489305987293584 10
    7080 [插桩] 返回值: 0.009489305987293584
    执行分支--o 22 栈r--> [0.009489305987293584]
    执行分支--o 35 栈r--> [0.009489305987293584,3]
    执行分支--o 17 栈r--> [true]
    执行分支--o 47 栈r--> []
    执行分支--o 2 栈r--> [[]]
    执行分支--o 76 栈r--> [null,[]]
    执行分支--o 68 栈r--> [null,[],"0"]
    7094 [插桩] 分支1 - 调用 i.call
    7095 [插桩] 调用函数: ƒ push() { [native code] }
    7096 [插桩] 参数: [] 0
    7100 [插桩] 返回值: 1
    执行分支--o 56 栈r--> [1]
    执行分支--o -910 栈r--> []
    执行分支--o -5375 栈r--> [-910]
    执行分支--o 56 栈r--> [-910,-5375]
    执行分支--o 6285 栈r--> [-6285]
    执行分支--o 5 栈r--> [-6285,6285]
    执行分支--o 32 栈r--> [0]
    执行分支--o 72 栈r--> [0,2]
    执行分支--o 3 栈r--> [false]
    执行分支--o 68 栈r--> []
    执行分支--o 87 栈r--> [10]
    执行分支--o 68 栈r--> []
    执行分支--o 12 栈r--> [0]
    执行分支--o 47 栈r--> []
    执行分支--o 3 栈r--> [省略]
    执行分支--o 41 栈r--> [null,省略]
    执行分支--o 40 栈r--> [null,省略,1]
    执行分支--o 75 栈r--> [null,省略,1,"0jhqw3pa2m"]
    执行分支--o 70 栈r--> [null,省略,1,10]
    7074 [插桩] 调用 i.call
    7075 [插桩] 调用函数: ƒ (_$VA, _$VL) {
                return _$VA  [true]
    执行分支--o 60 栈r--> []
    执行分支--o 3 栈r--> ["0jhqw3pa2m"]
    执行分支--o 81 栈r--> ["0jhqw3pa2m",1]
    执行分支--o 68 栈r--> ["j"]
    执行分支--o 12 栈r--> ["j"]
    执行分支--o 47 栈r--> []
    执行分支--o 0 栈r--> [省略]
    执行分支--o 47 栈r--> [null,省略]
    执行分支--o 1 栈r--> [null,省略,{}]
    执行分支--o 95 栈r--> [null,省略,null,{}]
    6954 [插桩] 分支1 - 调用 i.call
    6955 [插桩] 调用函数: ƒ random() { [native code] }
    6956 [插桩] 参数: Math {abs: ƒ, acos: ƒ, acosh: ƒ, asin: ƒ, asinh: ƒ, …}
    6960 [插桩] 返回值: 0.24283588276465118
    执行分支--o 75 栈r--> [null,省略,0.24283588276465118]
    执行分支--o 30 栈r--> [null,省略,0.24283588276465118,9]
    7074 [插桩] 调用 i.call
    7075 [插桩] 调用函数: ƒ (_$VA, _$VL) {
                return _$VA * _$VL;
            }
    7076 [插桩] 参数: {QuHhA: 'function', DPusW: ƒ, KzvJS: ƒ, TxipF: ƒ, Ufhnc: ƒ, …} 0.24283588276465118 9
    7080 [插桩] 返回值: 2.1855229448818605
    执行分支--o 22 栈r--> [2.1855229448818605]
    执行分支--o 35 栈r--> [2.1855229448818605,2]
    执行分支--o 17 栈r--> [false]
    执行分支--o 3 栈r--> [false]
    执行分支--o 68 栈r--> []
    执行分支--o 87 栈r--> [9]
    执行分支--o 68 栈r--> []
    执行分支--o 12 栈r--> [1]
    执行分支--o 47 栈r--> []
    执行分支--o 3 栈r--> [省略]
    执行分支--o 41 栈r--> [null,省略]
    执行分支--o 40 栈r--> [null,省略,2]
    执行分支--o 75 栈r--> [null,省略,2,"0jhqw3pa2m"]
    执行分支--o 70 栈r--> [null,省略,2,10]
    7074 [插桩] 调用 i.call
    7075 [插桩] 调用函数: ƒ (_$VA, _$VL) {
                return _$VA  [true]
    执行分支--o 60 栈r--> []
    执行分支--o 3 栈r--> ["0jhqw3pa2m"]
    执行分支--o 81 栈r--> ["0jhqw3pa2m",2]
    执行分支--o 68 栈r--> ["h"]
    执行分支--o 12 栈r--> ["h"]
    执行分支--o 47 栈r--> []
    执行分支--o 0 栈r--> [省略]
    执行分支--o 47 栈r--> [null,省略]
    执行分支--o 1 栈r--> [null,省略,{}]
    执行分支--o 95 栈r--> [null,省略,null,{}]
    6954 [插桩] 分支1 - 调用 i.call
    6955 [插桩] 调用函数: ƒ random() { [native code] }
    6956 [插桩] 参数: Math {abs: ƒ, acos: ƒ, acosh: ƒ, asin: ƒ, asinh: ƒ, …}
    6960 [插桩] 返回值: 0.5844895447176711
    执行分支--o 75 栈r--> [null,省略,0.5844895447176711]
    执行分支--o 30 栈r--> [null,省略,0.5844895447176711,8]
    7074 [插桩] 调用 i.call
    7075 [插桩] 调用函数: ƒ (_$VA, _$VL) {
                return _$VA * _$VL;
            }
    7076 [插桩] 参数: {QuHhA: 'function', DPusW: ƒ, KzvJS: ƒ, TxipF: ƒ, Ufhnc: ƒ, …} 0.5844895447176711 8
    7080 [插桩] 返回值: 4.675916357741369
    执行分支--o 22 栈r--> [4.675916357741369]
    执行分支--o 35 栈r--> [4.675916357741369,2]
    执行分支--o 17 栈r--> [false]
    执行分支--o 3 栈r--> [false]
    执行分支--o 68 栈r--> []
    执行分支--o 87 栈r--> [8]
    执行分支--o 68 栈r--> []
    执行分支--o 12 栈r--> [2]
    执行分支--o 47 栈r--> []
    执行分支--o 3 栈r--> [省略]
    执行分支--o 41 栈r--> [null,省略]
    执行分支--o 40 栈r--> [null,省略,3]
    执行分支--o 75 栈r--> [null,省略,3,"0jhqw3pa2m"]
    执行分支--o 70 栈r--> [null,省略,3,10]
    7074 [插桩] 调用 i.call
    7075 [插桩] 调用函数: ƒ (_$VA, _$VL) {
                return _$VA  [true]
    执行分支--o 60 栈r--> []
    执行分支--o 3 栈r--> ["0jhqw3pa2m"]
    执行分支--o 81 栈r--> ["0jhqw3pa2m",3]
    执行分支--o 68 栈r--> ["q"]
    执行分支--o 12 栈r--> ["q"]
    执行分支--o 47 栈r--> []
    执行分支--o 0 栈r--> [省略]
    执行分支--o 47 栈r--> [null,省略]
    执行分支--o 1 栈r--> [null,省略,{}]
    执行分支--o 95 栈r--> [null,省略,null,{}]
    6954 [插桩] 分支1 - 调用 i.call
    6955 [插桩] 调用函数: ƒ random() { [native code] }
    6956 [插桩] 参数: Math {abs: ƒ, acos: ƒ, acosh: ƒ, asin: ƒ, asinh: ƒ, …}
    6960 [插桩] 返回值: 0.5011145080247482
    执行分支--o 75 栈r--> [null,省略,0.5011145080247482]
    执行分支--o 30 栈r--> [null,省略,0.5011145080247482,7]
    7074 [插桩] 调用 i.call
    7075 [插桩] 调用函数: ƒ (_$VA, _$VL) {
                return _$VA * _$VL;
            }
    7076 [插桩] 参数: {QuHhA: 'function', DPusW: ƒ, KzvJS: ƒ, TxipF: ƒ, Ufhnc: ƒ, …} 0.5011145080247482 7
    7080 [插桩] 返回值: 3.5078015561732374
    执行分支--o 22 栈r--> [3.5078015561732374]
    执行分支--o 35 栈r--> [3.5078015561732374,2]
    执行分支--o 17 栈r--> [false]
    执行分支--o 3 栈r--> [false]
    执行分支--o 68 栈r--> []
    执行分支--o 87 栈r--> [7]
    执行分支--o 68 栈r--> []
    执行分支--o 12 栈r--> [3]
    执行分支--o 47 栈r--> []
    执行分支--o 3 栈r--> [省略]
    执行分支--o 41 栈r--> [null,省略]
    执行分支--o 40 栈r--> [null,省略,4]
    执行分支--o 75 栈r--> [null,省略,4,"0jhqw3pa2m"]
    执行分支--o 70 栈r--> [null,省略,4,10]
    7074 [插桩] 调用 i.call
    7075 [插桩] 调用函数: ƒ (_$VA, _$VL) {
                return _$VA  [true]
    执行分支--o 60 栈r--> []
    执行分支--o 3 栈r--> ["0jhqw3pa2m"]
    执行分支--o 81 栈r--> ["0jhqw3pa2m",4]
    执行分支--o 68 栈r--> ["w"]
    执行分支--o 12 栈r--> ["w"]
    执行分支--o 47 栈r--> []
    执行分支--o 0 栈r--> [省略]
    执行分支--o 47 栈r--> [null,省略]
    执行分支--o 1 栈r--> [null,省略,{}]
    执行分支--o 95 栈r--> [null,省略,null,{}]
    6954 [插桩] 分支1 - 调用 i.call
    6955 [插桩] 调用函数: ƒ random() { [native code] }
    6956 [插桩] 参数: Math {abs: ƒ, acos: ƒ, acosh: ƒ, asin: ƒ, asinh: ƒ, …}
    6960 [插桩] 返回值: 0.6615523978605656
    执行分支--o 75 栈r--> [null,省略,0.6615523978605656]
    执行分支--o 30 栈r--> [null,省略,0.6615523978605656,6]
    7074 [插桩] 调用 i.call
    7075 [插桩] 调用函数: ƒ (_$VA, _$VL) {
                return _$VA * _$VL;
            }
    7076 [插桩] 参数: {QuHhA: 'function', DPusW: ƒ, KzvJS: ƒ, TxipF: ƒ, Ufhnc: ƒ, …} 0.6615523978605656 6
    7080 [插桩] 返回值: 3.9693143871633936
    执行分支--o 22 栈r--> [3.9693143871633936]
    执行分支--o 35 栈r--> [3.9693143871633936,2]
    执行分支--o 17 栈r--> [false]
    执行分支--o 3 栈r--> [false]
    执行分支--o 68 栈r--> []
    执行分支--o 87 栈r--> [6]
    执行分支--o 68 栈r--> []
    执行分支--o 12 栈r--> [4]
    执行分支--o 47 栈r--> []
    执行分支--o 3 栈r--> [省略]
    执行分支--o 41 栈r--> [null,省略]
    执行分支--o 40 栈r--> [null,省略,5]
    执行分支--o 75 栈r--> [null,省略,5,"0jhqw3pa2m"]
    执行分支--o 70 栈r--> [null,省略,5,10]
    7074 [插桩] 调用 i.call
    7075 [插桩] 调用函数: ƒ (_$VA, _$VL) {
                return _$VA  [true]
    执行分支--o 60 栈r--> []
    执行分支--o 3 栈r--> ["0jhqw3pa2m"]
    执行分支--o 81 栈r--> ["0jhqw3pa2m",5]
    执行分支--o 68 栈r--> ["3"]
    执行分支--o 12 栈r--> ["3"]
    执行分支--o 47 栈r--> []
    执行分支--o 0 栈r--> [省略]
    执行分支--o 47 栈r--> [null,省略]
    执行分支--o 1 栈r--> [null,省略,{}]
    执行分支--o 95 栈r--> [null,省略,null,{}]
    6954 [插桩] 分支1 - 调用 i.call
    6955 [插桩] 调用函数: ƒ random() { [native code] }
    6956 [插桩] 参数: Math {abs: ƒ, acos: ƒ, acosh: ƒ, asin: ƒ, asinh: ƒ, …}
    6960 [插桩] 返回值: 0.53692932445542
    执行分支--o 75 栈r--> [null,省略,0.53692932445542]
    执行分支--o 30 栈r--> [null,省略,0.53692932445542,5]
    7074 [插桩] 调用 i.call
    7075 [插桩] 调用函数: ƒ (_$VA, _$VL) {
                return _$VA * _$VL;
            }
    7076 [插桩] 参数: {QuHhA: 'function', DPusW: ƒ, KzvJS: ƒ, TxipF: ƒ, Ufhnc: ƒ, …} 0.53692932445542 5
    7080 [插桩] 返回值: 2.6846466222771
    执行分支--o 22 栈r--> [2.6846466222771]
    执行分支--o 35 栈r--> [2.6846466222771,2]
    执行分支--o 17 栈r--> [false]
    执行分支--o 3 栈r--> [false]
    执行分支--o 68 栈r--> []
    执行分支--o 87 栈r--> [5]
    执行分支--o 68 栈r--> []
    执行分支--o 12 栈r--> [5]
    执行分支--o 47 栈r--> []
    执行分支--o 3 栈r--> [省略]
    执行分支--o 41 栈r--> [null,省略]
    执行分支--o 40 栈r--> [null,省略,6]
    执行分支--o 75 栈r--> [null,省略,6,"0jhqw3pa2m"]
    执行分支--o 70 栈r--> [null,省略,6,10]
    7074 [插桩] 调用 i.call
    7075 [插桩] 调用函数: ƒ (_$VA, _$VL) {
                return _$VA  [true]
    执行分支--o 60 栈r--> []
    执行分支--o 3 栈r--> ["0jhqw3pa2m"]
    执行分支--o 81 栈r--> ["0jhqw3pa2m",6]
    执行分支--o 68 栈r--> ["p"]
    执行分支--o 12 栈r--> ["p"]
    执行分支--o 47 栈r--> []
    执行分支--o 0 栈r--> [省略]
    执行分支--o 47 栈r--> [null,省略]
    执行分支--o 1 栈r--> [null,省略,{}]
    执行分支--o 95 栈r--> [null,省略,null,{}]
    6954 [插桩] 分支1 - 调用 i.call
    6955 [插桩] 调用函数: ƒ random() { [native code] }
    6956 [插桩] 参数: Math {abs: ƒ, acos: ƒ, acosh: ƒ, asin: ƒ, asinh: ƒ, …}
    6960 [插桩] 返回值: 0.6613187237589039
    执行分支--o 75 栈r--> [null,省略,0.6613187237589039]
    执行分支--o 30 栈r--> [null,省略,0.6613187237589039,4]
    7074 [插桩] 调用 i.call
    7075 [插桩] 调用函数: ƒ (_$VA, _$VL) {
                return _$VA * _$VL;
            }
    7076 [插桩] 参数: {QuHhA: 'function', DPusW: ƒ, KzvJS: ƒ, TxipF: ƒ, Ufhnc: ƒ, …} 0.6613187237589039 4
    7080 [插桩] 返回值: 2.6452748950356155
    执行分支--o 22 栈r--> [2.6452748950356155]
    执行分支--o 35 栈r--> [2.6452748950356155,2]
    执行分支--o 17 栈r--> [false]
    执行分支--o 3 栈r--> [false]
    执行分支--o 68 栈r--> []
    执行分支--o 87 栈r--> [4]
    执行分支--o 68 栈r--> []
    执行分支--o 12 栈r--> [6]
    执行分支--o 47 栈r--> []
    执行分支--o 3 栈r--> [省略]
    执行分支--o 41 栈r--> [null,省略]
    执行分支--o 40 栈r--> [null,省略,7]
    执行分支--o 75 栈r--> [null,省略,7,"0jhqw3pa2m"]
    执行分支--o 70 栈r--> [null,省略,7,10]
    7074 [插桩] 调用 i.call
    7075 [插桩] 调用函数: ƒ (_$VA, _$VL) {
                return _$VA  [true]
    执行分支--o 60 栈r--> []
    执行分支--o 3 栈r--> ["0jhqw3pa2m"]
    执行分支--o 81 栈r--> ["0jhqw3pa2m",7]
    执行分支--o 68 栈r--> ["a"]
    执行分支--o 12 栈r--> ["a"]
    执行分支--o 47 栈r--> []
    执行分支--o 0 栈r--> [省略]
    执行分支--o 47 栈r--> [null,省略]
    执行分支--o 1 栈r--> [null,省略,{}]
    执行分支--o 95 栈r--> [null,省略,null,{}]
    6954 [插桩] 分支1 - 调用 i.call
    6955 [插桩] 调用函数: ƒ random() { [native code] }
    6956 [插桩] 参数: Math {abs: ƒ, acos: ƒ, acosh: ƒ, asin: ƒ, asinh: ƒ, …}
    6960 [插桩] 返回值: 0.5048743044162417
    执行分支--o 75 栈r--> [null,省略,0.5048743044162417]
    执行分支--o 30 栈r--> [null,省略,0.5048743044162417,3]
    7074 [插桩] 调用 i.call
    7075 [插桩] 调用函数: ƒ (_$VA, _$VL) {
                return _$VA * _$VL;
            }
    7076 [插桩] 参数: {QuHhA: 'function', DPusW: ƒ, KzvJS: ƒ, TxipF: ƒ, Ufhnc: ƒ, …} 0.5048743044162417 3
    7080 [插桩] 返回值: 1.5146229132487252
    执行分支--o 22 栈r--> [1.5146229132487252]
    执行分支--o 35 栈r--> [1.5146229132487252,2]
    执行分支--o 17 栈r--> [true]
    执行分支--o 47 栈r--> []
    执行分支--o 2 栈r--> [["0"]]
    执行分支--o 76 栈r--> [null,["0"]]
    执行分支--o 68 栈r--> [null,["0"],"a"]
    7094 [插桩] 分支1 - 调用 i.call
    7095 [插桩] 调用函数: ƒ push() { [native code] }
    7096 [插桩] 参数: ['0'] a
    7100 [插桩] 返回值: 2
    执行分支--o 56 栈r--> [2]
    执行分支--o -910 栈r--> []
    执行分支--o -5375 栈r--> [-910]
    执行分支--o 56 栈r--> [-910,-5375]
    执行分支--o 6285 栈r--> [-6285]
    执行分支--o 5 栈r--> [-6285,6285]
    执行分支--o 32 栈r--> [0]
    执行分支--o 72 栈r--> [0,1]
    执行分支--o 3 栈r--> [false]
    执行分支--o 68 栈r--> []
    执行分支--o 87 栈r--> [3]
    执行分支--o 68 栈r--> []
    执行分支--o 12 栈r--> [7]
    执行分支--o 47 栈r--> []
    执行分支--o 3 栈r--> [省略]
    执行分支--o 41 栈r--> [null,省略]
    执行分支--o 40 栈r--> [null,省略,8]
    执行分支--o 75 栈r--> [null,省略,8,"0jhqw3pa2m"]
    执行分支--o 70 栈r--> [null,省略,8,10]
    7074 [插桩] 调用 i.call
    7075 [插桩] 调用函数: ƒ (_$VA, _$VL) {
                return _$VA  [true]
    执行分支--o 60 栈r--> []
    执行分支--o 3 栈r--> ["0jhqw3pa2m"]
    执行分支--o 81 栈r--> ["0jhqw3pa2m",8]
    执行分支--o 68 栈r--> ["2"]
    执行分支--o 12 栈r--> ["2"]
    执行分支--o 47 栈r--> []
    执行分支--o 0 栈r--> [省略]
    执行分支--o 47 栈r--> [null,省略]
    执行分支--o 1 栈r--> [null,省略,{}]
    执行分支--o 95 栈r--> [null,省略,null,{}]
    6954 [插桩] 分支1 - 调用 i.call
    6955 [插桩] 调用函数: ƒ random() { [native code] }
    6956 [插桩] 参数: Math {abs: ƒ, acos: ƒ, acosh: ƒ, asin: ƒ, asinh: ƒ, …}
    6960 [插桩] 返回值: 0.1288065950106041
    执行分支--o 75 栈r--> [null,省略,0.1288065950106041]
    执行分支--o 30 栈r--> [null,省略,0.1288065950106041,2]
    7074 [插桩] 调用 i.call
    7075 [插桩] 调用函数: ƒ (_$VA, _$VL) {
                return _$VA * _$VL;
            }
    7076 [插桩] 参数: {QuHhA: 'function', DPusW: ƒ, KzvJS: ƒ, TxipF: ƒ, Ufhnc: ƒ, …} 0.1288065950106041 2
    7080 [插桩] 返回值: 0.2576131900212082
    执行分支--o 22 栈r--> [0.2576131900212082]
    执行分支--o 35 栈r--> [0.2576131900212082,1]
    执行分支--o 17 栈r--> [true]
    执行分支--o 47 栈r--> []
    执行分支--o 2 栈r--> [["0","a"]]
    执行分支--o 76 栈r--> [null,["0","a"]]
    执行分支--o 68 栈r--> [null,["0","a"],"2"]
    7094 [插桩] 分支1 - 调用 i.call
    7095 [插桩] 调用函数: ƒ push() { [native code] }
    7096 [插桩] 参数: (2) ['0', 'a'] 2
    7100 [插桩] 返回值: 3
    执行分支--o 56 栈r--> [3]
    执行分支--o -910 栈r--> []
    执行分支--o -5375 栈r--> [-910]
    执行分支--o 56 栈r--> [-910,-5375]
    执行分支--o 6285 栈r--> [-6285]
    执行分支--o 5 栈r--> [-6285,6285]
    执行分支--o 32 栈r--> [0]
    执行分支--o 72 栈r--> [0,0]
    执行分支--o 3 栈r--> [true]
    执行分支--o 14 栈r--> []
    执行分支--o 4 栈r--> []
    执行分支--o 68 栈r--> [""]
    执行分支--o 56 栈r--> [""]
    执行分支--o -3847 栈r--> []
    执行分支--o -737 栈r--> [-3847]
    执行分支--o 56 栈r--> [-3847,-737]
    执行分支--o 4584 栈r--> [-4584]
    执行分支--o 11 栈r--> [-4584,4584]
    执行分支--o 68 栈r--> [0]
    执行分支--o 29 栈r--> [0]
    执行分支--o 49 栈r--> []
    执行分支--o 85 栈r--> []
    执行分支--o 40 栈r--> [0]
    执行分支--o 22 栈r--> [0,["0","a","2"]]
    我们还是接着向下看,我们发现这个短数组["0","a","2"] 不知道参与了什么变成了 02a,继续向下看,又产生了一个新的字符串 q02amwhwwpphm331
    这个字符串你会发现他是由好几部分拼接而成的。q 02a mwhwwpphm33 1
    其中 q和mwhwwpphm33都是通过一个函数生产的。


    6.png (104.13 KB, 下载次数: 0)
    下载附件
    2025-5-9 16:35 上传

    这个函数直接扣就行,不算难点。代码如下:
    const randomHelper = {
      cgmkT(x, y) {
        return Math.floor(x * y);
      }
    };
    function generateRandomString(config) {
      for (var length = config.size, pool = config.num, result = ''; length--; )
          result += pool[randomHelper.cgmkT(Math.random(), pool.length) | 0];
      console.log(config)
      return result;
    }
    那么这个size咋来的,这里就需要断点分析了,这就是为什么我要打出执行分支。这里size也是一个随机数参数的
    执行分支-->a 19 栈d--> []
    执行分支-->a 44 栈d--> [null]
    执行分支-->a 60 栈d--> [null,null]
    执行分支-->a 95 栈d--> [null,null,{}]
    执行分支-->a 1 栈d--> [null,null,{},1]
    执行分支-->a 95 栈d--> [null,null,{"size":1}]
    执行分支-->a 2 栈d--> [null,null,{"size":1},"jhqw3pm"]
    执行分支-->a 99 栈d--> [null,null,{"size":1,"num":"jhqw3pm"}]
    我们看到在分支1第一次出现,那么我们在他的上级95打上断点查看执行了什么。


    8.png (25.09 KB, 下载次数: 0)
    下载附件
    2025-5-9 16:35 上传

    简单搜一下


    9.png (69.62 KB, 下载次数: 0)
    下载附件
    2025-5-9 16:35 上传

    很好,将断点设置为46


    10.png (65.32 KB, 下载次数: 0)
    下载附件
    2025-5-9 16:35 上传

    我们得到如下:


    11.png (114.64 KB, 下载次数: 0)
    下载附件
    2025-5-9 16:35 上传

    那么很明显了。这个size就是随机数 * 10 | 0 得到的。
    那么后面那个size是怎么得到的呢,也很简单。就是固定13-size-1。这里你可以多大几分日志对比。后面那个1也是这个随机的size
    现在最难的就是这个02a。
    短串分析
    准备好,超长日志再次准备出现 ["0","a","2"] --> 02a


    12.png (102.51 KB, 下载次数: 0)
    下载附件
    2025-5-9 16:35 上传

    这里比较难,需要你自己多打几分日志对比


    13.png (102.55 KB, 下载次数: 0)
    下载附件
    2025-5-9 16:35 上传



    14.png (238.26 KB, 下载次数: 0)
    下载附件
    2025-5-9 16:35 上传

    这里代码我就不给出了,核心点在于计算取数,取数之后更新数组,后面再到新数组取数,再更新。
    6955 [插桩] 调用函数: ƒ random() { [native code] }
    6956 [插桩] 参数: Math {abs: ƒ, acos: ƒ, acosh: ƒ, asin: ƒ, asinh: ƒ, …}
    6960 [插桩] 返回值: 0.26127766219234505
    6921 执行分支--o 40 栈r--> [0.26127766219234505]
    6921 执行分支--o 90 栈r--> [0.26127766219234505,["0","a","2"]]
    6921 执行分支--o 61 栈r--> [0.26127766219234505,3]
    6921 执行分支--o 63 栈r--> [0.26127766219234505,3,0]
    6921 执行分支--o 56 栈r--> [0.26127766219234505,3]
    6921 执行分支--o -9420 栈r--> [0.7838329865770352]
    6921 执行分支--o -126 栈r--> [0.7838329865770352,-9420]
    6921 执行分支--o 56 栈r--> [0.7838329865770352,-9420,-126]
    6921 执行分支--o 9546 栈r--> [0.7838329865770352,-9546]
    6921 执行分支--o 94 栈r--> [0.7838329865770352,-9546,9546]
    6921 执行分支--o 67 栈r--> [0.7838329865770352,0]
    6921 执行分支--o 68 栈r--> [0]
    6921 执行分支--o 13 栈r--> [0]
    6921 执行分支--o 85 栈r--> []
    6921 执行分支--o 53 栈r--> [""]
    6921 执行分支--o 3 栈r--> ["",["0","a","2"]]
    6921 执行分支--o 20 栈r--> ["",["0","a","2"],0]
    6921 执行分支--o 51 栈r--> ["","0"]
    6921 执行分支--o 68 栈r--> ["0"]
    6921 执行分支--o 85 栈r--> ["0"]
    6921 执行分支--o 53 栈r--> []
    6921 执行分支--o 85 栈r--> [["0","a","2"]]
    6921 执行分支--o 85 栈r--> [["0","a","2"],0]
    6921 执行分支--o 40 栈r--> [["0","a","2"],0,["0","a","2"]]
    6921 执行分支--o 90 栈r--> [["0","a","2"],0,["0","a","2"],["0","a","2"]]
    6921 执行分支--o 61 栈r--> [["0","a","2"],0,["0","a","2"],3]
    6921 执行分支--o 56 栈r--> [["0","a","2"],0,["0","a","2"],3,0]
    6921 执行分支--o 1547 栈r--> [["0","a","2"],0,["0","a","2"],3]
    6921 执行分支--o 5708 栈r--> [["0","a","2"],0,["0","a","2"],3,1547]
    6921 执行分支--o 56 栈r--> [["0","a","2"],0,["0","a","2"],3,1547,5708]
    6921 执行分支--o -7254 栈r--> [["0","a","2"],0,["0","a","2"],3,7255]
    6921 执行分支--o 61 栈r--> [["0","a","2"],0,["0","a","2"],3,7255,-7254]
    6921 执行分支--o 3 栈r--> [["0","a","2"],0,["0","a","2"],3,1]
    6921 执行分支--o 84 栈r--> [["0","a","2"],0,["0","a","2"],2]
    6921 执行分支--o 68 栈r--> [["0","a","2"],0,"2"]
    6921 执行分支--o 14 栈r--> ["2"]
    6921 执行分支--o 68 栈r--> []
    6921 执行分支--o 90 栈r--> [0]
    6921 执行分支--o 85 栈r--> []
    6921 执行分支--o 40 栈r--> [1]
    6921 执行分支--o 22 栈r--> [1,["2","a","2"]]
    6921 执行分支--o 70 栈r--> [1,3]
    6921 执行分支--o -53 栈r--> [true]
    6921 执行分支--o 47 栈r--> []
    6921 执行分支--o 1 栈r--> [{}]
    6921 执行分支--o 85 栈r--> [null,{}]
    6954 [插桩] 分支1 - 调用 i.call
    6955 [插桩] 调用函数: ƒ random() { [native code] }
    6956 [插桩] 参数: Math {abs: ƒ, acos: ƒ, acosh: ƒ, asin: ƒ, asinh: ƒ, …}
    6960 [插桩] 返回值: 0.1915809302903172
    6921 执行分支--o 40 栈r--> [0.1915809302903172]
    6921 执行分支--o 90 栈r--> [0.1915809302903172,["2","a","2"]]
    6921 执行分支--o 61 栈r--> [0.1915809302903172,3]
    6921 执行分支--o 63 栈r--> [0.1915809302903172,3,1]
    6921 执行分支--o 56 栈r--> [0.1915809302903172,2]
    6921 执行分支--o -9420 栈r--> [0.3831618605806344]
    6921 执行分支--o -126 栈r--> [0.3831618605806344,-9420]
    6921 执行分支--o 56 栈r--> [0.3831618605806344,-9420,-126]
    6921 执行分支--o 9546 栈r--> [0.3831618605806344,-9546]
    6921 执行分支--o 94 栈r--> [0.3831618605806344,-9546,9546]
    6921 执行分支--o 67 栈r--> [0.3831618605806344,0]
    6921 执行分支--o 68 栈r--> [0]
    6921 执行分支--o 13 栈r--> [0]
    6921 执行分支--o 85 栈r--> []
    6921 执行分支--o 53 栈r--> ["0"]
    6921 执行分支--o 3 栈r--> ["0",["2","a","2"]]
    6921 执行分支--o 20 栈r--> ["0",["2","a","2"],0]
    6921 执行分支--o 51 栈r--> ["0","2"]
    6921 执行分支--o 68 栈r--> ["02"]
    6921 执行分支--o 85 栈r--> ["02"]
    6921 执行分支--o 53 栈r--> []
    6921 执行分支--o 85 栈r--> [["2","a","2"]]
    6921 执行分支--o 85 栈r--> [["2","a","2"],0]
    6921 执行分支--o 40 栈r--> [["2","a","2"],0,["2","a","2"]]
    6921 执行分支--o 90 栈r--> [["2","a","2"],0,["2","a","2"],["2","a","2"]]
    6921 执行分支--o 61 栈r--> [["2","a","2"],0,["2","a","2"],3]
    6921 执行分支--o 56 栈r--> [["2","a","2"],0,["2","a","2"],3,1]
    6921 执行分支--o 1547 栈r--> [["2","a","2"],0,["2","a","2"],2]
    6921 执行分支--o 5708 栈r--> [["2","a","2"],0,["2","a","2"],2,1547]
    6921 执行分支--o 56 栈r--> [["2","a","2"],0,["2","a","2"],2,1547,5708]
    6921 执行分支--o -7254 栈r--> [["2","a","2"],0,["2","a","2"],2,7255]
    6921 执行分支--o 61 栈r--> [["2","a","2"],0,["2","a","2"],2,7255,-7254]
    6921 执行分支--o 3 栈r--> [["2","a","2"],0,["2","a","2"],2,1]
    6921 执行分支--o 84 栈r--> [["2","a","2"],0,["2","a","2"],1]
    6921 执行分支--o 68 栈r--> [["2","a","2"],0,"a"]
    6921 执行分支--o 14 栈r--> ["a"]
    6921 执行分支--o 68 栈r--> []
    6921 执行分支--o 90 栈r--> [1]
    6921 执行分支--o 85 栈r--> []
    6921 执行分支--o 40 栈r--> [2]
    6921 执行分支--o 22 栈r--> [2,["a","a","2"]]
    6921 执行分支--o 70 栈r--> [2,3]
    6921 执行分支--o -53 栈r--> [true]
    6921 执行分支--o 47 栈r--> []
    6921 执行分支--o 1 栈r--> [{}]
    6921 执行分支--o 85 栈r--> [null,{}]
    6954 [插桩] 分支1 - 调用 i.call
    6955 [插桩] 调用函数: ƒ random() { [native code] }
    6956 [插桩] 参数: Math {abs: ƒ, acos: ƒ, acosh: ƒ, asin: ƒ, asinh: ƒ, …}
    6960 [插桩] 返回值: 0.11069052654495881
    6921 执行分支--o 40 栈r--> [0.11069052654495881]
    6921 执行分支--o 90 栈r--> [0.11069052654495881,["a","a","2"]]
    6921 执行分支--o 61 栈r--> [0.11069052654495881,3]
    6921 执行分支--o 63 栈r--> [0.11069052654495881,3,2]
    6921 执行分支--o 56 栈r--> [0.11069052654495881,1]
    6921 执行分支--o -9420 栈r--> [0.11069052654495881]
    6921 执行分支--o -126 栈r--> [0.11069052654495881,-9420]
    6921 执行分支--o 56 栈r--> [0.11069052654495881,-9420,-126]
    6921 执行分支--o 9546 栈r--> [0.11069052654495881,-9546]
    6921 执行分支--o 94 栈r--> [0.11069052654495881,-9546,9546]
    6921 执行分支--o 67 栈r--> [0.11069052654495881,0]
    6921 执行分支--o 68 栈r--> [0]
    6921 执行分支--o 13 栈r--> [0]
    6921 执行分支--o 85 栈r--> []
    6921 执行分支--o 53 栈r--> ["02"]
    6921 执行分支--o 3 栈r--> ["02",["a","a","2"]]
    6921 执行分支--o 20 栈r--> ["02",["a","a","2"],0]
    6921 执行分支--o 51 栈r--> ["02","a"]
    6921 执行分支--o 68 栈r--> ["02a"]
    6921 执行分支--o 85 栈r--> ["02a"]
    6921 执行分支--o 53 栈r--> []
    6921 执行分支--o 85 栈r--> [["a","a","2"]]
    6921 执行分支--o 85 栈r--> [["a","a","2"],0]
    6921 执行分支--o 40 栈r--> [["a","a","2"],0,["a","a","2"]]
    6921 执行分支--o 90 栈r--> [["a","a","2"],0,["a","a","2"],["a","a","2"]]
    6921 执行分支--o 61 栈r--> [["a","a","2"],0,["a","a","2"],3]
    6921 执行分支--o 56 栈r--> [["a","a","2"],0,["a","a","2"],3,2]
    6921 执行分支--o 1547 栈r--> [["a","a","2"],0,["a","a","2"],1]
    6921 执行分支--o 5708 栈r--> [["a","a","2"],0,["a","a","2"],1,1547]
    6921 执行分支--o 56 栈r--> [["a","a","2"],0,["a","a","2"],1,1547,5708]
    6921 执行分支--o -7254 栈r--> [["a","a","2"],0,["a","a","2"],1,7255]
    6921 执行分支--o 61 栈r--> [["a","a","2"],0,["a","a","2"],1,7255,-7254]
    6921 执行分支--o 3 栈r--> [["a","a","2"],0,["a","a","2"],1,1]
    6921 执行分支--o 84 栈r--> [["a","a","2"],0,["a","a","2"],0]
    6921 执行分支--o 68 栈r--> [["a","a","2"],0,"a"]
    6921 执行分支--o 14 栈r--> ["a"]
    6921 执行分支--o 68 栈r--> []
    6921 执行分支--o 90 栈r--> [2]
    6921 执行分支--o 85 栈r--> []
    6921 执行分支--o 40 栈r--> [3]
    6921 执行分支--o 22 栈r--> [3,["a","a","2"]]
    6921 执行分支--o 70 栈r--> [3,3]
    6921 执行分支--o -53 栈r--> [false]
    6921 执行分支--o 66 栈r--> []
    6921 执行分支--o 80 栈r--> ["02a"]
    7177 [插桩] 返回值: 02a
    执行分支-->a 71 栈d--> ["02a"]
    执行分支-->a 23 栈d--> ["02a"]
    后面就简单了,其实你解开上面这段就基本上完成这个逆向了。
    我把日志整理一下如下:
    7194 [插桩] 参数: ƒ slice() { [native code] } (16) ['q', '0', '2', 'a', 'm', 'w', 'h', 'w', 'w', 'p', 'p', 'h', 'm', '3', '3', '1'] 0 9
    7198 [插桩] 返回值: (9) ['q', '0', '2', 'a', 'm', 'w', 'h', 'w', 'w']
    这里就是一个简单的切割
    6628 [插桩] 调用函数: ƒ pop() { [native code] }
    6629 [插桩] 参数: (9) ['q', '0', '2', 'a', 'm', 'w', 'h', 'w', 'w']
    6633 [插桩] 返回值: w
    这里就是从后面取数
    执行分支-->a 36 栈d--> [null,[],null,省略,35,null,null,"w"]
    执行分支-->a 85 栈d--> [null,[],null,省略,35,null,null,"w",36]
    7171 [插桩] 调用 x.call
    7172 [插桩] 调用函数: ƒ parseInt() { [native code] }
    7173 [插桩] 参数: null w 36
    7177 [插桩] 返回值: 32
    执行分支-->a 21 栈d--> [null,[],null,省略,35,32]
    7171 [插桩] 调用 x.call
    7172 [插桩] 调用函数: ƒ (_$VA, _$VL) {
                return _$VA - _$VL;
            }
    7173 [插桩] 参数: {QuHhA: 'function', DPusW: ƒ, KzvJS: ƒ, TxipF: ƒ, Ufhnc: ƒ, …} 35 32
    7177 [插桩] 返回值: 3
    执行分支-->a 10 栈d--> [null,[],3]
    执行分支-->a 5591 栈d--> [null,[],null,3]
    执行分支-->a -2258 栈d--> [null,[],null,3,5591]
    执行分支-->a 23 栈d--> [null,[],null,3,5591,-2258]
    执行分支-->a -3297 栈d--> [null,[],null,3,3333]
    执行分支-->a 65 栈d--> [null,[],null,3,3333,-3297]
    执行分支-->a 65 栈d--> [null,[],null,3,36]
    6861 [插桩] 分支1 - 调用 x.call
    6862 [插桩] 调用函数: ƒ toString() { [native code] }
    6863 [插桩] 参数: 3 36
    6867 [插桩] 返回值: 3
    执行分支-->a 71 栈d--> [null,[],"3"]
    6861 [插桩] 分支1 - 调用 x.call
    6862 [插桩] 调用函数: ƒ push() { [native code] }
    6863 [插桩] 参数: [] 3
    这里就是将 取出的字符通过 parseInt(取出的,36) 然后被35 减去 再通过 toString(36)
    6627 [插桩] case 34 - 分支1 - 调用 x.call
    6628 [插桩] 调用函数: ƒ pop() { [native code] }
    6629 [插桩] 参数: (8) ['q', '0', '2', 'a', 'm', 'w', 'h', 'w']
    6633 [插桩] 返回值: w
    执行分支-->a 36 栈d--> [null,["3"],null,省略,35,null,null,"w"]
    执行分支-->a 85 栈d--> [null,["3"],null,省略,35,null,null,"w",36]
    7171 [插桩] 调用 x.call
    7172 [插桩] 调用函数: ƒ parseInt() { [native code] }
    7173 [插桩] 参数: null w 36
    7177 [插桩] 返回值: 32
    执行分支-->a 21 栈d--> [null,["3"],null,省略,35,32]
    7171 [插桩] 调用 x.call
    7172 [插桩] 调用函数: ƒ (_$VA, _$VL) {
                return _$VA - _$VL;
            }
    7173 [插桩] 参数: {QuHhA: 'function', DPusW: ƒ, KzvJS: ƒ, TxipF: ƒ, Ufhnc: ƒ, …} 35 32
    7177 [插桩] 返回值: 3
    执行分支-->a 10 栈d--> [null,["3"],3]
    执行分支-->a 5591 栈d--> [null,["3"],null,3]
    执行分支-->a -2258 栈d--> [null,["3"],null,3,5591]
    执行分支-->a 23 栈d--> [null,["3"],null,3,5591,-2258]
    执行分支-->a -3297 栈d--> [null,["3"],null,3,3333]
    执行分支-->a 65 栈d--> [null,["3"],null,3,3333,-3297]
    执行分支-->a 65 栈d--> [null,["3"],null,3,36]
    6861 [插桩] 分支1 - 调用 x.call
    6862 [插桩] 调用函数: ƒ toString() { [native code] }
    6863 [插桩] 参数: 3 36
    6867 [插桩] 返回值: 3
    执行分支-->a 71 栈d--> [null,["3"],"3"]
    6861 [插桩] 分支1 - 调用 x.call
    6862 [插桩] 调用函数: ƒ push() { [native code] }
    6863 [插桩] 参数: ['3'] 3
    一样的
    6628 [插桩] 调用函数: ƒ pop() { [native code] }
    6629 [插桩] 参数: (7) ['q', '0', '2', 'a', 'm', 'w', 'h']
    6633 [插桩] 返回值: h
    执行分支-->a 36 栈d--> [null,["3","3"],null,省略,35,null,null,"h"]
    执行分支-->a 85 栈d--> [null,["3","3"],null,省略,35,null,null,"h",36]
    7171 [插桩] 调用 x.call
    7172 [插桩] 调用函数: ƒ parseInt() { [native code] }
    7173 [插桩] 参数: null h 36
    7177 [插桩] 返回值: 17
    执行分支-->a 21 栈d--> [null,["3","3"],null,省略,35,17]
    7171 [插桩] 调用 x.call
    7172 [插桩] 调用函数: ƒ (_$VA, _$VL) {
                return _$VA - _$VL;
            }
    7173 [插桩] 参数: {QuHhA: 'function', DPusW: ƒ, KzvJS: ƒ, TxipF: ƒ, Ufhnc: ƒ, …} 35 17
    7177 [插桩] 返回值: 18
    执行分支-->a 10 栈d--> [null,["3","3"],18]
    执行分支-->a 5591 栈d--> [null,["3","3"],null,18]
    执行分支-->a -2258 栈d--> [null,["3","3"],null,18,5591]
    执行分支-->a 23 栈d--> [null,["3","3"],null,18,5591,-2258]
    执行分支-->a -3297 栈d--> [null,["3","3"],null,18,3333]
    执行分支-->a 65 栈d--> [null,["3","3"],null,18,3333,-3297]
    执行分支-->a 65 栈d--> [null,["3","3"],null,18,36]
    6861 [插桩] 分支1 - 调用 x.call
    6862 [插桩] 调用函数: ƒ toString() { [native code] }
    6863 [插桩] 参数: 18 36
    6867 [插桩] 返回值: i
    执行分支-->a 71 栈d--> [null,["3","3"],"i"]
    6861 [插桩] 分支1 - 调用 x.call
    6862 [插桩] 调用函数: ƒ push() { [native code] }
    6863 [插桩] 参数: (2) ['3', '3'] i
    你可以验证一下
    最后我们得到["3","3","i","3","d","p","x","z","9"] 这个和之前切割的后面一部分拼接就是我们的_fingerprint啦
    小结一下
    这个没有复杂计算基本上全是随机值。所以推理起来不算太难。但是他也不是很简单。只有自己关掉教程搞出来才知道是不是真的简单。
    如有错误,还请大佬指出谢谢!!!
    最后感谢大佬的观看,也感谢大佬们的支持。如果你有好玩的网站或者app可以私信我,如果有教学意义,并且无风险,我会出详细教程的。

    log.zip
    (28.96 KB, 下载次数: 20)
    2025-5-9 16:41 上传
    点击文件名下载附件
    下载积分: 吾爱币 -1 CB

    分支, 函数

  • yellowspider   

    大佬大佬,膜拜膜拜
    hackest   

    可惜是JS 来个APP的啊
    amwquhwqas128   

    感激大佬的分享知识文章
    twl288   

    谢谢,虽然我看不懂
    xue888   

    厉害厉害 好好学习
    wasm2023   

    楼主,可以试试猿人学第二届的题目,尤其是第10题
    utf8
    OP
      


    wasm2023 发表于 2025-5-10 11:27
    楼主,可以试试猿人学第二届的题目,尤其是第10题

    好像之前做过,不知道放哪里了
    lyyzs7742   

    配套的题目
    wasm2023   


    utf8 发表于 2025-5-10 17:21
    好像之前做过,不知道放哪里了

    知乎的vmp套wasm vmp也可以试试
    您需要登录后才可以回帖 登录 | 立即注册

    返回顶部