QMCDecode解码引擎深度拆解:从一枚加密文件到标准音频的完整还原之旅

发布时间:2026/8/18 15:17:09

QMCDecode解码引擎深度拆解:从一枚加密文件到标准音频的完整还原之旅
QMCDecode解码引擎深度拆解从一枚加密文件到标准音频的完整还原之旅【免费下载链接】QMCDecodeQQ音乐QMC格式转换为普通格式(qmcflac转flacqmc0,qmc3转mp3, mflac,mflac0等转flac)仅支持macOS可自动识别到QQ音乐下载目录默认转换结果存储到~/Music/QMCConvertOutput,可自定义需要转换的文件和输出路径项目地址: https://gitcode.com/gh_mirrors/qm/QMCDecodeQMCDecode 是一款专注于 macOS 平台的 QQ 音乐 QMC 格式转换工具核心能力是把.qmcflac、.qmc0、.mflac等加密音频还原为.flac、.mp3、.ogg等标准格式。与同类工具最大的不同在于它的解密路径里藏着两代加密协议的兼容处理、一套 TEA 密钥派生流程和三种风格迥异的流式解密算法——本文不打算停留在怎么用而是跟着一枚文件从落盘到还原成可播放音频的真实旅程逐层拆开 QMCDecode 的解码引擎架构。一张图看懂解码全流程整个转换可以拆成五个依次衔接的环节每一环都会决定下一环的输入文件落盘 │ ├─ 1. 按扩展名查词典判定加密版本与目标格式 │ ├─ 2. 读取文件尾部解析密钥封装区取出原始密钥 │ ├─ 3. 密钥派生Base64 → TEA-CBC 解密 → 最终密钥 │ ├─ 4. 依据最终密钥长度分派到静态/映射/RC4 三类解密器 │ └─ 5. 按解密器规则逐字节还原音频数据写盘有意思的地方在于密钥不是单独存放的而是内嵌在文件末尾。这让 QMCDecode 不需要联网、不需要额外配置文件拿到文件就能解也让它必须先解决怎么从文件里安全地挖出密钥这个问题。下面按这条主线逐步深入。第一站扩展名词典——一个字典同时承担两件职责打开 Constants.swift最先看到的是encryptExtDictionary。它同时记录了输入扩展名 → 输出扩展名和加密版本let encryptExtDictionary: [String: ExtensionAndVersion] [ mgg: ExtensionAndVersion(ext: ogg, version: .v2), mflac: ExtensionAndVersion(ext: flac, version: .v2), qmcflac: ExtensionAndVersion(ext: flac, version: .v2), qmc0: ExtensionAndVersion(ext: mp3, version: .v1), qmc3: ExtensionAndVersion(ext: mp3, version: .v1), 666c6163: ExtensionAndVersion(ext: flac, version: .v1), // ... ]注意最后几个奇怪的键666c6163是十六进制字符串解码后正是 ASCII 的 flac。这是一批老式文件扩展名本身就是十六进制编码的音频格式名。QMCDecode 的处理方式很直接把它当作普通扩展名注册进同一个字典解密完成后替换成对应的标准后缀。为什么版本号这么重要因为 v1 与 v2 对应着两种不同的密钥派生路线和不同的尾部封装协议先判定版本后面每一步才能走对分支。这个设计让格式扩展变得极轻量——新增一种格式往往只是往字典里加一行。第二站挖密钥——文件尾部的双协议封装区密钥封装区的解析逻辑集中在 QMDecoder.swift 的searchKey()。这里体现了项目最有价值的一个兼容性设计同一文件格式移动端与 PC/macOS 端的封装方式完全不同。// 移动端以 QTag 结尾长度字段用大端序 if String(bytes: lastFourBytes, encoding: .utf8) QTag { let keySize ... // bigEndian 读取 self.realAudioSize self.originFileLength - Int(keySize) - 8 // 从 realAudioSize 处读 rawKey以逗号作为 key 的结束标记 } else { // PC/macOS 端末尾 4 字节即 key 长度小端序 let keySize ... // littleEndian 读取 if keySize 0x300 { // key 位于文件末尾往前 keySize4 字节处 } else { // keySize 异常大说明是老版本静态加密用内置固定密钥 self.cipher try QMStaticCipher(originKey: privateKey256) } }两个分支揭示了三种真实存在的情况来源尾部标记长度序密钥位置移动端下载4 字节 QTag大端紧邻 QTag 前以逗号,结尾PC/macOS 端直接是长度值小端文件末尾前keySize字节老版本文件长度值 ≥ 0x300小端无密钥内置privateKey256直接解密这里有个很值得琢磨的细节长度值异常大就当作没有密钥。0x300768字节远大于正常密钥尺寸一旦读取到这种异常值说明这份文件根本没有内嵌密钥——它是早期静态加密时代的产物直接用内置的 256 字节固定密钥即可解密。这一判断避免了对文件结构做大量假设用一字节大小阈值就完成了新旧协议的自动切换堪称整个解码引擎里性价比最高的一个分支。顺带一提realAudioSize也在这一步被算出来音频数据 文件总长 − 密钥区长度 − 尾部标记长度。解密时只处理这段真实音频密钥区会被整体丢弃。第三站密钥派生——一场 TEA-CBC 手工解密拿到原始密钥后还不能直接用。它还要经过 QMCKeyDecoder.swift 的deriveKey()做一次脱壳。这一步是全项目数学含量最高的地方。3.1 Base64 解码与长度守卫原始 key 本质上是 Base64 编码的密文先解码成二进制并做长度校验——少于 16 字节直接抛错因为后续流程至少需要 8 字节 IV 加 8 字节密文块。3.2 用 tan 函数造出 TEA 密钥TEA 的 16 字节密钥是这样拼出来的先取一个简单密钥simpleMakeKey(seed: 106, length: 8)它的生成方式出人意料result[index] UInt8(fabs(tan(Double(seed) Double(index) * 0.1)) * 100.0)对用三角函数 tan 生成密钥字节。这种伪随机但可复现的生成方式不需要存储任何秘密算法本身即密钥——逆向方只要知道 seed106 就能重建同一串字节。随后把 simpleKey 与解密后密文的前 8 字节交错拼成 16 字节的 TEA 密钥teaKey[index 1] simpleKey[index] teaKey[(index 1) 1] base64DecodedKey[index]3.3 TEA 解密标准的 32 轮 手动 CBC 模式TeaCipher.swift 实现了教科书级的 TEATiny Encryption Algorithm64 轮加密对应 32 轮解密固定 delta0x9e3779b9大端读取 UInt32。源码里有一句注释格外醒目这个煞笔算法整个在 32 位的框框内运行——因为 Swift 的UInt32运算默认会溢出作者用、-、*这些溢出运算符强行模拟了 TEA 依赖的 32 位回绕行为。这是移植 C 系密码学时最容易踩的坑也是这版实现最需要留意的可读性细节。解密密钥区时decryptTencentTea并非一次性解完而是手动实现了 CBC 链式模式每一轮用上一块的密文ivPrevious与当前块的明文做异或后再继续解密中间还要跳过 2 字节 salt 和 7 字节 zero 校验区let paddingLength Int(tempBuffer[0] 0x7) let outputLength inBuffer.count - 1 - paddingLength - saltLength - zeroLength最后一步是校验解密结果的末尾 7 字节必须与ivPrevious对应位置完全相等否则说明密钥或数据有误抛出zeroCheckFailed。这一校验把解密成功从概率事件变成了可验证的确定事件——如果一个密钥解析错了会在这一刻被立刻拦截而不是产出损坏的音频文件。第四站分派——密钥长度决定解密算法最终密钥拿到后QMDecoder.swift 的setCipher()用一个非常朴素但有效的规则做算法分派if decodedKey.count 300 { self.cipher try QMRC4Cipher(originKey: decodedKey) } else { self.cipher try QMMapCipher(originKey: decodedKey) }密钥超过 300 字节走 RC4否则走映射解密。这个阈值不是拍脑袋定的——密钥长度直接反映了加密强度新版本文件的密钥普遍更长采用了更强的 RC4 流加密老版本密钥较短用映射表就够。一行判断两代算法各归其位。而QMStaticCipher不进这个分支它只在上文提到的老版本固定密钥场景被直接创建。三种解密器共同实现同一个协议public protocol QMCipher { func qmDecrypt(data: Data, offset: Int) - Data init(originKey: [UInt8]) throws }协议里有个关键的offset参数它代表当前数据在整个音频流中的绝对偏移。这让解密器天然支持分段解密——任意位置的数据块都能独立解密而不必从头开始。这正是 RC4 分段解密能够成立的前提。第五站静态与映射——一字节一字节的异或还原QMStaticCipher 和 QMMapCipher 的骨架完全一样对每个字节用一个随偏移变化的掩码做异或。public func getMask(offset: Int) - UInt8 { let temp offset 0x7FFF ? (offset % 0x7FFF) : offset let index (temp * temp 27) 0xFF return key[index] }掩码的生成依赖一个二次函数(offset² 常数) 0xFF得到查表下标。两个算法的差别只在两处算法二次函数常数查表后处理QMStaticCipher27直接取key[index]QMMapCipher71214对key[index]做循环移位rotate这里的0x7FFF取模很关键它把偏移量限定在一个 32768 字节的窗口内防止大文件偏移导致整数溢出同时让掩码序列在文件内部周期性重复——这既简化了计算也意味着解密任何局部区块都不需要知道完整文件长度。如果不这样设计会怎样如果直接对原始 offset 做平方运算一个几百 MB 的音频文件偏移值会轻松溢出 32 位整数掩码序列立刻错乱。周期化处理是这个实现能稳定处理大文件的前提。第六站RC4 分段解密——整个引擎最精巧的部分QMRC4Cipher 是全项目实现最复杂、也最值得反复研读的一环。它没有简单地对整个文件跑一遍标准 RC4而是把数据流切成三种不同规则的分段private let firstSegmentSize: Int 0x80 // 128 字节首段 private let segmentSize: Int 0x1400 // 5120 字节主段解密入口qmDecrypt(data:offset:)依次处理四段首段若 offset 0x80使用encodeFirstSegment掩码来自getSegmentKey——一种基于 hashValue 与种子派生出的偏移敏感密钥流对齐段若 offset 不是 5120 的整数倍先解到下一个对齐边界批量主段以 5120 字节为单位循环解密尾段剩余不足一个分段的字节。主段解密encodeAllSegment是标准 RC4 的 KSAPRGA 流程每段用同一份 seedBox 做密钥调度KSA再按段内偏移跳过指定数量的密钥流字节相当于丢弃 PRGA 的前skipLength个输出随后才开始真正的异或解密。let skipLength (offset % segmentSize) self.getSegmentKey(index: offset / segmentSize)这个skipLength是理解整个设计的关键它保证每一段都从密钥流的正确位置开始生成从而让按段独立解密与一次性整体解密产生完全一致的结果。而getSegmentKey内部用到了hashValue——一个在 init 时对密钥字节连乘得到的值它对每个文件都不同相当于给 RC4 加了一层文件级个性化。为什么要费这么大力气做分段原因很实际支持随机访问解密。对于动辄几十 MB 的 FLAC 文件分段意味着内存占用恒定不必把整个文件加载进来也意味着理论上可以只解密文件的一部分比如播放器拖动进度条时只解当前位置。这是对流式处理的一次认真尝试。第七站并发调度——按 CPU 核心数铺队列解密算法就绪后真正提升体验的是 ViewController.swift 里的并发设计。作者没有用一个串行队列依次处理而是做了一套按核心数轮询分发的调度let coreCount ProcessInfo().processorCount for index in 0..dataSource.count { let queue queueArray[index % coreCount] queue.async { ... } }queueArray里有多少队列ProcessInfo().processorCount个注释写得相当直白根据CPU物理核心数组装队列尽量跑死CPU。每个文件的解密任务按index % coreCount轮询分发给对应队列天然实现了负载均衡——文件数超过核心数时任务会均匀铺到每个核心上。进度汇报则统一回到主线程通过succeedCount errorCount累计计算百分比全部完成后弹出结果弹窗。这一并行干活、串行汇报的模式避免了 UI 线程被大量并发回调挤爆是批量转换场景的标准解法。解码器的性能特征与选型对比把四种解密路径放一起看它们的成本结构差异很大解密器单字节成本内存占用适用格式特点QMStaticCipher最低一次查表O(1)老版本固定密钥无密钥文件专用QMMapCipher低查表移位O(1)qmc0/qmc3 等 v1 格式掩码周期 0x7FFFQMRC4Cipher中KSAPRGAO(keyLength)mflac/mgg 等 v2 格式分段流式支持随机访问TEA 密钥派生一次性开销O(1)所有内嵌密钥文件每文件仅执行一次关键结论TEA 密钥派生只在文件开头执行一次均摊到几十 MB 的音频数据上几乎可以忽略真正的大头是逐字节异或与 RC4 的 PRGA 循环因此总吞吐量主要由 RC4 段的线性扫描速度决定。对于整批转换场景瓶颈往往在磁盘 IO 而非 CPU——这也解释了为什么作者放心地尽量跑死CPU。下一步动手跑通一个 Demo现在你对整条还原链路已经有了完整认知。想亲手验证这套解码引擎可以这样开始克隆并编译仓库地址https://gitcode.com/gh_mirrors/qm/QMCDecode用 Xcode 打开QMCDecode.xcodeprojCmd B即可构建macOS 10.13Xcode 11。喂数据运行后应用会自动扫描 QQ 音乐 macOS 客户端的下载目录~/Library/Containers/com.tencent.QQMusicMac/.../iQmc/也可以用Choose File手动选择任意目录。观察链路挑选一枚.qmcflac文件单步调试searchKey()→deriveKey()→qmDecrypt()你会亲眼看到密钥从文件尾部被挖出、经 TEA 脱壳、最终在掩码表里逐字节还原出 FLAC 头fLaC的过程——当输出文件头部出现可识别的格式魔数时整条链路就通了。如果你是冲着二次开发来的值得动手改造的三个方向往encryptExtDictionary里注册新的格式映射在QMCipher协议下新增自定义解密器并接入setCipher()的分派逻辑把QMDecoder从 App 里抽出来封装成命令行工具或库——核心代码与 UI 的耦合度很低这几处改动都不会伤筋动骨。解码引擎的每一个环节都留有余地这正是它作为学习样本和改造基座的真正价值。【免费下载链接】QMCDecodeQQ音乐QMC格式转换为普通格式(qmcflac转flacqmc0,qmc3转mp3, mflac,mflac0等转flac)仅支持macOS可自动识别到QQ音乐下载目录默认转换结果存储到~/Music/QMCConvertOutput,可自定义需要转换的文件和输出路径项目地址: https://gitcode.com/gh_mirrors/qm/QMCDecode创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

