如何從緩存白嫖網易雲音樂

一切的起因都得從一個神祕的夜開始...

那天小豬在剪視頻的時候,突然想用幾首曲子作爲 BGM,於是興高采烈的想到了鍾愛的網易雲音樂。不過在小豬的印象中,很多年前,是可以通過直接修改緩存文件的後綴名來白嫖音樂下載的。於是一個邪惡的計劃就此展開...

後綴名?

首先我們來到網易雲音樂在本地的緩存目錄,當然肯定是一堆看起來奇奇怪怪的文件啦。

netease-music-decoder-1.jpg

按照體積來看,這些 .uc 的文件應該就是 mp3 了。於是按照老方法,直接用播放器打開試試,結果發現無法正確解碼。可達鴨眉頭一皺,發現事情並不簡單。看起來,這些緩存文件應該是經過了處理的。不過既然作爲本地緩存使用,那麼這個處理一定是可逆的,並且通常是不復雜的。我們就嘗試來找找線索吧。

選個姿勢

首先就是,通常來說各種不同的文件類型都會有自己特定的格式。上網搜尋一番之後發現,mp3 文件開頭會都會有一個以 ID3 開始的標籤頭。於是抱着好奇心,我們來查看一下這個 .uc 緩存文件看看:

netease-music-decoder-2.jpg

可以發現並不符合之前查到的格式。因吹斯汀~

結合我們前面說的,這個處理一定可逆,並且可能不會很複雜。小豬這裏大膽猜測可能是對於每一個 byte 都進行了某種運算。接下來我們對比一下正式下載下來的 mp3 和這個緩存文件的內容:

netease-music-decoder-3.jpg

圖中左側爲緩存文件的內容,右側爲對應的 mp3 文件的內容。可以發現右側數據確實是以 ID3 開頭的,驗證了之前搜索的內容。這裏其實我們就得到了一個由原始數據到處理後數據的對應表。可以作爲後續解碼的線索。

不過其實更讓小豬注意的是,我們在 mp3 文件中會發現存在着一段 00 的內容,可能是作爲頭部擴展標籤的預留位。不過在緩存文件中,這部分內容全部變成了 A3。由於 00 這個值的特殊性(全都是 0 鴨),小豬下意識覺得這裏很可能就是一個突破口。

首先,根據這段數據的位置關係,我們可以猜測的是處理後的緩存文件中每個 byte 都是原地修改數據,並不存在數據整體的前後移動。接下來,如何從 00 變爲 A3 呢?這裏可能有幾種很常見的運算,例如通過加法、或運算或者異或運算。假設是通過加法,那麼在編碼和解碼的時候還得處理數據溢出然後循環的問題;假設是通過或運算,那麼解碼的時候就無法直接還原了,畢竟 0 | 1 與 1 | 1 都是 1;假設是通過異或,那麼還原只需要再做一次異或運算即可。看起來似乎得到一點線索了,我們再驗證一下吧。

基於上面的線索,我們回頭看看標籤頭部的值,緩存文件中是 EA、E7、90,mp3 文件中是 49、44、33。下面就是見證奇蹟的時刻啦:

(0xea ^ 0xa3) === 0x49
(0xe7 ^ 0xa3) === 0x44
(0x90 ^ 0xa3) === 0x33

感興趣的同學可以自行嘗試算一下上面 3 個判斷,會發現它們全都是 true。亦可賽艇!

到此似乎線索已經明朗起來了,那麼我們嘗試把整個文件都轉換一下吧。

NodeJS 模塊

在 NodeJS 中我們可以輕鬆的把文件的內容讀進內存,然後對每一個 byte 進行上述運算處理,再將結果輸出。常見的方式有兩種,可以基於 fs.open 去創建文件句柄,或者基於 fs.createReadStream 來創建讀取流。對於大文件來說,後者會比較有優勢,不過對於常見的 mp3 歌曲,小夥伴們可以看自己的喜好咯。

這裏小豬實現了一個 repo 包含了上述功能,repo 地址在此。當然除了直接解碼 buffer 或者解碼文件之外,還支持通過緩存文件名自動獲取這首歌的歌名和歌手來作爲解碼後輸出的文件名。例如 repo 中的測試文件的結果如下:

netease-music-decoder-4.jpg

repo 中的代碼並不複雜,暴露的方法也很簡單,感興趣的小夥伴可以自行查看。歡迎 STAR,歡迎 PR~ >.<

在線版本

瞭解小豬的小夥伴一定猜到啦,除了 NodeJS 模塊,小豬也提供了在線版本供使用。具體地址在此

該在線版本可以選擇本地緩存文件,然後進行在線解碼,處理完之後自動觸發下載。效果如下圖所示:

netease-music-decoder-5.jpg

不過在線版本目前不支持自動獲取歌名和歌手名。其實雲服務的 serverless 那邊已經做好接口了,但是小豬測試的時候發現外網流量要計費,100 首歌就幾百兆啦。小豬最近經濟又比較拮据,所以決定先不支持啦。如果需要的小夥伴多的話,可以等等小豬後續的桌面軟件版本。

後記

最終的代碼其實非常簡單,不過中間尋找線索的過程還是挺有意思的。所以寫出來和小夥伴們分享一下。但是有很多環境還沒有測試過,例如 macOS、linux、android、iOS 等平臺的緩存默認路徑啦,或者不同平臺的瀏覽器的兼容性啦。如果發現有問題,歡迎去 repo 中提 issue 即可。

加之最近發現 electron 已經發布了 9.0.0 了,而小豬以前用它來做正式項目的時候還是很多年前的版本,於是想體驗一下現在究竟有哪些改變。所以就打算順便做一個桌面軟件版本。

當然本文也是有時效性的,如果網易雲音樂改了緩存文件的編碼方式,那麼可能就失效啦。不過到時候小豬應該也會更新 repo 的代碼的。


整理了學習資料以及學習視頻,送給小夥伴們。公號內回覆【學習資料】自行領取。和一些小夥伴們建了一個技術交流羣,一起探討技術、分享技術資料,旨在共同學習進步,如果感興趣就掃碼加入我們吧!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章