QQ音乐sign vmp逆向

定位

复制代码
return u = ie(r.data)

跟进return u = ie(r.data)

发现是个vmp

下日志断点然后分析log日志

分析

前缀

7CB69B11F03F540463B696AE679DF97A7ED34709

复制代码
通过将log给ai,ai告诉我说这是sha1

入参是啥?

复制代码
搜索 finalize
发现一个数组 SHA-1 常量 [undefined, 1732584193, 4023233417, 2562383102, 3285377520, false, true, 2147483648, 4294967295, 4294967296, 1518500249, 1859775393, 1894007588]

分析得知
{"comm":{"cv":4747474,"ct":24,"format":"json","inCharset":"utf-8","outCharset":"utf-8","notice":0,"platform":"yqq.json","needNewCode":1,"uin":2573298872,"g_tk_new_20200303":1415120135,"g_tk":1415120135},"req_1":{"module":"music.musicsearch.HotkeyService","method":"GetHotkeyForQQMusicMobile","param":{"searchid":"32782922762486672","remoteplace":"txt.yqq.top","from":"yqqweb"}},"req_2":{"module":"music.musicHall.MusicHallPlatformSvr","method":"GetFocus","param":{"ForceBig":1}},"req_3":{"module":"newalbum.NewAlbumServer","method":"get_new_album_area","param":{}},"req_4":{"module":"newalbum.NewAlbumServer","method":"get_new_album_info","param":{"area":1,"sin":0,"num":20}},"req_5":{"module":"musicToplist.ToplistInfoServer","method":"GetAll","param":{}},"req_6":{"module":"MvService.MvInfoProServer","method":"GetNewMv","param":{"style":0,"tag":0,"start":0,"size":40}},"req_7":{"module":"music.paycenterapi.LoginStateVerificationApi","method":"GetChargeAccount","param":{"appid":"mlive"}}}
得到 7CB69B11F03F540463B696AE679DF97A7ED34709

E014616分析

复制代码
h[16] = "7CB69B11F03F540463B696AE679DF97A7ED34709";
h[95] = [23, 14, 6, 36, 16, 40, 7, 19]; // 固定数组
h[139] = h[95].map(i => h[16][i]);
h[8] = h[139].join("");

h[16][23] = "E"
h[16][14] = "0"
h[16][6]  = "1"
h[16][36] = "4"
h[16][16] = "6"
h[16][40] = undefined
h[16][7]  = "1"
h[16][19] = "6"

得到 97DBD30 

中缀

复制代码
SHA1 十六进制字符串按 2 位一组转字节,然后和固定数组逐位 XOR。
十进制就是:
[124, 182, 155, 17, 240, 63, 84, 4, 99, 182, 150, 174, 103, 157, 249, 122, 126, 211, 71, 9]

日志里这个数组:
xor_key = [89, 39, 179, 150, 218, 82, 58, 252, 177, 52, 186, 123, 120, 64, 242, 133, 143, 161, 121, 179]

然后逐位异或:

124 ^ 89  = 37
182 ^ 39  = 145
155 ^ 179 = 40
17  ^ 150 = 135
240 ^ 218 = 42
...
9   ^ 179 = 186

[37, 145, 40, 135, 42, 109, 110, 248, 210, 130, 44, 213, 31, 221, 11, 255, 241, 114, 62, 186] base64
new RegExp("[\\/+]", "g") 正则将/去掉
JZEohyptbvjSgizVH90LFyPro

后缀

复制代码
SHA1 字符串
   ↓
用 [23,14,6,36,16,40,7,19] 抽字符
   ↓
得到 E014616
   ↓
用 E014616 作为种子/中间值
   ↓
生成 [16,1,32,12,19,27,8,5]
[16, 1, 32, 12, 19, 27, 8, 5] 解码
6C756DFB

拼接

复制代码
zzc + E014616 + JZEohyptbvjSgizVH90LFyPro + 6C756DFB

执行 toLowerCase

复制代码
zzce014616jzeohyptbvjsgizvh90lfypro6c756dfb

