Merge remote-tracking branch 'upstream/master'
All checks were successful
continuous-integration/drone/pr Build is passing

# Conflicts:
#	src/App.vue
#	src/view/Home.vue
This commit is contained in:
KyleBing 2023-09-25 12:15:18 +08:00
commit eaca480700
43 changed files with 297 additions and 2658 deletions

View File

@ -4,11 +4,6 @@ type: docker
name: default
steps:
- name: build-wasm
image: emscripten/emsdk:3.0.0
commands:
- ./scripts/build-wasm.sh
- name: build
image: node:16.18-bullseye
commands:

View File

@ -0,0 +1,76 @@
name: 解码错误报告 (填表)
about: 遇到文件解码失败的问题请选择该项。
title: '[Bug/Crypto] '
labels:
- bug
- crypto
body:
- type: textarea
id: what-happened
attributes:
label: 错误描述
description: 请描述你所遇到的问题,以及你期待的行为。
placeholder: ''
value: ''
validations:
required: true
- type: dropdown
id: version
attributes:
label: Unlock Music 版本
description: |
能够重现错误的版本,版本号通常在页面底部。
如果不确定,请升级到最新版确认问题是否解决。
multiple: true
options:
- 1.10.5 (仓库最新)
- 1.10.3 (官方 DEMO)
- 其它(请在错误描述中指定)
validations:
required: true
- type: dropdown
id: browsers
attributes:
label: 产生错误的浏览器
multiple: true
options:
- 火狐 / Firefox
- Chrome
- Safari
- 其它基于 Chromium 的浏览器 (Edge、Brave、Opera 等)
- type: dropdown
id: music-platform
attributes:
label: 音乐平台
description: |
如果需要报告多个平台的问题,请每个平台提交一个新的 Issue。
请注意:播放器缓存文件不属于该项目支持的文件类型。
multiple: false
options:
- 其它 (请在错误描述指定)
- QQ 音乐
- Joox (QQ 音乐海外版)
- 虾米音乐
- 网易云音乐
- 酷我音乐
- 酷狗音乐
- 喜马拉雅
- 咪咕 3D
validations:
required: true
- type: textarea
id: logs
attributes:
label: 日志信息
description: 如果有请提供浏览器开发者控制台Console的错误日志
render: text
- type: checkboxes
id: terms
attributes:
label: 我已经阅读并确认下述内容
description: ''
options:
- label: 我已经检索过 Issue 列表,并确认这是一个为报告过的问题。
required: true
- label: 我有证据表明这是程序导致的问题(如不确认,可以通过 Telegram 讨论组 (https://t.me/unlock_music_chat) 进行讨论)
required: true

View File

@ -1,39 +1,40 @@
---
name: Bug报告
about: 报告Bug以帮助改进程序
title: ''
labels: bug
assignees: ''
name: "错误报告"
about: "报告 Bug 以帮助改进程序,非填表。"
title: "[BUG] "
labels:
- bug
---
* 请按照此模板填写,否则可能立即被关闭
- [x] 我确认已经搜索过Issue不存并确认相同的Issue
- [x] 我有证据表明这是程序导致的问题(如不确认,可以在[Discussions](https://github.com/ix64/unlock-music/discussions)内提出
- [x] 我有证据表明这是程序导致的问题(如不确认,可以通过 Telegram 讨论组 (https://t.me/unlock_music_chat) 进行讨论
**Bug描述**
## Bug描述
简要地复述你遇到的Bug
**复现方法**
## 复现方法
描述复现方法,必要时请提供样本文件
**程序截图或者Console报错信息**
## 程序截图或浏览器开发者控制台Console的报错信息
如果可以请提供二者之一
**环境信息:**
## 环境信息
- 操作系统和浏览器:
- 程序版本:
- 获取音乐文件所使用的客户端及其版本信息
- 网页版的地址(如果为非官方部署请注明)
注意:如果需要会员才能获取该资源,你可能也需要作为附件提交。
**附加信息**
## 附加信息
其他能够帮助确认问题的信息
如果有,请提供其他能够帮助确认问题的信息到下方:

View File

@ -1,26 +1,29 @@
---
name: 新功能
about: 对于程序新的想法或建议
title: ''
labels: enhancement
assignees: ''
name: "新功能"
about: "对于程序新的想法或建议"
title: "[新功能] "
labels:
- enhancement
---
- 请按照此模板填写,否则可能立即被关闭
<!-- ⚠ 请按照此模板填写,否则可能立即被关闭 -->
<!-- 提交前请使用【Preview】预览提交的更改 -->
**背景和说明**
## 背景和说明
简要说明产生此想法的背景和此想法的具体内容
<!-- 简要说明产生此想法的背景和此想法的具体内容 -->
**实现途径**
## 实现途径
- 如果没有设计方案,请简要描述实现思路
- 如果你没有任何的实现思路,请通过[Discussions](https://github.com/ix64/unlock-music/discussions)或者Telegram进行讨论
- 如果你没有任何的实现思路,请通过 Telegram 讨论组 (https://t.me/unlock_music_chat) 进行讨论
**附加信息**
## 附加信息
更多你想要表达的内容
<!-- 更多你想要表达的内容 -->

View File

@ -50,8 +50,6 @@
### 自行构建
#### JS部分
- 环境要求
- nodejs (v16.x)
- npm
@ -59,6 +57,7 @@
1. 获取项目源代码后安装相关依赖:
```sh
npm install
npm ci
```
@ -76,15 +75,3 @@
```sh
npm run make-extension
```
#### WASM部分
- 环境要求
- Linux
- python3
- 运行此目录下的build-wasm
```sh
./scripts/build-wasm.sh
```

View File

@ -6,11 +6,13 @@
"128": "./img/icons/msapplication-icon-144x144.png"
},
"description": "在任何设备上解锁已购的加密音乐!",
"permissions": ["storage"],
"permissions": [
"storage"
],
"offline_enabled": true,
"options_page": "./index.html",
"homepage_url": "https://github.com/ix64/unlock-music",
"homepage_url": "https://git.unlock-music.dev/um/web",
"browser_action": {
"default_popup": "./popup.html"
}
}
}

62
package-lock.json generated
View File

@ -1,18 +1,19 @@
{
"name": "unlock-music",
"version": "v1.10.3",
"version": "1.10.6",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "unlock-music",
"version": "v1.10.3",
"version": "1.10.6",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"@babel/preset-typescript": "^7.16.5",
"@jixun/kugou-crypto": "^1.0.3",
"@unlock-music/joox-crypto": "^0.0.1-R5",
"@xhacker/kgmwasm": "^1.0.0",
"@xhacker/qmcwasm": "^1.0.0",
"base64-js": "^1.5.1",
"browser-id3-writer": "^4.4.0",
"core-js": "^3.16.0",
@ -2986,22 +2987,6 @@
"regenerator-runtime": "^0.13.3"
}
},
"node_modules/@jixun/kugou-crypto": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@jixun/kugou-crypto/-/kugou-crypto-1.0.3.tgz",
"integrity": "sha512-ZiwSkpIAH8IkFcTfMjdQMpP/xco3iXEdYDEQo4wquYpSAln5RmSed3iBctnpoE6s3X1cxmBGhpCYW6v6vZfs+g==",
"dependencies": {
"commander": "^9.2.0"
}
},
"node_modules/@jixun/kugou-crypto/node_modules/commander": {
"version": "9.2.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz",
"integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==",
"engines": {
"node": "^12.20.0 || >=14"
}
},
"node_modules/@mrmlnc/readdir-enhanced": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
@ -4197,6 +4182,16 @@
"@xtuc/long": "4.2.2"
}
},
"node_modules/@xhacker/kgmwasm": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@xhacker/kgmwasm/-/kgmwasm-1.0.0.tgz",
"integrity": "sha512-LnBuEVRJQVyJGJTb0cPZxZDu7Qi4PqDhJLRaRJfG6pSUeZuIoglzHiysyd4XfNHobNnLxG8v1IiNPS/uWwoG0A=="
},
"node_modules/@xhacker/qmcwasm": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@xhacker/qmcwasm/-/qmcwasm-1.0.0.tgz",
"integrity": "sha512-oE6isNLmCDqIvxJV9KyDVlIzMISQzTj8o1ePWtQ+DhfXLI0hel/DwOIQ3icCikWnfwA/5SDs2hYw5BvrxdJ63g=="
},
"node_modules/@xtuc/ieee754": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
@ -5717,7 +5712,7 @@
},
"node_modules/caniuse-lite": {
"version": "1.0.30001434",
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001434.tgz",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001434.tgz",
"integrity": "sha512-aOBHrLmTQw//WFa2rcF1If9fa3ypkC1wzqqiKHgfdrXTWcU8C4gKVZT77eQAPWN1APys3+uQ0Df07rKauXGEYA=="
},
"node_modules/case-sensitive-paths-webpack-plugin": {
@ -23195,21 +23190,6 @@
"regenerator-runtime": "^0.13.3"
}
},
"@jixun/kugou-crypto": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@jixun/kugou-crypto/-/kugou-crypto-1.0.3.tgz",
"integrity": "sha512-ZiwSkpIAH8IkFcTfMjdQMpP/xco3iXEdYDEQo4wquYpSAln5RmSed3iBctnpoE6s3X1cxmBGhpCYW6v6vZfs+g==",
"requires": {
"commander": "^9.2.0"
},
"dependencies": {
"commander": {
"version": "9.2.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz",
"integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w=="
}
}
},
"@mrmlnc/readdir-enhanced": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
@ -24256,6 +24236,16 @@
"@xtuc/long": "4.2.2"
}
},
"@xhacker/kgmwasm": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@xhacker/kgmwasm/-/kgmwasm-1.0.0.tgz",
"integrity": "sha512-LnBuEVRJQVyJGJTb0cPZxZDu7Qi4PqDhJLRaRJfG6pSUeZuIoglzHiysyd4XfNHobNnLxG8v1IiNPS/uWwoG0A=="
},
"@xhacker/qmcwasm": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@xhacker/qmcwasm/-/qmcwasm-1.0.0.tgz",
"integrity": "sha512-oE6isNLmCDqIvxJV9KyDVlIzMISQzTj8o1ePWtQ+DhfXLI0hel/DwOIQ3icCikWnfwA/5SDs2hYw5BvrxdJ63g=="
},
"@xtuc/ieee754": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
@ -25487,7 +25477,7 @@
},
"caniuse-lite": {
"version": "1.0.30001434",
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001434.tgz",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001434.tgz",
"integrity": "sha512-aOBHrLmTQw//WFa2rcF1If9fa3ypkC1wzqqiKHgfdrXTWcU8C4gKVZT77eQAPWN1APys3+uQ0Df07rKauXGEYA=="
},
"case-sensitive-paths-webpack-plugin": {

View File

@ -1,13 +1,13 @@
{
"name": "unlock-music",
"version": "1.10.3",
"version": "1.10.6",
"ext_build": 0,
"updateInfo": "完善音乐标签编辑功能,支持编辑更多标签",
"updateInfo": "修正文件过小的情况下酷狗 / QQ解密错误问题",
"license": "MIT",
"description": "Unlock encrypted music file in browser.",
"repository": {
"type": "git",
"url": "https://github.com/ix64/unlock-music"
"url": "https://git.unlock-music.dev/um/web"
},
"private": true,
"scripts": {
@ -21,8 +21,9 @@
},
"dependencies": {
"@babel/preset-typescript": "^7.16.5",
"@jixun/kugou-crypto": "^1.0.3",
"@unlock-music/joox-crypto": "^0.0.1-R5",
"@xhacker/kgmwasm": "^1.0.0",
"@xhacker/qmcwasm": "^1.0.0",
"base64-js": "^1.5.1",
"browser-id3-writer": "^4.4.0",
"core-js": "^3.16.0",

View File

@ -1,39 +1,89 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta content="webkit" name="renderer">
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
<meta content="width=device-width,initial-scale=1.0" name="viewport">
<head>
<meta charset="utf-8" />
<meta content="webkit" name="renderer" />
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible" />
<meta content="width=device-width,initial-scale=1.0" name="viewport" />
<title>音乐解锁</title>
<meta content="音乐,解锁,ncm,qmc,mgg,mflac,qq音乐,网易云音乐,加密" name="keywords"/>
<meta content="音乐解锁 - 在任何设备上解锁已购的加密音乐!" name="description"/>
<!--@formatter:off-->
<style>#loader{position:absolute;left:50%;top:50%;z-index:1010;margin:-75px 0 0 -75px;border:16px solid #f3f3f3;border-radius:50%;border-top:16px solid #1db1ff;width:120px;height:120px;animation:spin 2s linear infinite}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}#loader-mask{text-align:center;position:absolute;width:100%;height:100%;bottom:0;left:0;right:0;top:0;z-index:1009;background-color:rgba(242,246,252,.88)}@media (prefers-color-scheme:dark){#loader-mask{color:#fff;background-color:rgba(0,0,0,.85)}#loader-mask a{color:#ddd}#loader-mask a:hover{color:#1db1ff}}#loader-source{font-size:1.5rem}#loader-tips-timeout{font-size:1.2rem}</style>
<!--@formatter:on-->
</head>
<body>
<meta content="音乐,解锁,ncm,qmc,mgg,mflac,qq音乐,网易云音乐,加密" name="keywords" />
<meta content="音乐解锁 - 在任何设备上解锁已购的加密音乐!" name="description" />
<style>
#loader {
position: absolute;
left: 50%;
top: 50%;
z-index: 1010;
margin: -75px 0 0 -75px;
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #1db1ff;
width: 120px;
height: 120px;
animation: spin 2s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
#loader-mask {
text-align: center;
position: absolute;
width: 100%;
height: 100%;
bottom: 0;
left: 0;
right: 0;
top: 0;
z-index: 1009;
background-color: rgba(242, 246, 252, 0.88);
}
@media (prefers-color-scheme: dark) {
#loader-mask {
color: #fff;
background-color: rgba(0, 0, 0, 0.85);
}
#loader-mask a {
color: #ddd;
}
#loader-mask a:hover {
color: #1db1ff;
}
}
#loader-source {
font-size: 1.5rem;
}
#loader-tips-timeout {
font-size: 1.2rem;
}
</style>
</head>
<div id="loader-mask">
<div id="loader"></div>
<noscript>
<body>
<div id="loader-mask">
<div id="loader"></div>
<noscript>
<h3 id="loader-js">请启用JavaScript</h3>
</noscript>
<h3 id="loader-source"> 请勿直接运行源代码! </h3>
<div id="loader-tips-outdated" hidden>
<h2>您可能在使用不受支持的<span style="color:#f00;">过时</span>浏览器,这可能导致此应用无法正常工作。</h2>
<h3>如果您使用双核浏览器,您可以尝试切换到 <span style="color:#f00;">“极速模式”</span> 解决此问题。</h3>
</noscript>
<h3 id="loader-source">请勿直接运行源代码!</h3>
<div id="loader-tips-outdated" hidden>
<h2>您可能在使用不受支持的<span style="color: #f00">过时</span>浏览器,这可能导致此应用无法正常工作。</h2>
<h3>如果您使用双核浏览器,您可以尝试切换到 <span style="color: #f00">“极速模式”</span> 解决此问题。</h3>
<h3>或者,您可以尝试更换下方的几个浏览器之一。</h3>
</div>
<h3 id="loader-tips-timeout" hidden>
</div>
<h3 id="loader-tips-timeout" hidden>
音乐解锁采用了一些新特性!建议使用
<a href="https://www.microsoft.com/zh-cn/edge" target="_blank">Microsoft Edge Chromium</a>
<a href="https://www.google.cn/chrome/" target="_blank">Google Chrome</a>
<a href="https://www.firefox.com.cn/" target="_blank">Mozilla Firefox</a>
| <a href="https://github.com/ix64/unlock-music/wiki/使用提示" target="_blank">使用提示</a>
</h3>
</div>
<div id="app"></div>
<script src="./loader.js"></script>
</body>
| <a href="https://git.unlock-music.dev/um/web/wiki/使用提示" target="_blank">使用提示</a>
</h3>
</div>
<div id="app"></div>
<script src="./loader.js"></script>
</body>
</html>

