上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖

抖音JSVMP算法逆向(一)

[复制链接]
  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    611

    主题

    4982

    回帖

    5855

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    5855

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2023-12-8 23:42:14 | 显示全部楼层 | 阅读模式

    FBI WARNING

    本文基于渔歌的教程以及K哥爬虫的抖音分析得来
    https://cloud.tencent.com/developer/article/2208864

    正文

    抓包地址设为我最喜欢的主播 云雀Qqq
    https://www.douyin.com/user/MS4wLjABAAAAwHlnPXaL8Is7itEu8SHMocTc3V1zdU4X2sjZVKeNHro?vid=7308030273759776015
    抓包发现视频加载地址为

    https://www.douyin.com/aweme/v1/web/aweme/post/?device_platform=webapp&aid=6382&channel=channel_pc_web&sec_user_id=MS4wLjABAAAAwHlnPXaL8Is7itEu8SHMocTc3V1zdU4X2sjZVKeNHro&max_cursor=0&locate_item_id=25424245245245524&locate_query=false&show_live_replay_strategy=1&need_time_list=1&time_list_query=0&whale_cut_token=&cut_version=1&count=18&publish_video_strategy_type=2&pc_client_type=1&version_code=1704010&version_name=17.4.0&cookie_enabled=true&screen_width=1436&screen_height=864&browser_language=zh-CN&browser_platform=Win32&browser_name=Chrome&browser_version=119.0.0.0&browser_online=true&engine_name=Blink&engine_version=119.0.0.0&os_name=Windows&os_version=10&cpu_core_num=16&device_memory=8&platform=PC&downlink=10&effective_type=4g&round_trip_time=50&webid=73026748115794832422&msToken=6VCiWBzn1jh29Fcw2HpZokry78bf6ACWAFHGKLCetv9xwuuHBC0GLAqc5kWD9Pd49qBhe3glQHLT4VCo2zVHo27-Ughk4DeRjFv-bP4Su2-_Ed1BLWPs=&X-Bogus=DFSzswVOKRxANtOstzKMGe9WX7JJ

    sec_user_id 博主id
    msToken和X-Bogus是我们的这次主要目标
    分别为6VCiWBzn1jh29Fcw2HpZokr3635f69JMcYRKLCetv9xw363635BC0GLAqc5kWD9Pd49qBhe3glQHLT4VCo2zVHo27-Ughk4DeRjFv-bP4Su2-_Ed1BLWPs=
    以及DFSzswVOKRxANtOsFAAFAMme9WX7JJ
    根据测试msToken为本地存储中
    图片.png
    那我们的主要目标就是X-Bogus
    打下xhr断点
    图片.png
    断下后堆栈回溯找到了
    图片.png
    这种基本就是jsvmp加密了
    jsvmp是将原有的代码进行转义成字节码的形式
    将大量函数聚集在一个函数中,打乱原有的代码形式,变为字节码控制
    同时将函数的变量声明转为堆栈式,将返回内容,函数的调用等都由转义后的代码进行管理
    相比ob易解混淆来说更难以进行分析
    我们在这里采用插装法
    首先覆盖文件
    将原有的代码复制,使用v_jstools将变量进行压缩
    图片.png
    覆盖文件后再次触发Xhr断点进行观察
    这里O是一个全局变量的管理对象
    通过S控制变量的弹出和塞入
    P控制执行哪部分的代码
    图片.png
    一直往上走可以找到
    可以看到for指令
    其中P通过j运算得出,而j通过在a数组中A下标得到
    最后算出应该执行哪部分代码
    图片.png
    根据K哥的教程可以知道应该在全局的头部进行插桩来获取信息
    图片.png
    由于这里有两个大的for循环,所以我们最好每个都插一下
    K哥的代码是"位置 1", "索引I", I, "索引A", A, "值S: ", JSON.stringify(S, function(key, value) {if (value == window) {return undefined} return value})
    但是我实际测试发现触发XHR或者循环JSON会出现问题
    所以这里我用了一个try...catch捕获以及xhr过滤
    如果发现xhr对象就无视,如果发现存在循环就调用一个缓存来处理

              try {
                console.log(
                  "位置 1",
                  "索引j",
                  j,
                  "索引A",
                  A,
                  "值O: ",
                  JSON.stringify(O, function (key, value) {
                    if (value == window) {
                      return undefined;
                    }
                    if (value?.send !== undefined) {
                      return "xhr";
                    }
                    return value;
                  })
                );
              } catch (error) {
                if (
                  error.message.indexOf("Converting circular structure to JSON") !==
                  -1
                ) {
                  //循环模式
                  try {
                    let cache = [];
                    console.log(
                      "位置 1",
                      "索引j",
                      j,
                      "索引A",
                      A,
                      "值O: ",
                      JSON.stringify(O, function (key, value) {
                        if (typeof value === "object" && value !== null) {
                          if (cache.indexOf(value) !== -1) {
                            return;
                          }
                          cache.push(value);
                        }
                        if (value == window) {
                          return undefined;
                        }
                        if (value?.send !== undefined) {
                          return "xhr";
                        }
                        return value;
                      })
                    );
                    cache = null; // reset the cache
                  } catch (error) {
                    debugger;
                  }
                } else {
                  debugger;
                }
              }

    由于覆盖文件了,我就直接在里面写了
    同时加了一个window.log更方便什么时候捕捉数据
    图片.png
    一共两个点都插入抓了大概8w条数据
    搜索xhr断下得到的X-Bogus找到了数据,最后一次是生成9
    图片.png
    9的生成在9的上一个null和9之间
    位置是位置 2 索引j 16 索引A 716 值O:
    同时为了更好的限制数据可以下条件断点j===16&A===716&O[7]===21
    这部分是K哥爬虫的经验,是多次抓数据进行比对,最后找到的O最后一位具有一定的特征点
    下断停到了
    图片.png
    其中P是charat,m是字符表,w是数组
    说明是取字符表中特定位置的数据
    图片.png
    我们原数据中是的W刚好对应了(不同批次抓的数据,有少许出入,只要逻辑贯通就可以)
    图片.png
    那问题变成了两个
    1.这个字符串是怎么生成的?
    2.这个数字是怎么得来的?

    我们过两天继续研究...

    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表