跳至内容

Jixun's Blog 填坑还是开坑,这是个好问题。

QQ 音乐文件解密 (QMCv2)

支持 2022 年 4 月之前的 QQ音乐 下载的加密文件。其特征为后缀名:mflac / mflac0 / mflac1 / mgg / mgg0 / mgg1

项目 #

C++ 实现使用 MIT 授权协议、Rust 实现使用 MIT + Apache 2.0 双协议。

链接:

基本使用方法 #

打开终端,键入:

./QMC2-decoder "加密文件路径.mflac" "解密文件储存路径.flac"

等待数秒后就完成了!

使用 CLI 工具进行解密的实例

或者,使用转译到 WASM 的网页版:

网页版的解密应用

直接选择文件,或将文件拖放到网页即可。每次一个文件。

碎碎念 #

一开始只是想着学学 rust,移植下以前写的 qmc-decode(毕竟代码简单),然后就发现了 unlock-music 这个项目,以及彼时尚未解决的 MGG/FLAC 加密分析

分析过程略。大致分析出加密流程,和 QMCv1 类似的情况是,二者都依赖当前的偏移位置来计算对应的 xor key。

于是初步整理了一些逆向出来的代码片段,如下方的参与 TEA Key 生成的一部分:

void SimpleMakeKey(uint8_t salt, int len, uint8_t *key_buf) {
  for (size_t i = 0LL; len > i; ++i) {
    key_buf[i] = (uint8_t)(fabs(tan((float)salt + (double)i * 0.1)) * 100.0);
  }
}

  uint8_t simple_key_buf[8] = {0};
  SimpleMakeKey(106, 8, simple_key_buf);

// 本地跑出来的结果
// 69 56 46 38 2b 20 15 0b

(为什么这么喜欢这种用利用浮点运算做 key 呢?)

整理完毕后就开了个项目,恰好发现 Visual Studio 2022 竟然支持 CMake 跨平台项目了… 那这必须体验一波。

… 发现问题并不少:

  1. 编译器的不同
    • MSVC 似乎会自动 #include 一部分标准库的定义,在 Windows 下编译成功后到 WSL2 下编译会失败。
    • 部分头文件缺失,如 endian.h。自己最后做了个简单的 polyfill
    • #include 路径解析。有时候明明自动填充都能正常提示,却无法 ctrl-左键 跳到对应的文件。
  2. 重构(Refactor)不够智能。
    • 需要将头文件和实现放在同一个目录下… 否则就会失败。

不过这些都是小问题,照着编译器提示的错误信息一个一个解决即可。

然后就开始各种折腾了:

  • 加了 emscripten 工具链,现在可以编译到 wasm/js 格式了。上线了个实验性质的网页版解密应用
    • 比想象中的要容易一些,但也有麻烦的地方,例如不可以直接传递 primitive 数据的指针(如 char*),必须在最终的导出函数声明使用类型 uintptr_t,然后使用 reinterpret_cast 将类型强行更改为期待的类型后调用;
    • 缝缝补补,发了个 @jixun/qmc2-crypto 的包,可以直接在别的 Node 或网页中零配置调用了(不过没有做高级封装,使用者需要手动调用 emscripten 提供的一些底层运行时接口)。同时也随包提供了 TypeScript 定义文件。
  • 折腾了下 GitHub Actions,自动跨平台编译 + 提交到 gh-pages 分支 + 发布区的草稿。

奇怪的知识增加了!.jpg

知识共享许可协议 本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。

评论区