From 00aa243053be263dbc5a5a5f59abd52d715bb660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=8B=20=E5=A5=88=E6=9C=88?= <43605695+akinazuki@users.noreply.github.com> Date: Tue, 16 Aug 2022 00:58:20 +0800 Subject: [PATCH 1/3] rebuild blog --- _config.melody.yml | 14 +- _config.yml | 4 +- .../netease-eapi-music-recognize-reverse-1.md | 202 +++++++++++------- .../netease-eapi-music-recognize-reverse-2.md | 45 +++- .../netease-eapi-music-recognize-reverse-3.md | 21 +- source/about/index.md | 24 +++ source/labs/index.md | 8 + source/links/index.md | 23 ++ 8 files changed, 247 insertions(+), 94 deletions(-) create mode 100644 source/about/index.md create mode 100644 source/labs/index.md create mode 100644 source/links/index.md diff --git a/_config.melody.yml b/_config.melody.yml index 949934c..62d2193 100644 --- a/_config.melody.yml +++ b/_config.melody.yml @@ -127,9 +127,9 @@ cdn: fontawesome: https://cdn.jsdelivr.net/npm/font-awesome@latest/css/font-awesome.min.css # fontawesomeV5: https://use.fontawesome.com/releases/v5.3.1/css/all.css js: - anime: https://cdn.jsdelivr.net/npm/animejs@latest/lib/anime.min.js - jquery: https://cdn.jsdelivr.net/npm/jquery@latest/dist/jquery.min.js - fancybox: https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@latest/dist/jquery.fancybox.min.js + anime: https://cdnjs.loli.net/ajax/libs/animejs/3.2.1/anime.min.js + jquery: https://cdnjs.loli.net/ajax/libs/jquery/3.6.0/jquery.min.js + fancybox: https://cdnjs.loli.net/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.js velocity: https://cdn.jsdelivr.net/npm/velocity-animate@latest/velocity.min.js velocity-ui: https://cdn.jsdelivr.net/npm/velocity-ui-pack@latest/velocity.ui.min.js @@ -211,9 +211,9 @@ addThis: # Comments System # --------------- disqus: - enable: false - #shortname: - #count: + enable: true + shortname: nazukis-blog + count: true # laibili: # enable: false @@ -269,7 +269,7 @@ disqus: # Footer Settings # --------------- -since: 2017 +since: 2015 footer_custom_text: 萌ICP备20229233号 diff --git a/_config.yml b/_config.yml index 1713a1f..6d40c2e 100644 --- a/_config.yml +++ b/_config.yml @@ -13,8 +13,8 @@ timezone: '' # URL ## Set your site url heare. For example, if you use GitHub Page, set url as 'https://username.github.io/project' -url: http://example.com -permalink: :year/:month/:day/:title/ +url: https://nazuki.moe +permalink: :title/ permalink_defaults: pretty_urls: trailing_index: true # Set to false to remove trailing 'index.html' from permalinks diff --git a/source/_posts/netease-eapi-music-recognize-reverse-1.md b/source/_posts/netease-eapi-music-recognize-reverse-1.md index f8a023a..c9bcb6d 100644 --- a/source/_posts/netease-eapi-music-recognize-reverse-1.md +++ b/source/_posts/netease-eapi-music-recognize-reverse-1.md @@ -1,103 +1,139 @@ --- -title: netease-eapi-music-recognize-reverse-1 -date: 2022-06-27 13:46:44 +title: 网易云音乐听歌识曲 API 逆向 (一) +date: 2022-05-05 tags: --- 首先是抓了一下协议, 网易云音乐的接口本身是有加密的, 但是没关系, 已经有 [NetEaseCloudMusic](https://github.com/Binaryify/NeteaseCloudMusicApi) 这样的项目逆向出了基本的通讯协议, 可以直接使用. +  + + + 网易云音乐识曲会向 `https://music.163.com/eapi/music/audio/match?_nmclfl=1` 这个接口发送请求 + 解密后的请求体大概长这样 ```json -{ - "rawdata":"eJx11H9M1HUYB\/C7+2p5\/PhHTUQGwW......", - "from":"recognize-song", - "verifyId":1, - "deviceId":"??????", - "os":"iOS", - "header":{ - - }, - "algorithmCode":"shazam_v2", - "times":1, - "sessionId":"??????", - "duration":3.4, - "e_r":true, - "sceneParams":"{\"action\":0,\"code\":2}" -} +{ + "rawdata":"eJx11H9M1HUYB/C7+2p5/PhHTUQGwW......", + "from":"recognize-song", + "verifyId":1, + "deviceId":"??????", + "os":"iOS", + "header":{ + + }, + "algorithmCode":"shazam_v2", + "times":1, + "sessionId":"??????", + "duration":3.4, + "e_r":true, + "sceneParams":"{"action":0,"code":2}" +} ``` -  -猜测其中 `rawdata` 就是录音的 Base64 编码, 尝试解码扔进 ffprobe, 但是失败了 + +猜测其中 `rawdata` 就是录音的 Base64 编码, 尝试解码扔进 ffprobe, 但是失败了 有可能 `rawdata` 是根据音频频谱生成了摘要, `algorithmCode` 字段也提示了 `shazam_v2` 这个值 + 接下来开始逆向 APP + 下载了一份比较旧但还能用的 网易云音乐 APK -[old_version_apk.png](https://s2.loli.net/2022/05/05/uliO4SfnUpyIN1L.png) + + + 扔进 Jadx, 发现有比较奇特的混淆方法, 任意地方的字符串都会调用一个函数来进行解密 -[Obfuscation.jpg](https://s2.loli.net/2022/05/05/wrAiL2uzyHUsPD7.jpg) + + + 定位到解密函数 -[decryptor.png](https://s2.loli.net/2022/05/05/d43Aw5fTby2h9ju.png) + + + 这里的解密看起来并不困难, `C0003a()` 这个类显然是 Base64 解码用的 -过我们要写出一个反向的操作(用来方便逆向查找字符串) +不过我们要写出一个反向的操作(用来方便逆向查找字符串) ```java -import java.util.Base64; - -class Main { - public static String key = "Encrypt"; - - public static void main(String[] args) { - if (args[0].equals("decrypt")) { - System.out.println(decrypt(args[1]));; - }else{ - System.out.println(encrypt(args[1])); - } - } - - public static String decrypt(String s) { - byte[] decode = Base64.getDecoder().decode(s); - String str2; - int length = decode.length; - int length2 = key.length(); - int i = 0; - int i2 = 0; - while (true) { - int i3 = i2; - if (i >= length) { - break; - } - int i4 = i3; - if (i3 >= length2) { - i4 = 0; - } - decode[i] = (byte) (decode[i] ^ key.charAt(i4)); - i++; - i2 = i4 + 1; - } - str2 = new String(decode); - return str2; - } - - public static String encrypt(String str_enc) { - byte[] s = str_enc.getBytes(); - int length = str_enc.length(); - int length2 = key.length(); - int i = 0; - int i2 = 0; - while (true) { - int i3 = i2; - if (i >= length) { - break; - } - int i4 = i3; - if (i3 >= length2) { - i4 = 0; - } - s[i] = (byte) (s[i] ^ key.charAt(i4)); - i++; - i2 = i4 + 1; - } - return Base64.getEncoder().encodeToString(s); - } -} +import java.util.Base64; + +class Main { + public static String key = "Encrypt"; + + public static void main(String[] args) { + if (args[0].equals("decrypt")) { + System.out.println(decrypt(args[1]));; + }else{ + System.out.println(encrypt(args[1])); + } + } + + public static String decrypt(String s) { + byte[] decode = Base64.getDecoder().decode(s); + String str2; + int length = decode.length; + int length2 = key.length(); + int i = 0; + int i2 = 0; + while (true) { + int i3 = i2; + if (i >= length) { + break; + } + int i4 = i3; + if (i3 >= length2) { + i4 = 0; + } + decode[i] = (byte) (decode[i] ^ key.charAt(i4)); + i++; + i2 = i4 + 1; + } + str2 = new String(decode); + return str2; + } + + public static String encrypt(String str_enc) { + byte[] s = str_enc.getBytes(); + int length = str_enc.length(); + int length2 = key.length(); + int i = 0; + int i2 = 0; + while (true) { + int i3 = i2; + if (i >= length) { + break; + } + int i4 = i3; + if (i3 >= length2) { + i4 = 0; + } + s[i] = (byte) (s[i] ^ key.charAt(i4)); + i++; + i2 = i4 + 1; + } + return Base64.getEncoder().encodeToString(s); + } +} ``` +根据 `rawdata` 这个关键词在 Jadx 里查找 + + + +确实能找到这个字符串 + + + +继续跟踪函数调用栈, 最终跟踪到了 `MusicDetector` 类 + + + +看起来是 `getFP()` 这个 Native 函数返回了一个三维数组, 最终封装成了 `rawdata` + + + + + +暂时跟踪不下去了, 看见汇编就头大( + +敬请期待第二章(咕咕咕 + + \ No newline at end of file diff --git a/source/_posts/netease-eapi-music-recognize-reverse-2.md b/source/_posts/netease-eapi-music-recognize-reverse-2.md index e089087..264eb0d 100644 --- a/source/_posts/netease-eapi-music-recognize-reverse-2.md +++ b/source/_posts/netease-eapi-music-recognize-reverse-2.md @@ -1,5 +1,48 @@ --- -title: netease-eapi-music-recognize-reverse-2 +title: 网易云音乐听歌识曲 API 逆向 (二) date: 2022-05-12 00:33:26 tags: --- + + +前两天看到网易云音乐发布了一个网页上做音乐识别的 [Chrome 插件](https://juejin.cn/post/7094083239702659109) + + + + + +于是立即下载了一份来研究 + + + +Chrome 插件的请求方式和结构和客户端几乎一模一样 + + + +根据函数栈追踪, 可以分析出比较核心的逻辑都在 `sandbox.bundle.js` 内 + +看起来是用了 WebAssemble 来解析网页录音, 在点击开始录音后会开始录制当前 TAB 的音频 + +当录音完成后就会将音频传到 WASM 暴露的函数 `l().ExtractQueryFP(...)` 中 + + + +WASM 层处理完成后就会将返回的 ArrayBuffer 封装成一个 Base64 串, 最后会将这个 Base64 串提交给 API + + + +* * * + +虽然还是不太清楚 WASM 层内部是如何处理传入的音频数据, 但是已经可以将它的代码抽出来作为一个类库了 + +基于插件代码制作了一份 DEMO, 可以参考 [NeteaseCloudMusic-Audio-Recognize](https://github.com/akinazuki/NeteaseCloudMusic-Audio-Recognize) + +`rec.json` 内是封装成 JSON 的录音 ArrayBuffer + +运行后会在 Chrome Console 打印出音频指纹的 Base64 串 + +[本页面已更新](/netease-eapi-music-recognize-reverse-3/) + + + + \ No newline at end of file diff --git a/source/_posts/netease-eapi-music-recognize-reverse-3.md b/source/_posts/netease-eapi-music-recognize-reverse-3.md index 91a82c8..0e1e7fe 100644 --- a/source/_posts/netease-eapi-music-recognize-reverse-3.md +++ b/source/_posts/netease-eapi-music-recognize-reverse-3.md @@ -1,5 +1,24 @@ --- -title: netease-eapi-music-recognize-reverse-3 +title: 网易云音乐听歌识曲 API 逆向 (三) date: 2022-06-27 20:46:28 tags: --- + +闲来无事填一下坑 + +根据 [这个 issue 的讨论](https://github.com/akinazuki/NeteaseCloudMusic-Audio-Recognize/issues/1) + +现在已经将 [NeteaseCloudMusic-Audio-Recognize](https://github.com/akinazuki/NeteaseCloudMusic-Audio-Recognize) 这个项目移植到了 Node.js上 + + + + + +顺便吐槽一下 NPM 上的 `web-audio-api` 项目 +NPM 版的 `web-audio-api` 已经 7 年没更新了, 直接 `npm install web-audio-api` 安装的包完全不能用 +连 `AudioContext.decodeAudioData()` 方法都没有, 一开始还以为是自己的调用方式有问题 +但是它的示例代码里也是这样写的 +结果一翻 GitHub 上的代码, 发现 GitHub 上安装的版本和 NPM 上的版本完全不一样 +GitHub 上的版本是一直在更新的, 估计有在 Node.js 里解析 `AudioBuffer` 的不少人都会踩这个坑 + +~~本项目由 Copilot 强力驱动~~ \ No newline at end of file diff --git a/source/about/index.md b/source/about/index.md new file mode 100644 index 0000000..36dac0b --- /dev/null +++ b/source/about/index.md @@ -0,0 +1,24 @@ +--- +title: 关于 +date: 2022-08-16 +tags: +--- + +Bug Producer / ~~猫娘~~ +{% raw %} +
+{% endraw %} + +### 公钥 +```bash +curl https://server.pub >> ~/.ssh/authorized_keys +``` + +OR + +``` +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCmStKmnnCJIIp2e5IQ43GuBHQrPwjLW7c6fXblGVVD5T/HO16zLYzrkKs5sqw1vd8u4UkKg6B6LyOSJOvjb+Qgit45Vgse9zfTJd+w/8lv0M0qhX+6NQidZxhyXYpS2sd/pANC5R1fRHKK57A6tpfCAnilFLClZDv8zhJPbQyOpoEsKn8obHvvlYkTHAohERPoEbeFtCpnP64ZG543OWQK1fmCyWu+gsc9UuY2kJLTU3Z9H0EdG/rQFTCgBMRNAf/mIvIF4sF6ine3h8xVe5jLHXqidFpxVX8K0KJqQQrAFKoVlH04YZyx+uCnrHSl3QHMy9FLWnAvpivJLZqgMaU5 nazuki@AkiNazuki-MBP +``` \ No newline at end of file diff --git a/source/labs/index.md b/source/labs/index.md new file mode 100644 index 0000000..0e55612 --- /dev/null +++ b/source/labs/index.md @@ -0,0 +1,8 @@ +--- +title: 实验室 +date: 2022-08-16 +tags: +--- + + +正在施工中... \ No newline at end of file diff --git a/source/links/index.md b/source/links/index.md new file mode 100644 index 0000000..f060c7c --- /dev/null +++ b/source/links/index.md @@ -0,0 +1,23 @@ +--- +title: Links +date: 2022-08-16 +tags: +--- + +[Ayaka Neko](https://neko.ayaka.moe/) +[Makito’s Notebook](https://mak1t0.cc/) +[贫困的蚊子](https://qwq.moe/) +[Nekoyue’s Blog](https://yue.moe/) +[Yukari’s Blog](https://0w0.live/) +[谦谦的博客](https://xqq.im/) +[Sukka’s Blog](https://skk.moe/) +[DIYgod](https://diygod.me/) +[小新喵~](https://xin.moe/) +[KK 的博客](https://ikk.me/) +[小竹’s blog](https://blog.justforlxz.com/) +[403 Forbidden](https://233.imjs.work/) +[Sayaka’s Blog](https://baka.studio/) +[QiroNT/blog](https://ntz.im/) +[芝士部落格](https://chee5e.space/) +[LinEvil’s Blog](https://linevil.net/) +[Canarypwn’s Blog](https://aaaab3n.moe/) \ No newline at end of file From 4c8fa8fe450c07037fbc8a6d3cf66a029c32a2e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=8B=20=E5=A5=88=E6=9C=88?= <43605695+akinazuki@users.noreply.github.com> Date: Fri, 26 Aug 2022 03:38:16 +0800 Subject: [PATCH 2/3] add rss generator --- _config.yml | 15 +++++++++++++++ package.json | 1 + pnpm-lock.yaml | 12 ++++++++++++ 3 files changed, 28 insertions(+) diff --git a/_config.yml b/_config.yml index 6d40c2e..f253f51 100644 --- a/_config.yml +++ b/_config.yml @@ -103,3 +103,18 @@ theme: melody ## Docs: https://hexo.io/docs/one-command-deployment deploy: type: '' + + +feed: + enable: true + type: atom + path: atom.xml + limit: 20 + hub: + content: + content_limit: 140 + content_limit_delim: ' ' + order_by: -date + icon: icon.png + autodiscovery: true + template: \ No newline at end of file diff --git a/package.json b/package.json index 7e54ec0..6681a21 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "hexo": "^6.2.0", "hexo-generator-archive": "^1.0.0", "hexo-generator-category": "^1.0.0", + "hexo-generator-feed": "^3.0.0", "hexo-generator-index": "^2.0.0", "hexo-generator-tag": "^1.0.0", "hexo-renderer-ejs": "^2.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9e4c442..a0b7f82 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,7 @@ specifiers: hexo: ^6.2.0 hexo-generator-archive: ^1.0.0 hexo-generator-category: ^1.0.0 + hexo-generator-feed: ^3.0.0 hexo-generator-index: ^2.0.0 hexo-generator-tag: ^1.0.0 hexo-renderer-ejs: ^2.0.0 @@ -18,6 +19,7 @@ dependencies: hexo: 6.2.0 hexo-generator-archive: 1.0.0 hexo-generator-category: 1.0.0 + hexo-generator-feed: 3.0.0 hexo-generator-index: 2.0.0 hexo-generator-tag: 1.0.0 hexo-renderer-ejs: 2.0.0 @@ -716,6 +718,16 @@ packages: hexo-pagination: 1.0.0 dev: false + /hexo-generator-feed/3.0.0: + resolution: {integrity: sha512-Jo35VSRSNeMitS2JmjCq3OHAXXYU4+JIODujHtubdG/NRj2++b3Tgyz9pwTmROx6Yxr2php/hC8og5AGZHh8UQ==} + engines: {node: '>=10.13.0'} + dependencies: + hexo-util: 2.7.0 + nunjucks: 3.2.3 + transitivePeerDependencies: + - chokidar + dev: false + /hexo-generator-index/2.0.0: resolution: {integrity: sha512-q/29Vj9BZs0dwBcF+s9IT8ymS4aYZsDwBEYDnh96C8tsX+KPY5v6TzCdttz58BchifaJpP/l9mi6u9rZuYqA0g==} engines: {node: '>=10.13.0'} From bad20a20bf91945ffd4f1e4267b91a71e69f8298 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Oct 2022 14:22:56 +0000 Subject: [PATCH 3/3] Bump hexo-generator-category from 1.0.0 to 2.0.0 Bumps [hexo-generator-category](https://github.com/hexojs/hexo-generator-category) from 1.0.0 to 2.0.0. - [Release notes](https://github.com/hexojs/hexo-generator-category/releases) - [Commits](https://github.com/hexojs/hexo-generator-category/compare/v1.0.0...v2.0.0) --- updated-dependencies: - dependency-name: hexo-generator-category dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot]