如何从缓存中免费嫖网易云音乐本文仅供学习交流!一切从一个神秘的夜晚开始……那天小猪在剪辑视频的时候,突然想用几首歌做BGM,于是开心的想到了自己喜欢的网易云音乐。不过在小猪的印象中,很多年前,直接修改缓存文件的后缀名就可以免费下载音乐了。于是展开了一个邪恶的计划……后缀?首先我们来到网易云音乐的本地缓存目录下,当然肯定有一堆看起来很奇怪的文件。根据大小,这些.uc文件应该是mp3。于是按照老方法,尝试直接用播放器打开,发现无法正确解码。幸田矢皱了皱眉,意识到事情的不简单。看来应该处理这些缓存文件。但是,由于它是作为本地缓存使用的,所以这个处理必须是可逆的,而且通常并不复杂。让我们试着寻找线索。挑个姿势首先,一般来说,各种文件类型都会有自己特定的格式。上网查找后发现在mp3文件的开头会有一个ID3开头的tagheader。于是带着好奇,我们来看看这个.uc缓存文件:我们可以发现它并不符合之前找到的格式。YinBingsting~结合我们前面说的,这个过程肯定是可逆的,可能不是很复杂。小猪这里的大胆猜测可能是对每个字节都进行了某种计算。接下来我们对比一下官方下载的mp3和这个缓存文件的内容:图中左边是缓存文件的内容,右边是对应的mp3文件的内容。可以发现右边的数据确实以ID3开头,验证了之前搜索的内容。这里我们实际上得到了一个原始数据到处理后数据的对应表。可以作为后续解码的线索。但其实小猪比较注意的是,我们会在mp3文件中发现一段00,这可能是headerextensiontag的保留位。但是在缓存文件中,这部分内容全部变成了A3。由于00值(都是0鸭)的特殊性,小猪下意识觉得这可能是个突破口。首先,根据这块数据的位置关系,我们可以猜测,处理后的缓存文件中的每个字节都是在原地修改数据,并没有数据整体的前后移动。接下来,如何从00变成A3呢?这里可能有几个很常见的操作,比如加法,或,或异或。如果是加法,那么在编解码的时候就要处理数据溢出然后循环的问题;如果是通过or操作,那么解码的时候不能直接还原,毕竟0|1和1|1都是1;假设是通过异或,那么恢复只需要再做一次异或运算即可。看来我们是掌握了一点端倪,我们再验证一下。根据以上线索,我们回过头来看看标签头中的值。缓存文件为EA、E7、90,mp3文件为49、44、33。下面是见证奇迹的时刻:(0xea^0xa3)===0x49(0xe7^0xa3)===0x44(0x90^0xa3)===0x33有兴趣的同学可以自己尝试计算一下上面的3个判断,会发现都为真。也可以划船!至此,似乎线索已经明朗了,那我们来试试转换整个文件吧。NodeJS模块在NodeJS中,我们可以很方便的将文件内容读取到内存中,然后对每个字节进行上述操作,然后输出结果。有两种常见的方式,可以基于fs.open创建文件句柄,或者基于fs.createReadStream创建读取流。对于大文件,后者会更有优势,但是对于常见的mp3歌曲,朋友们可以看自己的喜好了。这里Piggy实现了一个包含上述功能的repo,repo的地址在这里。当然,除了直接解码缓冲区或解码文件外,还支持通过缓存的文件名自动获取歌曲的歌名和歌手作为解码后的输出文件名。比如repo中的测试文件结果如下:repo中的代码并不复杂,暴露的方法也很简单。感兴趣的小伙伴可以自行查看。欢迎STAR,欢迎PR~>.<网络版了解小猪的朋友一定猜到了。除了NodeJS模块,小猪还提供了在线版本供使用。具体地址在这里。在这个在线版本中,你可以选择一个本地缓存文件,然后进行在线解码,处理完成后自动触发下载。效果如下图所示:但是网络版目前不支持自动获取歌名和歌手名。其实云服务的Serverless端已经完成了接口,但是小猪测试的时候发现外网流量需要计费,100首歌曲就是几百兆。小猪最近经济拮据,暂时不支持了。需要更多的朋友可以等待小猪后续的桌面软件版本。更新:网络版已经支持文件拖拽和批量拖拽,会自动忽略所有非.uc结尾的文件。后记最终的代码其实很简单,但是中间找线索的过程还是挺有意思的。所以写出来和你的朋友分享。但是还有很多环境没有经过测试,比如macOS、linux、android、iOS等平台的默认缓存路径,或者不同平台浏览器的兼容性。如果您发现任何问题,请在回购中提出问题。另外,最近发现electron已经发布了9.0.0版本,而小猪在正式项目中使用它的时候,还是很多年前的版本,所以想体验一下现在有什么变化。所以打算顺便做一个桌面软件版。当然,这篇文章也是时效性的。如果网易云音乐更改了缓存文件的编码方式,可能会失效。但Piggy届时也应该更新repo代码。本文仅供学习交流!相关链接在线使用地址netease-music-cache-decoderrepo我的segmentfault专栏我的知乎专栏
