From bf34e00243120693198778488e0001fd2c20b7b0 Mon Sep 17 00:00:00 2001 From: jixunmoe Date: Fri, 31 Mar 2023 14:46:54 +0000 Subject: [PATCH] Add 'Kuwo' --- Kuwo.md | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 Kuwo.md diff --git a/Kuwo.md b/Kuwo.md new file mode 100644 index 0000000..b6bed36 --- /dev/null +++ b/Kuwo.md @@ -0,0 +1,70 @@ +## 酷我格式研究 + +* 来源:酷我音乐官网的 `10.3.8.1` APK + * 存档:https://t.me/unlock_music_chat/122119 +* 加密文件样本:https://t.me/unlock_music_chat/121782 + +```txt +别怕变老(Live)-艾热_王以太-226743561.mflac SHA-256 7FDE8344B54EEA989AAE103982743EC2F5D7E6F93F7D6793BF5C95F34E5DBCD1 +酷我音乐.10.3.8.1.apk SHA-256 4B4595A3A42244A833BA777DDB222C487AD70C560E866D01EE6B1ADBFCFC4C15 +``` + +### 格式说明 + +文件头有很多信息: + +```txt +0000h 79 65 65 6C 69 6F 6E 2D 6B 75 77 6F 2D 74 6D 65 yeelion-kuwo-tme +0010h 02 00 00 00 00 00 00 00 09 D5 83 0D 00 00 00 00 .........Õƒ..... +0020h 88 54 0D 57 00 00 00 00 AC 6E 8C B8 00 00 00 00 ˆT.W....¬nŒ¸.... +0030h 32 30 39 30 30 6B 6D 66 6C 61 63 00 76 00 00 00 20900kmflac.v... +0040h 10 E7 03 85 76 00 00 00 01 00 00 00 08 00 00 00 .ç.…v........... +0050h 20 E7 03 85 76 00 00 00 00 00 00 00 20 00 00 00 ç.…v....... ... +0060h 84 69 10 24 87 01 00 00 0D 00 00 00 00 00 00 00 „i.$‡........... +0070h 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +``` + +格式描述为 `偏移: 类型 描述`: + +- `0x00`: `char[16]` 固定文件头。 +- `0x10`: `u32,le` 加密版本。目前 `mflac` 的这个值是 `2`,之前版本是 `1`。 + 内部名称为 `KwPocoVersion` 或 `EncryptVersion`。 + (内部) 加密版本为 `3` 时,当作未加密文件处理。猜测下个加密版本可能会使用 `4`。 +- `0x18`: `u32,le` 资源 ID,同之前版本。写出时实际写出的是 `u64` 数值。 +- `0x30`: `char[?]` 缓冲区,读入字符到一个类型为 `std::string` 的变量内。 + 在该样本的情况会读入 `11` 字节并储存。 +- `0x68`: `u8` VIP 资源类型,见下表; + +其它:和解密没有多大关系,没有细看。 + +### VIP 资源类型 + +样本的 VIP 资源类型为 `0D`,转换为二进制为 `1101`。 + +分别对应下述标记: + +- `isTingshuVipPay` +- `isSongPay` +- `isVipPay` + +```java + public static void a(Music music, int vip_type) { + boolean is_vip_pay = false; + music.isTingshuVipPay = (vip_type & 1) == 1; + music.isAlbumPay = (vip_type >> 1 & 1) == 1; + music.isSongPay = (vip_type >> 2 & 1) == 1; + if((vip_type >> 3 & 1) == 1) { + is_vip_pay = true; + } + + music.isVipPay = is_vip_pay; + } +``` + +该值置零也许不能绕过非会员播放,因为文件未内嵌 `ekey` 密钥。 + +### 解密流程 + +1. 读取文件头,校验加密版本是否为 `2`。 +2. 使用读入的 `ekey` 进行解密,解密时的 `offset` 为 `file_offset - 1024`。 +3. 使用 QQ 音乐同款 `QMC2::MAP` 或 `QMC2::RC4` 进行解密 (取决于密钥长度)。