很简单 附代码

复制代码
import hashlib
import base64
import json
from typing import List


IDX_1 = [23, 14, 6, 36, 16, 40, 7, 19]
IDX_2 = [16, 1, 32, 12, 19, 27, 8, 5]

XOR_KEY = [
    89, 39, 179, 150, 218,
    82, 58, 252, 177, 52,
    186, 123, 120, 64, 242,
    133, 143, 161, 121, 179
]


def pick_chars(s: str, idx: List[int]) -> str:
    return "".join(s[i] if 0 <= i < len(s) else "" for i in idx)


def get_sign(json_str: str) -> str:
    sha1_hex = hashlib.sha1(json_str.encode("utf-8")).hexdigest().upper()

    part1 = pick_chars(sha1_hex, IDX_1)

    sha_bytes = bytes.fromhex(sha1_hex)

    xor_bytes = bytes(
        b ^ k
        for b, k in zip(sha_bytes, XOR_KEY)
    )

    mid = base64.b64encode(xor_bytes).decode()
    mid = mid.replace("/", "").replace("+", "").replace("=", "")

    part2 = pick_chars(sha1_hex, IDX_2)

    return "zzc" + part1 + mid + part2


data = {"comm":{"cv":4747474,"ct":24,"format":"json","inCharset":"utf-8","outCharset":"utf-8","notice":0,"platform":"yqq.json","needNewCode":1,"uin":2573298872,"g_tk_new_20200303":1415120135,"g_tk":1415120135},"req_1":{"module":"music.musicsearch.HotkeyService","method":"GetHotkeyForQQMusicMobile","param":{"searchid":"32782922762486672","remoteplace":"txt.yqq.top","from":"yqqweb"}},"req_2":{"module":"music.musicHall.MusicHallPlatformSvr","method":"GetFocus","param":{"ForceBig":1}},"req_3":{"module":"newalbum.NewAlbumServer","method":"get_new_album_area","param":{}},"req_4":{"module":"newalbum.NewAlbumServer","method":"get_new_album_info","param":{"area":1,"sin":0,"num":20}},"req_5":{"module":"musicToplist.ToplistInfoServer","method":"GetAll","param":{}},"req_6":{"module":"MvService.MvInfoProServer","method":"GetNewMv","param":{"style":0,"tag":0,"start":0,"size":40}},"req_7":{"module":"music.paycenterapi.LoginStateVerificationApi","method":"GetChargeAccount","param":{"appid":"mlive"}}}

json_str = json.dumps(data, separators=(",", ":"), ensure_ascii=False)

print(json_str)
print(get_sign(json_str).lower())

声明

本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!

本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请联系作者立即删除!

相关推荐
安_2 小时前
如何构建和使用向量索引?HNSW 和 IVF 有什么区别?
python·ai
counting money3 小时前
Java IO流详解:从InputStream到文件操作实战
java·开发语言·python
坚持学习前端日记4 小时前
Python SQLAlchemy ORM 从0到1精通实战手册(基础到复杂高阶)
数据库·python·oracle
北斗落凡尘4 小时前
LangGraph 入门实战(11)--输出模式
后端·python·langchain
雪碧聊技术5 小时前
安装Python(保姆级教程)
python·版本更新·python下载
++==5 小时前
JSON和Python的 四种核心容器
python·json
张龙6877 小时前
uv 全面指南:比 pip 快 100 倍的 Python 包管理器,从安装到团队落地
后端·python
@HNUSTer8 小时前
Python数据可视化科技图表绘制系列教程(八)
python·数据可视化·科技论文·专业制图·科研图表
专注仿真9 小时前
问答大模型技术方案算法实现-熵权法融合算法 + 交叉编码器重排算法
人工智能·python·算法·语言模型·问答大模型关键算法·熵权融合算法·交叉编码器重排算法
满怀冰雪9 小时前
22-使用 PaddleClas 快速训练图像分类模型
人工智能·python·机器学习·分类·数据挖掘·paddlepaddle