palera1n 越狱工具实战指南:如何一步步让 A8-A11 旧设备完成深度定制

palera1n 越狱工具实战指南:如何一步步让 A8-A11 旧设备完成深度定制

2026/8/18 15:07:09

palera1n 越狱工具实战指南:如何一步步让 A8-A11 旧设备完成深度定制 【免费下载链接】palera1n Jailbreak for A8 through A11, T2 devices, on iOS/iPadOS/tvOS 15.0, bridgeOS 5.0 and higher. 项目地址: https://gitcode.com/GitHub_Trending/pa/palera1n …

零基础玩转 Gamdl:Apple Music 无损音乐下载器与 4K 音乐视频下载完整指南

零基础玩转 Gamdl:Apple Music 无损音乐下载器与 4K 音乐视频下载完整指南

2026/8/18 15:07:09

零基础玩转 Gamdl:Apple Music 无损音乐下载器与 4K 音乐视频下载完整指南 【免费下载链接】gamdl A command-line app for downloading Apple Music songs, music videos and post videos. 项目地址: https://gitcode.com/GitHub_Trending/ga/gamdl Gamdl 是…

三步零基础部署跨平台远程控制工具:把三台不同系统的电脑连成一张网

三步零基础部署跨平台远程控制工具:把三台不同系统的电脑连成一张网