View File

@ -1,13 +0,0 @@
#!/usr/bin/env bash
set -ex
cd "$(git rev-parse --show-toplevel)"
pushd ./src/QmcWasm
bash build-wasm
popd
pushd ./src/KgmWasm
bash build-wasm
popd

View File

@ -1,23 +1,23 @@
<template>
<el-container id="app">
<el-main class="p-0">
<el-main>
<Home />
</el-main>
<el-footer id="app-footer">
<div>
<a href="https://github.com/ix64/unlock-music" target="_blank">音乐解锁</a>({{ version }})
<a href="https://git.unlock-music.dev/um/web" target="_blank">音乐解锁</a>({{ version }})
移除已购音乐的加密保护
<a href="https://github.com/ix64/unlock-music/wiki/使用提示" target="_blank">使用提示</a>
<a href="https://git.unlock-music.dev/um/web/wiki/使用提示" target="_blank">使用提示</a>
</div>
<div>
目前支持 网易云音乐(ncm), QQ音乐(qmc, mflac, mgg), 酷狗音乐(kgm), 虾米音乐(xm), 酷我音乐(.kwm)
<a href="https://github.com/ix64/unlock-music/blob/master/README.md" target="_blank">更多</a>
<a href="https://git.unlock-music.dev/um/web/src/branch/master/README.md" target="_blank">更多</a>
</div>
<div>
<!--如果进行二次开发此行版权信息不得移除且应明显地标注于页面上-->
<span>Copyright &copy; 2019 - {{ new Date().getFullYear() }} MengYX</span>
音乐解锁使用
<a href="https://github.com/ix64/unlock-music/blob/master/LICENSE" target="_blank">MIT许可协议</a>
<a href="https://git.unlock-music.dev/um/web/src/branch/master/LICENSE" target="_blank">MIT许可协议</a>
开放源代码
</div>
</el-footer>
@ -40,13 +40,11 @@ export default {
},
data() {
return {
version: config.version
version: config.version,
};
},
created() {
this.$nextTick(() => {
this.finishLoad()
});
this.$nextTick(() => this.finishLoad());
},
methods: {
async finishLoad() {
@ -79,7 +77,7 @@ export default {
<div class="update-title">最近更新</div>
<div class="update-content"> ${config.updateInfo} </div>
</div>
<a target="_blank" href="https://github.com/ix64/unlock-music/wiki/使用提示">使用提示</a>
<a target="_blank" href="https://git.unlock-music.dev/um/web/wiki/使用提示">使用提示</a>
</div>`,
dangerouslyUseHTMLString: true,
duration: 10000,

View File

@ -1,65 +0,0 @@
# CMakeList.txt : CMake project for KgmWasm, include source and define
# project specific logic here.
#
cmake_minimum_required (VERSION 3.8)
project ("KgmWasm")
set(CMAKE_CXX_STANDARD 14)
include_directories(
$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>
)
# Add source to this project's executable.
set(RUNTIME_METHODS_LIST
getValue
writeArrayToMemory
UTF8ToString
)
list(JOIN RUNTIME_METHODS_LIST "," RUNTIME_METHODS)
set(EMSCRIPTEN_FLAGS
"--bind"
"-s NO_DYNAMIC_EXECUTION=1"
"-s MODULARIZE=1"
"-s EXPORT_NAME=KgmCryptoModule"
"-s EXPORTED_RUNTIME_METHODS=${RUNTIME_METHODS}"
)
set(EMSCRIPTEN_LEGACY_FLAGS
${EMSCRIPTEN_FLAGS}
"-s WASM=0"
"--memory-init-file 0"
)
set(EMSCRIPTEN_WASM_BUNDLE_FLAGS
${EMSCRIPTEN_FLAGS}
"-s SINGLE_FILE=1"
)
list(JOIN EMSCRIPTEN_FLAGS " " EMSCRIPTEN_FLAGS_STR)
list(JOIN EMSCRIPTEN_LEGACY_FLAGS " " EMSCRIPTEN_LEGACY_FLAGS_STR)
list(JOIN EMSCRIPTEN_WASM_BUNDLE_FLAGS " " EMSCRIPTEN_WASM_BUNDLE_FLAGS_STR)
# Define projects config
set(WASM_SOURCES
"KgmWasm.cpp"
)
add_executable(KgmWasm ${WASM_SOURCES})
set_target_properties(
KgmWasm
PROPERTIES LINK_FLAGS ${EMSCRIPTEN_FLAGS_STR}
)
add_executable(KgmWasmBundle ${WASM_SOURCES})
set_target_properties(
KgmWasmBundle
PROPERTIES LINK_FLAGS ${EMSCRIPTEN_WASM_BUNDLE_FLAGS_STR}
)
add_executable(KgmLegacy ${WASM_SOURCES})
set_target_properties(
KgmLegacy
PROPERTIES LINK_FLAGS ${EMSCRIPTEN_LEGACY_FLAGS_STR}
)

View File

@ -1,20 +0,0 @@
// KgmWasm.cpp : Defines the entry point for the application.
//
#include "KgmWasm.h"
#include "kgm.hpp"
#include <stddef.h>
#include <string.h>
size_t preDec(uintptr_t blob, size_t blobSize, std::string ext)
{
return PreDec((uint8_t*)blob, blobSize, ext == "vpr");
}
void decBlob(uintptr_t blob, size_t blobSize, size_t offset)
{
Decrypt((uint8_t*)blob, blobSize, offset);
return;
}

View File

@ -1,18 +0,0 @@
// KgmWasm.h : Include file for standard system include files,
// or project specific include files.
#pragma once
#include <emscripten/bind.h>
#include <string>
namespace em = emscripten;
size_t preDec(uintptr_t blob, size_t blobSize, std::string ext);
void decBlob(uintptr_t blob, size_t blobSize, size_t offset);
EMSCRIPTEN_BINDINGS(QmcCrypto)
{
em::function("preDec", &preDec, em::allow_raw_pointers());
em::function("decBlob", &decBlob, em::allow_raw_pointers());
}

View File

@ -1,9 +0,0 @@
# KgmWasm
## 构建
在 Linux 环境下执行 `bash build-wasm` 即可构建。
## Build
Linux environment required. Build wasm binary by execute `bash build-wasm`.

View File

@ -1,41 +0,0 @@
#!/usr/bin/env bash
set -e
pushd "$(realpath "$(dirname "$0")")"
CURR_DIR="${PWD}"
BUILD_TYPE="$1"
if [ -z "$BUILD_TYPE" ]; then
BUILD_TYPE=Release
fi
# CI: already had emsdk installed.
if ! command -v emcc; then
if [ ! -d ../../build/emsdk ]; then
git clone https://github.com/emscripten-core/emsdk.git ../../build/emsdk
fi
pushd ../../build/emsdk
./emsdk install 3.0.0
./emsdk activate 3.0.0
source ./emsdk_env.sh
popd # ../../build/emsdk
fi
mkdir -p build/wasm
pushd build/wasm
emcmake cmake -DCMAKE_BUILD_TYPE="$BUILD_TYPE" ../..
make -j
TARGET_FILES="
KgmLegacy.js
KgmWasm.js
KgmWasm.wasm
KgmWasmBundle.js
"
cp $TARGET_FILES "${CURR_DIR}/"
popd # build/wasm
popd

View File

@ -1,112 +0,0 @@
#include <vector>
std::vector<uint8_t> VprHeader = {
0x05, 0x28, 0xBC, 0x96, 0xE9, 0xE4, 0x5A, 0x43,
0x91, 0xAA, 0xBD, 0xD0, 0x7A, 0xF5, 0x36, 0x31 };
std::vector<uint8_t> KgmHeader = {
0x7C, 0xD5, 0x32, 0xEB, 0x86, 0x02, 0x7F, 0x4B,
0xA8, 0xAF, 0xA6, 0x8E, 0x0F, 0xFF, 0x99, 0x14 };
std::vector<uint8_t> VprMaskDiff = {
0x25, 0xDF, 0xE8, 0xA6, 0x75, 0x1E, 0x75, 0x0E,
0x2F, 0x80, 0xF3, 0x2D, 0xB8, 0xB6, 0xE3, 0x11, 0x00 };
std::vector<uint8_t> MaskV2;
std::vector<uint8_t> table1 = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x21, 0x01, 0x61, 0x01, 0x21, 0x01, 0xe1, 0x01, 0x21, 0x01, 0x61, 0x01, 0x21, 0x01,
0xd2, 0x23, 0x02, 0x02, 0x42, 0x42, 0x02, 0x02, 0xc2, 0xc2, 0x02, 0x02, 0x42, 0x42, 0x02, 0x02,
0xd3, 0xd3, 0x02, 0x03, 0x63, 0x43, 0x63, 0x03, 0xe3, 0xc3, 0xe3, 0x03, 0x63, 0x43, 0x63, 0x03,
0x94, 0xb4, 0x94, 0x65, 0x04, 0x04, 0x04, 0x04, 0x84, 0x84, 0x84, 0x84, 0x04, 0x04, 0x04, 0x04,
0x95, 0x95, 0x95, 0x95, 0x04, 0x05, 0x25, 0x05, 0xe5, 0x85, 0xa5, 0x85, 0xe5, 0x05, 0x25, 0x05,
0xd6, 0xb6, 0x96, 0xb6, 0xd6, 0x27, 0x06, 0x06, 0xc6, 0xc6, 0x86, 0x86, 0xc6, 0xc6, 0x06, 0x06,
0xd7, 0xd7, 0x97, 0x97, 0xd7, 0xd7, 0x06, 0x07, 0xe7, 0xc7, 0xe7, 0x87, 0xe7, 0xc7, 0xe7, 0x07,
0x18, 0x38, 0x18, 0x78, 0x18, 0x38, 0x18, 0xe9, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x08, 0x09, 0x29, 0x09, 0x69, 0x09, 0x29, 0x09,
0xda, 0x3a, 0x1a, 0x3a, 0x5a, 0x3a, 0x1a, 0x3a, 0xda, 0x2b, 0x0a, 0x0a, 0x4a, 0x4a, 0x0a, 0x0a,
0xdb, 0xdb, 0x1b, 0x1b, 0x5b, 0x5b, 0x1b, 0x1b, 0xdb, 0xdb, 0x0a, 0x0b, 0x6b, 0x4b, 0x6b, 0x0b,
0x9c, 0xbc, 0x9c, 0x7c, 0x1c, 0x3c, 0x1c, 0x7c, 0x9c, 0xbc, 0x9c, 0x6d, 0x0c, 0x0c, 0x0c, 0x0c,
0x9d, 0x9d, 0x9d, 0x9d, 0x1d, 0x1d, 0x1d, 0x1d, 0x9d, 0x9d, 0x9d, 0x9d, 0x0c, 0x0d, 0x2d, 0x0d,
0xde, 0xbe, 0x9e, 0xbe, 0xde, 0x3e, 0x1e, 0x3e, 0xde, 0xbe, 0x9e, 0xbe, 0xde, 0x2f, 0x0e, 0x0e,
0xdf, 0xdf, 0x9f, 0x9f, 0xdf, 0xdf, 0x1f, 0x1f, 0xdf, 0xdf, 0x9f, 0x9f, 0xdf, 0xdf, 0x0e, 0x0f,
0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0xe0, 0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0xf1
};
std::vector<uint8_t> table2 = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x23, 0x01, 0x67, 0x01, 0x23, 0x01, 0xef, 0x01, 0x23, 0x01, 0x67, 0x01, 0x23, 0x01,
0xdf, 0x21, 0x02, 0x02, 0x46, 0x46, 0x02, 0x02, 0xce, 0xce, 0x02, 0x02, 0x46, 0x46, 0x02, 0x02,
0xde, 0xde, 0x02, 0x03, 0x65, 0x47, 0x65, 0x03, 0xed, 0xcf, 0xed, 0x03, 0x65, 0x47, 0x65, 0x03,
0x9d, 0xbf, 0x9d, 0x63, 0x04, 0x04, 0x04, 0x04, 0x8c, 0x8c, 0x8c, 0x8c, 0x04, 0x04, 0x04, 0x04,
0x9c, 0x9c, 0x9c, 0x9c, 0x04, 0x05, 0x27, 0x05, 0xeb, 0x8d, 0xaf, 0x8d, 0xeb, 0x05, 0x27, 0x05,
0xdb, 0xbd, 0x9f, 0xbd, 0xdb, 0x25, 0x06, 0x06, 0xca, 0xca, 0x8e, 0x8e, 0xca, 0xca, 0x06, 0x06,
0xda, 0xda, 0x9e, 0x9e, 0xda, 0xda, 0x06, 0x07, 0xe9, 0xcb, 0xe9, 0x8f, 0xe9, 0xcb, 0xe9, 0x07,
0x19, 0x3b, 0x19, 0x7f, 0x19, 0x3b, 0x19, 0xe7, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x08, 0x09, 0x2b, 0x09, 0x6f, 0x09, 0x2b, 0x09,
0xd7, 0x39, 0x1b, 0x39, 0x5f, 0x39, 0x1b, 0x39, 0xd7, 0x29, 0x0a, 0x0a, 0x4e, 0x4e, 0x0a, 0x0a,
0xd6, 0xd6, 0x1a, 0x1a, 0x5e, 0x5e, 0x1a, 0x1a, 0xd6, 0xd6, 0x0a, 0x0b, 0x6d, 0x4f, 0x6d, 0x0b,
0x95, 0xb7, 0x95, 0x7b, 0x1d, 0x3f, 0x1d, 0x7b, 0x95, 0xb7, 0x95, 0x6b, 0x0c, 0x0c, 0x0c, 0x0c,
0x94, 0x94, 0x94, 0x94, 0x1c, 0x1c, 0x1c, 0x1c, 0x94, 0x94, 0x94, 0x94, 0x0c, 0x0d, 0x2f, 0x0d,
0xd3, 0xb5, 0x97, 0xb5, 0xd3, 0x3d, 0x1f, 0x3d, 0xd3, 0xb5, 0x97, 0xb5, 0xd3, 0x2d, 0x0e, 0x0e,
0xd2, 0xd2, 0x96, 0x96, 0xd2, 0xd2, 0x1e, 0x1e, 0xd2, 0xd2, 0x96, 0x96, 0xd2, 0xd2, 0x0e, 0x0f,
0x00, 0x22, 0x00, 0x66, 0x00, 0x22, 0x00, 0xee, 0x00, 0x22, 0x00, 0x66, 0x00, 0x22, 0x00, 0xfe
};
std::vector<uint8_t> MaskV2PreDef = {
0xB8, 0xD5, 0x3D, 0xB2, 0xE9, 0xAF, 0x78, 0x8C, 0x83, 0x33, 0x71, 0x51, 0x76, 0xA0, 0xCD, 0x37,
0x2F, 0x3E, 0x35, 0x8D, 0xA9, 0xBE, 0x98, 0xB7, 0xE7, 0x8C, 0x22, 0xCE, 0x5A, 0x61, 0xDF, 0x68,
0x69, 0x89, 0xFE, 0xA5, 0xB6, 0xDE, 0xA9, 0x77, 0xFC, 0xC8, 0xBD, 0xBD, 0xE5, 0x6D, 0x3E, 0x5A,
0x36, 0xEF, 0x69, 0x4E, 0xBE, 0xE1, 0xE9, 0x66, 0x1C, 0xF3, 0xD9, 0x02, 0xB6, 0xF2, 0x12, 0x9B,
0x44, 0xD0, 0x6F, 0xB9, 0x35, 0x89, 0xB6, 0x46, 0x6D, 0x73, 0x82, 0x06, 0x69, 0xC1, 0xED, 0xD7,
0x85, 0xC2, 0x30, 0xDF, 0xA2, 0x62, 0xBE, 0x79, 0x2D, 0x62, 0x62, 0x3D, 0x0D, 0x7E, 0xBE, 0x48,
0x89, 0x23, 0x02, 0xA0, 0xE4, 0xD5, 0x75, 0x51, 0x32, 0x02, 0x53, 0xFD, 0x16, 0x3A, 0x21, 0x3B,
0x16, 0x0F, 0xC3, 0xB2, 0xBB, 0xB3, 0xE2, 0xBA, 0x3A, 0x3D, 0x13, 0xEC, 0xF6, 0x01, 0x45, 0x84,
0xA5, 0x70, 0x0F, 0x93, 0x49, 0x0C, 0x64, 0xCD, 0x31, 0xD5, 0xCC, 0x4C, 0x07, 0x01, 0x9E, 0x00,
0x1A, 0x23, 0x90, 0xBF, 0x88, 0x1E, 0x3B, 0xAB, 0xA6, 0x3E, 0xC4, 0x73, 0x47, 0x10, 0x7E, 0x3B,
0x5E, 0xBC, 0xE3, 0x00, 0x84, 0xFF, 0x09, 0xD4, 0xE0, 0x89, 0x0F, 0x5B, 0x58, 0x70, 0x4F, 0xFB,
0x65, 0xD8, 0x5C, 0x53, 0x1B, 0xD3, 0xC8, 0xC6, 0xBF, 0xEF, 0x98, 0xB0, 0x50, 0x4F, 0x0F, 0xEA,
0xE5, 0x83, 0x58, 0x8C, 0x28, 0x2C, 0x84, 0x67, 0xCD, 0xD0, 0x9E, 0x47, 0xDB, 0x27, 0x50, 0xCA,
0xF4, 0x63, 0x63, 0xE8, 0x97, 0x7F, 0x1B, 0x4B, 0x0C, 0xC2, 0xC1, 0x21, 0x4C, 0xCC, 0x58, 0xF5,
0x94, 0x52, 0xA3, 0xF3, 0xD3, 0xE0, 0x68, 0xF4, 0x00, 0x23, 0xF3, 0x5E, 0x0A, 0x7B, 0x93, 0xDD,
0xAB, 0x12, 0xB2, 0x13, 0xE8, 0x84, 0xD7, 0xA7, 0x9F, 0x0F, 0x32, 0x4C, 0x55, 0x1D, 0x04, 0x36,
0x52, 0xDC, 0x03, 0xF3, 0xF9, 0x4E, 0x42, 0xE9, 0x3D, 0x61, 0xEF, 0x7C, 0xB6, 0xB3, 0x93, 0x50,
};
uint8_t getMask(size_t pos) {
size_t offset = pos >> 4;
uint8_t value = 0;
while (offset >= 0x11) {
value ^= table1[offset % 272];
offset >>= 4;
value ^= table2[offset % 272];
offset >>= 4;
}
return MaskV2PreDef[pos % 272] ^ value;
}
std::vector<uint8_t> key(17);
bool isVpr = false;
size_t PreDec(uint8_t* fileData, size_t size, bool iV) {
uint32_t headerLen = *(uint32_t*)(fileData + 0x10);
memcpy(key.data(), (fileData + 0x1C), 0x10);
key[16] = 0;
isVpr = iV;
return headerLen;
}
void Decrypt(uint8_t* fileData, size_t size, size_t offset) {
for (size_t i = 0; i < size; ++i) {
uint8_t med8 = key[(i + offset) % 17] ^ fileData[i];
med8 ^= (med8 & 0xf) << 4;
uint8_t msk8 = getMask(i + offset);
msk8 ^= (msk8 & 0xf) << 4;
fileData[i] = med8 ^ msk8;
if (isVpr) {
fileData[i] ^= VprMaskDiff[(i + offset) % 17];
}
}
}

View File

@ -1,65 +0,0 @@
# CMakeList.txt : CMake project for QmcWasm, include source and define
# project specific logic here.
#
cmake_minimum_required (VERSION 3.8)
project ("QmcWasm")
set(CMAKE_CXX_STANDARD 14)
include_directories(
$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>
)
# Add source to this project's executable.
set(RUNTIME_METHODS_LIST
getValue
writeArrayToMemory
UTF8ToString
)
list(JOIN RUNTIME_METHODS_LIST "," RUNTIME_METHODS)
set(EMSCRIPTEN_FLAGS
"--bind"
"-s NO_DYNAMIC_EXECUTION=1"
"-s MODULARIZE=1"
"-s EXPORT_NAME=QmcCryptoModule"
"-s EXPORTED_RUNTIME_METHODS=${RUNTIME_METHODS}"
)
set(EMSCRIPTEN_LEGACY_FLAGS
${EMSCRIPTEN_FLAGS}
"-s WASM=0"
"--memory-init-file 0"
)
set(EMSCRIPTEN_WASM_BUNDLE_FLAGS
${EMSCRIPTEN_FLAGS}
"-s SINGLE_FILE=1"
)
list(JOIN EMSCRIPTEN_FLAGS " " EMSCRIPTEN_FLAGS_STR)
list(JOIN EMSCRIPTEN_LEGACY_FLAGS " " EMSCRIPTEN_LEGACY_FLAGS_STR)
list(JOIN EMSCRIPTEN_WASM_BUNDLE_FLAGS " " EMSCRIPTEN_WASM_BUNDLE_FLAGS_STR)
# Define projects config
set(WASM_SOURCES
"QmcWasm.cpp"
)
add_executable(QmcWasm ${WASM_SOURCES})
set_target_properties(
QmcWasm
PROPERTIES LINK_FLAGS ${EMSCRIPTEN_FLAGS_STR}
)
add_executable(QmcWasmBundle ${WASM_SOURCES})
set_target_properties(
QmcWasmBundle
PROPERTIES LINK_FLAGS ${EMSCRIPTEN_WASM_BUNDLE_FLAGS_STR}
)
add_executable(QmcLegacy ${WASM_SOURCES})
set_target_properties(
QmcLegacy
PROPERTIES LINK_FLAGS ${EMSCRIPTEN_LEGACY_FLAGS_STR}
)

View File

@ -1,57 +0,0 @@
// QmcWasm.cpp : Defines the entry point for the application.
//
#include "QmcWasm.h"
#include "qmc.hpp"
#include <stddef.h>
#include <string.h>
std::string err = "";
std::string sid = "";
QmcDecode e;
int preDec(uintptr_t blob, size_t blobSize, std::string ext)
{
if (!e.SetBlob((uint8_t*)blob, blobSize))
{
err = "cannot allocate memory";
return -1;
}
int tailSize = e.PreDecode(ext);
if (e.error != "")
{
err = e.error;
return -1;
}
sid = e.songId;
return tailSize;
}
size_t decBlob(uintptr_t blob, size_t blobSize, size_t offset)
{
if (!e.SetBlob((uint8_t*)blob, blobSize))
{
err = "cannot allocate memory";
return 0;
}
std::vector<uint8_t> decData = e.Decode(offset);
if (e.error != "")
{
err = e.error;
return 0;
}
memcpy((uint8_t*)blob, decData.data(), decData.size());
return decData.size();
}
std::string getErr()
{
return err;
}
std::string getSongId()
{
return sid;
}

View File

@ -1,23 +0,0 @@
// QmcWasm.h : Include file for standard system include files,
// or project specific include files.
#pragma once
#include <emscripten/bind.h>
#include <string>
namespace em = emscripten;
int preDec(uintptr_t blob, size_t blobSize, std::string ext);
size_t decBlob(uintptr_t blob, size_t blobSize, size_t offset);
std::string getErr();
std::string getSongId();
EMSCRIPTEN_BINDINGS(QmcCrypto)
{
em::function("getErr", &getErr);
em::function("getSongId", &getSongId);
em::function("preDec", &preDec, em::allow_raw_pointers());
em::function("decBlob", &decBlob, em::allow_raw_pointers());
}

View File

@ -1,9 +0,0 @@
# QmcWasm
## 构建
在 Linux 环境下执行 `bash build-wasm` 即可构建。
## Build
Linux environment required. Build wasm binary by execute `bash build-wasm`.

View File

@ -1,289 +0,0 @@
#ifndef QQMUSIC_CPP_TENCENTTEA_HPP
#define QQMUSIC_CPP_TENCENTTEA_HPP
#include <cstdlib>
#include <cstdio>
#include <cstdint>
#include <vector>
#include <time.h>
#include <arpa/inet.h>
const uint32_t DELTA = 0x9e3779b9;
#define ROUNDS 32
#define SALT_LEN 2
#define ZERO_LEN 7
void TeaDecryptECB(uint8_t* src, uint8_t* dst, std::vector<uint8_t> key, size_t rounds = ROUNDS) {
if (key.size() != 16 || (rounds & 1) != 0)
{
return;
}
uint32_t y, z, sum;
uint32_t k[4];
int i;
//now encrypted buf is TCP/IP-endian;
//TCP/IP network byte order (which is big-endian).
y = ntohl(*((uint32_t*)src));
z = ntohl(*((uint32_t*)(src + 4)));
//std::cout << ntohl(0x0a3aea41);
for (i = 0; i < 4; i++) {
//key is TCP/IP-endian;
k[i] = ntohl(*((uint32_t*)(key.data() + i * 4)));
}
sum = (DELTA * rounds);
for (i = 0; i < rounds; i++) {
z -= ((y << 4) + k[2]) ^ (y + sum) ^ ((y >> 5) + k[3]);
y -= ((z << 4) + k[0]) ^ (z + sum) ^ ((z >> 5) + k[1]);
sum -= DELTA;
}
*((uint32_t*)dst) = ntohl(y);
*((uint32_t*)(dst + 4)) = ntohl(z);
//now plain-text is TCP/IP-endian;
}
void TeaEncryptECB(uint8_t* src, uint8_t* dst, std::vector<uint8_t> key, size_t rounds = ROUNDS) {
if (key.size() != 16 || (rounds & 1) != 0)
{
return;
}
uint32_t y, z, sum;
uint32_t k[4];
int i;
//now encrypted buf is TCP/IP-endian;
//TCP/IP network byte order (which is big-endian).
y = ntohl(*((uint32_t*)src));
z = ntohl(*((uint32_t*)(src + 4)));
//std::cout << ntohl(0x0a3aea41);
for (i = 0; i < 4; i++) {
//key is TCP/IP-endian;
k[i] = ntohl(*((uint32_t*)(key.data() + i * 4)));
}
sum = 0;
for (i = 0; i < rounds; i++) {
sum += DELTA;
y += ((z << 4) + k[0]) ^ (z + sum) ^ ((z >> 5) + k[1]);
z += ((y << 4) + k[2]) ^ (y + sum) ^ ((y >> 5) + k[3]);
}
*((uint32_t*)dst) = ntohl(y);
*((uint32_t*)(dst + 4)) = ntohl(z);
//now plain-text is TCP/IP-endian;
}
/*pKey为16byte*/
/*
:nInBufLen为需加密的明文部分(Body);
:(8byte的倍数);
*/
/*TEA加密算法,CBC模式*/
/*密文格式:PadLen(1byte)+Padding(var,0-7byte)+Salt(2byte)+Body(var byte)+Zero(7byte)*/
int encryptTencentTeaLen(int nInBufLen)
{
int nPadSaltBodyZeroLen/*PadLen(1byte)+Salt+Body+Zero的长度*/;
int nPadlen;
/*根据Body长度计算PadLen,最小必需长度必需为8byte的整数倍*/
nPadSaltBodyZeroLen = nInBufLen/*Body长度*/ + 1 + SALT_LEN + ZERO_LEN/*PadLen(1byte)+Salt(2byte)+Zero(7byte)*/;
if ((nPadlen = nPadSaltBodyZeroLen % 8)) /*len=nSaltBodyZeroLen%8*/
{
/*模8余0需补0,余1补7,余2补6,...,余7补1*/
nPadlen = 8 - nPadlen;
}
return nPadlen;
}
/*pKey为16byte*/
/*
:pInBuf为需加密的明文部分(Body),nInBufLen为pInBuf长度;
:pOutBuf为密文格式,pOutBufLen为pOutBuf的长度是8byte的倍数;
*/
/*TEA加密算法,CBC模式*/
/*密文格式:PadLen(1byte)+Padding(var,0-7byte)+Salt(2byte)+Body(var byte)+Zero(7byte)*/
bool encryptTencentTea(std::vector<uint8_t> inBuf, std::vector<uint8_t> key, std::vector<uint8_t> &outBuf)
{
srand(time(0));
int nPadlen = encryptTencentTeaLen(inBuf.size());
size_t ivCrypt;
std::vector<uint8_t> srcBuf;
srcBuf.resize(8);
std::vector<uint8_t> ivPlain;
ivPlain.resize(8);
int tmpIdx, i, j;
/*加密第一块数据(8byte),取前面10byte*/
srcBuf[0] = (((char)rand()) & 0x0f8)/*最低三位存PadLen,清零*/ | (char)nPadlen;
tmpIdx = 1; /*tmpIdx指向srcBuf下一个位置*/
while (nPadlen--) srcBuf[tmpIdx++] = (char)rand(); /*Padding*/
/*come here, tmpIdx must <= 8*/
for (i = 0; i < 8; i++) ivPlain[i] = 0;
ivCrypt = 0;//ivPlain /*make zero iv*/
auto outBufPos = 0; /*init outBufPos*/
#define cryptBlock {\
/*tmpIdx==8*/\
outBuf.resize(outBuf.size() + 8);\
for (j = 0; j < 8; j++) /*加密前异或前8个byte的密文(iv_crypt指向的)*/\
srcBuf[j] ^= outBuf[j + ivCrypt];\
/*pOutBuffer、pInBuffer均为8byte, pKey为16byte*/\
/*加密*/\
TeaEncryptECB(srcBuf.data(), outBuf.data()+outBufPos, key, 16);\
for (j = 0; j < 8; j++) /*加密后异或前8个byte的明文(iv_plain指向的)*/\
outBuf[j + outBufPos] ^= ivPlain[j];\
/*保存当前的iv_plain*/\
for (j = 0; j < 8; j++) ivPlain[j] = srcBuf[j];\
/*更新iv_crypt*/\
tmpIdx = 0;\
ivCrypt = outBufPos;\
outBufPos += 8;\
}
for (i = 1; i <= SALT_LEN;) /*Salt(2byte)*/
{
if (tmpIdx < 8)
{
srcBuf[tmpIdx++] = (char)rand();
i++; /*i inc in here*/
}
if (tmpIdx == 8)
{
cryptBlock
}
}
/*tmpIdx指向srcBuf下一个位置*/
auto inBufPos = 0;
while (inBufPos < inBuf.size())
{
if (tmpIdx < 8)
{
srcBuf[tmpIdx++] = inBuf[inBufPos];
inBufPos++;
}
if (tmpIdx == 8)
{
cryptBlock
}
}
/*tmpIdx指向srcBuf下一个位置*/
for (i = 1; i <= ZERO_LEN;)
{
if (tmpIdx < 8)
{
srcBuf[tmpIdx++] = 0;
i++; //i inc in here
}
if (tmpIdx == 8)
{
cryptBlock
}
}
return true;
#undef cryptBlock
}
bool decryptTencentTea(std::vector<uint8_t> inBuf, std::vector<uint8_t> key, std::vector<uint8_t> &out) {
if (inBuf.size() % 8 != 0) {
return false;
//inBuf size not a multiple of the block size
}
if (inBuf.size() < 16) {
return false;
//inBuf size too small
}
std::vector<uint8_t> tmpBuf;
tmpBuf.resize(8);
TeaDecryptECB(inBuf.data(), tmpBuf.data(), key, 16);
auto nPadLen = tmpBuf[0] & 0x7; //只要最低三位
/*密文格式:PadLen(1byte)+Padding(var,0-7byte)+Salt(2byte)+Body(var byte)+Zero(7byte)*/
auto outLen = inBuf.size() - 1 /*PadLen*/ - nPadLen - SALT_LEN - ZERO_LEN;
std::vector<uint8_t> outBuf;
outBuf.resize(outLen);
std::vector<uint8_t> ivPrev;
ivPrev.resize(8);
std::vector<uint8_t> ivCur;
ivCur.resize(8);
for (size_t i = 0; i < 8; i++)
{
ivCur[i] = inBuf[i]; // init iv
}
auto inBufPos = 8;
// 跳过 Padding Len 和 Padding
auto tmpIdx = 1 + nPadLen;
// CBC IV 处理
#define cryptBlock {\
ivPrev = ivCur;\
for (size_t k = inBufPos; k < inBufPos + 8; k++)\
{\
ivCur[k - inBufPos] = inBuf[k];\
}\
for (size_t j = 0; j < 8; j++) {\
tmpBuf[j] ^= ivCur[j];\
}\
TeaDecryptECB(tmpBuf.data(), tmpBuf.data(), key, 16);\
inBufPos += 8;\
tmpIdx = 0;\
}
// 跳过 Salt
for (size_t i = 1; i <= SALT_LEN; ) {
if (tmpIdx < 8) {
tmpIdx++;
i++;
}
else {
cryptBlock
}
}
// 还原明文
auto outBufPos = 0;
while (outBufPos < outLen) {
if (tmpIdx < 8) {
outBuf[outBufPos] = tmpBuf[tmpIdx] ^ ivPrev[tmpIdx];
outBufPos++;
tmpIdx++;
}
else {
cryptBlock
}
}
// 校验Zero
for (size_t i = 1; i <= ZERO_LEN; i++) {
if (tmpBuf[i] != ivPrev[i]) {
return false;
//zero check failed
}
}
out = outBuf;
return true;
#undef cryptBlock
}
#endif //QQMUSIC_CPP_TENCENTTEA_HPP

View File

@ -1,207 +0,0 @@
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
/*
Portions from http://www.adp-gmbh.ch/cpp/common/base64.html
Copyright notice:
base64.cpp and base64.h
Copyright (C) 2004-2008 Rene Nyffenegger
This source code is provided 'as-is', without any express or implied
<