2 Kuwo (v2)
jixunmoe edited this page 2023-03-31 15:24:51 +00:00
This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

酷我格式研究

别怕变老(Live)-艾热_王以太-226743561.mflac	SHA-256	7FDE8344B54EEA989AAE103982743EC2F5D7E6F93F7D6793BF5C95F34E5DBCD1
酷我音乐.10.3.8.1.apk	SHA-256	4B4595A3A42244A833BA777DDB222C487AD70C560E866D01EE6B1ADBFCFC4C15

※ 该格式研究来自静态分析,并没有进行验证。可能会有不准确的地方。

格式说明

文件头有很多信息:

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
    内部名称为 KwPocoVersionEncryptVersion
    (内部) 加密版本为 3 时,当作未加密文件处理。猜测下个加密版本可能会使用 4
  • 0x18: u32,le 资源 ID同之前版本。写出时实际写出的是 u64 数值。
  • 0x30: char[?] 文件格式,读入字符到一个类型为 std::string 的变量内。
    在该样本的情况会读入 11 字节并储存。
  • 0x68: u8 VIP 资源类型,见下表;

其它:和解密没有多大关系,没有细看。

VIP 资源类型

样本的 VIP 资源类型为 0D,转换为二进制为 1101

分别对应下述标记:

  • isTingshuVipPay
  • isSongPay
  • isVipPay
    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 进行解密,解密时的 offsetfile_offset - 1024
  3. 使用 QQ 音乐同款 QMC2::MAPQMC2::RC4 进行解密 (取决于密钥长度)。

ekey 缓存

该逻辑在安卓的 Java 端:

    public static String get_cached_file_ekey(long res_id, String format) {
        return MMKV.ReadMMKVString("sec_ekey", res_id + "-" + format.toLowerCase(), "");
    }

其中 format 为文件格式,该样本的值为 "20900kmflac"res_id 则是资源 ID226743561