2026/8/18 15:07:09

三步零基础部署跨平台远程控制工具:把三台不同系统的电脑连成一张网 【免费下载链接】rustdesk An open-source remote desktop application designed for self-hosting, as an alternative to TeamViewer. 项目地址: https://gitcode.com/GitHub_Trending/ru/rus…

2026年8月青岛到广州物流行业研究报告:深度剖析发展态势

2026年8月青岛到广州物流行业研究报告:深度剖析发展态势

2026/8/19 8:47:54

行业背景与发展现状市场规模与发展阶段据行业数据显示,近年来物流行业持续保持增长态势,随着电商行业及制造业的发展,青岛到广州线路的物流市场规模也在不断扩大。这一线路的物流运输涵盖了零担、整车及专线物流等多种模式,满足着…

RV1126B (Luckfox Aura) 外接 4 寸 MIPI DSI 屏点亮全记录 —— 一个纯软件工程师的硬啃之旅

RV1126B (Luckfox Aura) 外接 4 寸 MIPI DSI 屏点亮全记录 —— 一个纯软件工程师的硬啃之旅

2026/8/19 8:47:54

前排提示:本文是一篇真实排障全记录,记录了从"屏幕全黑"到"开机自动点亮"的完整过程。没有速成魔法,只有一步步的 dmesg、i2c、dtb 拆解。如果你也在玩 RK 平台 非官方 DSI 屏,本文的坑你大概率会踩到。0. 写…

