简单探究某站指纹参数算法

查看 34|回复 3
作者:utf8   
简单探究某站指纹参数算法
近期较忙,这个是6月的最后一篇文章啦。后续要写什么我还需要好好思考。
本文仅供学习交流,因使用本文内容而产生的任何风险及后果,作者不承担任何责任,一起学习吧

目标接口: 个人主页info

接口情况如下:


1.png (98.25 KB, 下载次数: 0)
下载附件
2025-6-21 11:01 上传

确认逆向参数
[ol]
  • dm_img_str
  • dm_cover_img_str
  • dm_img_inter
  • w_webid
  • w_rid
  • wts
    [/ol]
    本文的重点是dm_img_str和dm_cover_img_str,w_rid现在网络上有不少文章相信你一定可以读懂的,所以就不将重点放在这个参数上。接下来,请跟着我一步步去分析,看看遇到一个逆向参数问题,我是如何思考的。
    逆向“搜”当先
    面对复杂的参数,先不要慌张,直接搜索片段,看看它是否能够被搜到。它可能来源于其他包,有可能就是一个简单的固定值,不要因为长而乱就自乱阵脚。
    通过搜索,我们发现w_webid就是主页HTML返回的


    2.png (127.17 KB, 下载次数: 0)
    下载附件
    2025-6-21 11:01 上传

    很好,那我们可以打上断点看看,到底是个什么情况。
    简单分析我们可以知道,它将这段乱码通过JSON.parse(decodeURIComponent())函数赋值给了window._render_data_


    3.png (425.74 KB, 下载次数: 0)
    下载附件
    2025-6-21 11:00 上传

    那么这个参数我们就搞定了。接下来看看dm_img_str
    参数分析
    还是一样,先搜后看堆栈。
    搜索结果如下:


    4.png (50.15 KB, 下载次数: 0)
    下载附件
    2025-6-21 11:00 上传

    不知道对不对,先进去打上断点。逆向永远是在试错的路上


    5.png (56.29 KB, 下载次数: 0)
    下载附件
    2025-6-21 11:00 上传

    这里我们可以发现,这些参数均来自
    [s,c,l,u] = window.__biliUserFp__.queryUserLog({
                ...i,
                target: a
            });
    在这里打上断点,刷新。向下步入。欸,我们进入了


    6.png (140.1 KB, 下载次数: 0)
    下载附件
    2025-6-21 11:00 上传

    看文件名字,基本上就知道是这个没错了。让我们找到函数的出口,向上看。
    在函数出口(return)处打上断点,看看我们找到位置是否正确,同时向上看思考更加清晰明确。


    7.png (54.66 KB, 下载次数: 0)
    下载附件
    2025-6-21 11:00 上传

    很好,基本确定是这里。接下来就是简单的函数扣取和函数简化。
    function fp(_0x645cbb) {
        var _0x504ef3 = _0x24be7c  // 如果你对ob混淆很熟悉,那么这个还原会很简单。
            , _0x2d5ecc = _0x645cbb[_0x504ef3(0x11e)]
            , _0x268943 = _0x645cbb['startTime']
            , _0x366fc6 = _0x645cbb['endTime']
            , _0x44234a = _0x645cbb[_0x504ef3(0xbc)];
        if (!this[_0x504ef3(0xaf)]) {
            var _0x398e6b = window[_0x504ef3(0xb9)];
            this[_0x504ef3(0x10a)](_0x398e6b || {});
        }
        var _0x45e018 = function(_0x5c3c27) {
            var _0xd43606 = _0x504ef3
                , _0x1a00cf = _0x5c3c27[_0xd43606(0x8c)](function(_0x436c1d, _0x1c4ea4) {
                var _0x2f1045 = _0xd43606
                    , _0x489e4e = _0x436c1d['x']
                    , _0x3168c2 = void 0x0 === _0x489e4e ? 0x0 : _0x489e4e
                    , _0x45fa28 = _0x436c1d['y']
                    , _0x384e98 = void 0x0 === _0x45fa28 ? 0x0 : _0x45fa28
                    , _0x510a04 = _0x436c1d[_0x2f1045(0xa2)]
                    , _0x5ce436 = _0x436c1d[_0x2f1045(0x113)]
                    , _0x8a367f = _0x436c1d[_0x2f1045(0x104)];
                return _0x3e1d8f(_0x3168c2, _0x384e98, _0x510a04, _0x5ce436, _0x1c4ea4, _0x8a367f);
            })
                , _0x532efb = _0x1a00cf['map'](function(_0x2d90b5) {
                return {
                    'x': _0x2d90b5[0x0],
                    'y': _0x2d90b5[0x1],
                    'z': _0x2d90b5[0x2],
                    'timestamp': _0x2d90b5[0x3],
                    'k': _0x2d90b5[0x4],
                    'type': _0x2d90b5[0x5]
                };
            });
            try {
                return JSON[_0xd43606(0x129)](_0x532efb);
            } catch (_0x8d1795) {
                return console[_0xd43606(0x97)](_0x8d1795),
                '';
            }
        }(_0x2d5ecc ? this[_0x504ef3(0xaf)][_0x504ef3(0xe2)](_0x2d5ecc) : this[_0x504ef3(0xaf)]['getLog'](_0x268943, _0x366fc6));
        return [_0x45e018, _0x28b679(this[_0x504ef3(0xaf)]['webglStr']), _0x28b679(this['instance'][_0x504ef3(0x9a)]), this['instance']['getActiveFeaturesStr'](_0x44234a)];
    }
    还是一样,缺什么补什么,这里仁者见仁智者见智,你可以缺的扣,也可以直接改写函数。但是最重要的还是你自己去跟
    _0x504ef3 :这个就是字符串还原。我们从下面往上分析代码,发现这个函数返回值不关心前面部分。
    var _0x504ef3 = _0x24be7c  
        , _0x2d5ecc = _0x645cbb[_0x504ef3(0x11e)]
        , _0x268943 = _0x645cbb['startTime']
        , _0x366fc6 = _0x645cbb['endTime']
        , _0x44234a = _0x645cbb[_0x504ef3(0xbc)];
    if (!this[_0x504ef3(0xaf)]) {
        var _0x398e6b = window[_0x504ef3(0xb9)];
        this[_0x504ef3(0x10a)](_0x398e6b || {});
    }
    那么分析重点就是_0x45e018,这个是一个自执行函数的返回值,还是一样,直接去找函数出口(return),JSON['stringify'](_0x532efb);,就是这样一步步向上找,分析。最后你会发现这个就是个空列表,那么这甚至不用写成函数。接着看剩下三个,还原算法不算难,这里我只放几个关键图片,大家自己去动手分析(也为了防止伸手党)。


    8.png (39.25 KB, 下载次数: 0)
    下载附件
    2025-6-21 11:00 上传



    9.png (26.59 KB, 下载次数: 0)
    下载附件
    2025-6-21 11:00 上传



    10.png (28.01 KB, 下载次数: 0)
    下载附件
    2025-6-21 11:00 上传



    11.png (20.05 KB, 下载次数: 0)
    下载附件
    2025-6-21 11:00 上传

    小结
    这个指纹算法确实不算难,大家认真分析绝对是没啥问题的。这段时间太忙了,简单水个文章哈哈哈

    下载次数, 参数

  • buluo533   

    有一点不懂的是怎么去判断和找指纹呢
    wapj1688   

    后续要写什么我还需要好好思考。
    linswin   

    收藏学习,谢谢大佬分享。
    您需要登录后才可以回帖 登录 | 立即注册

    返回顶部