网易云音乐PC客户端加密API逆向解析
字数 1342 2025-08-18 11:37:07
网易云音乐PC客户端加密API逆向解析教学文档
1. 前言
本文详细解析网易云音乐PC客户端(版本2.3.0.196231)的API接口加密机制,重点分析params参数的生成方式,用于模拟客户端与服务器的交互。
2. 初步分析
2.1 文件结构分析
-
动态链接库与可执行文件:
libcurl.dll:仅用于程序启动时的少量网络交互libcef.dll:基于C/C++的Web browser控件,主交互界面cloudmusic.dll:核心功能模块
-
资源文件:
package/目录下的.ntpk文件:加密的ZIP格式资源文件orpheus.ntpk:包含核心JS文件(core.js),但被加密
3. 逆向过程
3.1 获取加密ZIP密码
- 使用调试器(如x64dbg)断点在
CreateFileW系统API - 跟踪文件加载过程,定位解压操作
- 通过内存分析找到解压密码(具体密码逆向过程略)
3.2 修改资源文件
由于资源文件有数字签名保护,直接修改会导致程序无法启动,需以下步骤:
-
分析签名机制:
- 使用Windows CSP(加密服务提供程序)库
- SHA1签名算法
- 文件头结构:
- 4字节"NTPK"标识
- 4字节文件长度
- 256字节校验数据
- 实际ZIP内容
-
绕过签名验证:
- 修改
cloudmusic.dll中的公钥 - 或修改验证逻辑的跳转指令
- 修改
3.3 启用远程调试
- 修改
cloudmusic.dll中的CEF结构体,开启调试端口(9222) - 补充devtools资源文件
- 通过
http://127.0.0.1:9222访问DevTools
4. 加密算法分析
4.1 params生成流程
-
输入参数:
url:请求路径data:提交的JSON数据
-
计算MD5:
md5_str = md5("nobody" + url + "use" + data + "md5forencrypt") -
二次拼接:
to_encrypt = url + "-36cd479b6b5-" + data + "-36cd479b6b5-" + md5_str -
填充对齐:
- 按0x10字节对齐
- 缺少部分用缺少的位数填充(如缺3字节则填充0x03)
-
私有加密算法:
- 每次处理16字节数据
- 使用动态生成的辅助加密数据(固定)
- 包含大量异或和位移操作
4.2 加密算法伪代码
void encrypt_block(uint8_t *block, uint8_t *key) {
uint32_t a = *(uint32_t*)block;
uint32_t b = *(uint32_t*)(block+4);
uint32_t c = *(uint32_t*)(block+8);
uint32_t d = *(uint32_t*)(block+12);
for(int i = 0; i < 16; i++) {
uint32_t tmp = a;
a = b ^ (key[i*4] | (key[i*4+1]<<8) | (key[i*4+2]<<16) | (key[i*4+3]<<24));
b = c;
c = d;
d = tmp;
}
*(uint32_t*)block = a;
*(uint32_t*)(block+4) = b;
*(uint32_t*)(block+8) = c;
*(uint32_t*)(block+12) = d;
}
5. 实现模拟请求
5.1 请求示例
import hashlib
import json
def generate_params(url, data):
# 转换为JSON字符串并去除空格
data_str = json.dumps(data, separators=(',', ':'))
# 计算MD5
md5_str = hashlib.md5(
("nobody" + url + "use" + data_str + "md5forencrypt").encode()
).hexdigest()
# 构造待加密字符串
to_encrypt = f"{url}-36cd479b6b5-{data_str}-36cd479b6b5-{md5_str}"
# 填充对齐
pad_len = 16 - (len(to_encrypt) % 16)
to_encrypt += chr(pad_len) * pad_len
# 加密处理(此处简化,实际需实现完整算法)
encrypted = custom_encrypt(to_encrypt.encode())
# 转换为大写十六进制字符串
params = ''.join(f"{b:02X}" for b in encrypted)
return params
# 示例请求
url = "/api/song/enhance/player/url"
data = {
"ids": "[123456]",
"br": 320000,
"csrf_token": ""
}
params = generate_params(url, data)
5.2 响应解密
部分API响应也是加密的,可通过设置e_r参数控制:
e_r=0:返回明文e_r=1:返回加密数据(需解密)
6. 总结
-
网易云音乐PC客户端使用多层保护:
- 资源文件加密压缩
- 数字签名验证
- 自定义加密算法
-
核心加密流程:
- 基于MD5和自定义加密算法
- 需要处理对齐填充
- 使用固定密钥和辅助数据
-
逆向技巧:
- 通过内存分析定位关键代码
- 利用CEF调试接口
- 修改DLL绕过保护机制
7. 扩展思考
- 加密算法的可逆性分析
- 不同版本间的算法差异
- 移动端与PC端加密机制对比
- 更高效的逆向分析方法
8. 注意事项
- 本文仅用于学习研究目的
- 实际实现需考虑不同版本的差异
- 网易云音乐可能随时更新加密机制
- 商业使用需获得官方授权
附录:关键函数偏移(基于2.3.0.196231版本)
- 公钥位置:
cloudmusic.dll + 0x7C3438 - 调试端口设置:
cloudmusic.dll + 0x14EED - 加密函数入口:
cloudmusic.dll + 0x123456(示例,实际需分析)