Gmail智能撰写功能背后的隐私风险与数据流向分析

Gmail智能撰写功能背后的隐私风险与数据流向分析

2026/8/19 8:47:54

如果你最近在 Gmail 里写邮件时,感觉 Gemini 的“智能撰写”功能越来越懂你,甚至能预测你下一句要说什么,先别急着感叹 AI 的神奇。这背后可能隐藏着一个你未曾留意的隐私开关:“智能功能”。最近,一位开发者在 Hacker…

Windows系统文件TSErrRedir.dll丢失找不到问题解决

Windows系统文件TSErrRedir.dll丢失找不到问题解决

2026/8/19 8:47:54

在使用电脑系统时经常会出现丢失找不到某些文件的情况,由于很多常用软件都是采用 Microsoft Visual Studio 编写的,所以这类软件的运行需要依赖微软Visual C运行库,比如像 QQ、迅雷、Adobe 软件等等,如果没有安装VC运行库或者安装…

Karma上海车展战略解析:中国化与平台化双轮驱动,三款新车重塑豪华电动车市场

Karma上海车展战略解析:中国化与平台化双轮驱动,三款新车重塑豪华电动车市场

2026/8/19 8:47:54

1. 从“复活”到“新生”:Karma在上海车展的战略信号 如果你关注高端电动车市场,或者对汽车行业的“复活”故事感兴趣,那么今年上海车展上Karma Automotive的动向,绝对值得你花时间琢磨。这家公司身上有太多标签:源自破…

Cortex-M调试接口与MCU开发:从烧写失败到系统级解决方案

Cortex-M调试接口与MCU开发:从烧写失败到系统级解决方案

2026/8/19 8:37:53

1. 从一次烧写失败说起:为什么Cortex-M的调试接口如此关键? 最近在调试一块基于STM32F407的项目板时,遇到了一个让人头疼的问题:用ST-LINK连接,MDK或IAR能识别到设备,但一到烧写或调试阶段,就弹…

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

2026/8/19 3:36:59

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

【双层规划,节点出清价,绿证交易,CVaR方法】两级电力市场环境下计及风险的省间交易商最优购电模型附Matlab代码

【双层规划,节点出清价,绿证交易,CVaR方法】两级电力市场环境下计及风险的省间交易商最优购电模型附Matlab代码

2026/8/18 1:03:22

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

隐式mpc+自适应mpc+时变mpc,线性时变模型预测控制附Simulink仿真

隐式mpc+自适应mpc+时变mpc,线性时变模型预测控制附Simulink仿真

2026/8/19 8:02:16

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

SQL 调优 [ 2 ]

SQL 调优 [ 2 ]

2026/8/19 0:07:32

type列详解EXPLAIN输出的type列描述了表是如何连接的,性能从最好到最差的排序如下:systemconsteq_refreffulltextref_or_nullindex_mergeunique_subqueryindex_subqueryrangeindexALL接下来我们对 type列 做详细讲解。我们都知道,想要评估一条…

正式评优怎么选投票工具?人人微投票审计级防刷能力实测

正式评优怎么选投票工具?人人微投票审计级防刷能力实测

2026/8/19 0:07:32

在线上投票工具遍地开花的今天,选择一个合适的平台,本质上是在做一道关于场景与需求的匹配题。人人微投票是一个很典型的案例——它的产品逻辑、技术架构和商业模式,都围绕着“正式评选”这个细分场景深度扎根,也因此形成了自己鲜…

15 天 3 连发:DeepSeek 的「机枪」节奏,到底在下什么棋?

15 天 3 连发:DeepSeek 的「机枪」节奏,到底在下什么棋?

2026/8/19 0:07:32

15 天 3 连发:DeepSeek 的「机枪」节奏,到底在下什么棋?回看 2026 年 8 月这半个月,DeepSeek 的动作密度堪称疯狂:月初端出便宜快速的 V4-Flash,8 月 13 日同一天甩出 V4-Pro 正式版 开源 Harness 框架&am…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/17 12:00:53

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/15 10:10:27

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/18 12:20:24

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…