闲来无事研究一下酷狗缓存文件kgtemp的加密方式
此贴为本人原创,转载请注明出处
序
前几天更新了被打入冷宫很久的酷狗,等进入之后就感觉菊花一紧————试 听 居 然 都 要 开 通 音 乐 包(高品和无损)才行了,WTF!
这意味着以前缓存的都听不了了,本着好马不吃回头草的原则,不打算去降级了,下载PJ版的又担心被植入恶意代码,心好累╮(╯▽╰)╭
作为一个程序猿,岂能被你这小阴招就击败,定要给你点颜色看看!
探索
首先对比了一下缓存文件和下载好的mp3文件,发现缓存文件多了1024个字节,而且对比了几个缓存文件,前1024个字节都一样,看来使了个障眼法,去掉这1024个字节应该就是原版的音频数据了。
然后下图是加密前后的对比:


会发现加密前的一堆0x55 加密后变成 0xA9 0xE9 0xDA 0x52循环了,说明是用了4字节的循环加密,然后切换成2进制研究
加密前 0x55 0x55 0x55 0x55 01010101 01010101 01010101 01010101
加密后 0xA9 0xE9 0xDA 0x52 10101001 11101001 11011010 01010010
对称逐字节加密的运算也就循环移位或者异或固定的数或者取反,但上面的几组数循环移位和取反都不太像,就先假设是异或固定的数A B C D,接下来做填空题:
0x55 0x55 0x55 0x55 01010101 01010101 01010101 01010101
A B C D 11111100 10111100 10001111 00000111
0xA9 0xE9 0xDA 0x52 10101001 11101001 11011010 01010010
得出:A B C D分别为0xFC 0xBC 0x8F 0x07 ,然后取开头的数据验证:
加密前 0x49 0x44 0x33 0x03 01001001 01000100 00110011 00000011
xor 0x3C 0xAC 0xEF 0x67 00111100 10101100 11101111 01100111
加密后 0x75 0xE8 0xDC 0x64 01110101 11101000 11011100 01100100
这次的A B C D分别为0x3C 0xAC 0xEF 0x67
纳尼?不是固定的?WTF!
两组A B C D低4位的数字都是 C C F 7
看来最终结果确实是xor计算来的,只是高4位的数值要复杂一些。
根据0 xor X =X的性质,我找了一组全0的加密前后的对比,
加密前 0x00 0x00 0x00 0x00 00000000 00000000 00000000 00000000
加密后 0xAC 0xEC 0xDF 0x57 10101100 11101100 11011111 01010111
那A B C D高4位就对应 0xA 0xE 0xD 0x5
再用开头的数据验证:
加密前 0x49 0x44 0x33 0x03 01001001 01000100 00110011 00000011
xor 0xAC 0xEC 0xDF 0x57 10101100 11101100 11011111 01010111
加密后 0xE5 0xA8 0xEC 0x54 11100101 10101000 11101100 01010100
还是不对,而且发现一点:只要加密前的数的高4位=低4位,加密后的高4位都固定为0xA 0xE 0xD 0x5
这不就是xor 中的4个数的高4位吗,由(0 xor X=X)和(X xor X=0)可知,高4位的算法应该是这样的:
分别取输入数的高4位和低4位H,L, 然后取xor的高4位I 结果Y= H xor L xor I
带入前面的3组数据验算,都对了^_^
撸码
既然加密算法已经猜出来了,就撸码验证一下,看解密后的文件的MD5与缓存文件名是否相等:
class Program
{
static void Main(string[] args)
{ byte[] key={0xAC,0xEC,0xDF,0x57};
using (var input = new FileStream(@"E:\KuGou\Temp\236909b6016c6e98365e5225f488dd7a.kgtemp", FileMode.Open, FileAccess.Read))
{
var output = File.OpenWrite(@"d:\test.mp3");//输出文件
input.Seek(, SeekOrigin.Begin);//跳过1024字节的包头
byte[] buffer = new byte[key.Length];
int length;
while((length=input.Read(buffer,,buffer.Length))>)
{
for(int i=;i<length;i++)
{
var k = key[i];
var kh = k >> ;
var kl = k & 0xf;
var b = buffer[i];
var low = b & 0xf ^ kl;//解密后的低4位
var high = (b >> ) ^ kh ^ low & 0xf;//解密后的高4位
buffer[i] = (byte)(high << | low);
}
output.Write(buffer, , length);
}
output.Close();
}
Console.WriteLine("按任意键退出...");
Console.ReadKey();
}
}
结果:输出文件的MD5与缓存文件名相同,大功告成
总结
固定要异或的key={0xAC,0xEC,0xDF,0x57}
加密方式如下:
1.设输入的数为x,输出结果为y,循环变量为i;
2.分别取x的高4位和低4位h,l; h=x >> 4 ; l=x & 0xf;
3.分别取key[i]的高4位和低4位kh,kl;kh=key[i] >> 4;kl=key[i] & 0xf;
4.y=h ^ l ^ kh;
5.y=y<< 4 | (l ^ kl);
解密方式如下:
1.设输入的数为x,输出结果为y,循环变量为i;
2.分别取x的高4位和低4位h,l;h=x >> 4 ; l=x & 0xf;
3.分别取key[i]的高4位和低4位kh,kl;kh=key[i] >> 4;kl=key[i] & 0xf;
4.y=l ^ kl;
5.y=(h ^ kh ^ y)<<4 | y;
闲来无事研究一下酷狗缓存文件kgtemp的加密方式的更多相关文章
- 酷狗缓存文件kgtemp的加密方式
[转自:http://www.cnblogs.com/KMBlog/p/6877752.html] 首先对比了一下缓存文件和下载好的mp3文件,发现缓存文件多了1024个字节,而且对比了几个缓存文件, ...
- 开源小工具 酷狗、网易音乐缓存文件转mp3工具
发布一个开源小工具,支持将酷狗和网易云音乐的缓存文件转码为MP3文件. 以前写过kgtemp文件转mp3工具,正好当前又有网易云音乐缓存文件需求,因此就在原来小工具的基础上做了一点修改,增加了对网易云 ...
- 酷狗.kgtemp文件加密算法逆向
该帖转载于孤心浪子--http://www.cnblogs.com/KMBlog/p/6877752.html 酷狗音乐上的一些歌曲是不能免费下载的,然而用户仍然可以离线试听,这说明有缓存文件,并且极 ...
- 酷狗音乐盒缓存文件夹KuGouCache的设置方法
1.每次一打开酷狗总能在E盘里找到这个 KuGouCache 文件夹 ,是自动生成的MV缓存文件 .按照常规 ,可以修改这个文件的办法是 找到C盘里的:用户\administrator\AppDate ...
- Redrain仿酷狗音乐播放器开发完毕,发布测试程序
转载请说明原出处,谢谢~~ 从暑假到现在中秋刚过,我用duilib开发仿酷狗播放器大概经历了50天.做仿酷狗的意图只是看原酷狗的界面比较漂亮,想做个完整一些的工程来练习一下duilib.今天把写好的程 ...
- java爬取并下载酷狗TOP500歌曲
是这样的,之前买车送的垃圾记录仪不能用了,这两天狠心买了好点的记录仪,带导航.音乐.蓝牙.4G等功能,寻思,既然有这些功能就利用起来,用4G听歌有点奢侈,就准备去酷狗下点歌听,居然都是需要办会员才能下 ...
- 用vuejs写了一个酷狗的webApp
这几天在学习vueJS,学了半个月,觉得是不是该写点什么呢?于是 .脑子一抽,仿了一个酷狗的webapp. 项目截图: 由于是单页应用,切换路由时音乐不会停止,算是一个小亮点吧. 技术栈: vuejs ...
- 仿酷狗音乐播放器开发日志二十七 用ole为窗体增加文件拖动功能(附源码)
转载请说明原出处,谢谢~~ 中秋到了,出去玩了几天.今天把仿酷狗程序做了收尾,已经开发完成了,下一篇博客把完结的情况说一下.在这篇博客里说一下使用OLE为窗体增加文件拖拽的功能.使用播放器,我更喜欢直 ...
- 仿酷狗音乐播放器开发日志二十六 duilib在标题栏弹出菜单的方法
转载请说明原出处,谢谢~~ 上篇日志说明了怎么让自定义控件响应右键消息.之后我给主窗体的标题栏增加右键响应,观察原酷狗后可以发现,在整个标题栏都是可以响应右键并弹出菜单的.应该的效果如下: 本以为像上 ...
随机推荐
- python字典学习笔记
字典是一种可变容器模型,且可存储任意类型对象.键是不可变类型(且是唯一的),值可以是任意类型(不可变类型:整型,字符串,元组:可变类型:列表,字典).字典是无序的,没有顺序关系,访问字典中的键值是通过 ...
- hbase的HQuorumPeer和QuorumPeerMain
hbase是列式数据库,既可以单机也可以以集群的方式搭建,以集群的方式搭建一般建立在hdfs之上. 分布式的hbase如何启动? 首先启动hadoop,然后就来问题了:zookeeper和hbase的 ...
- [译]ASP.NET Core 2.0 布局页面
问题 如何在ASP.NET Core 2.0项目中共享可见元素.代码块和指令? 答案 新建一个空项目,首先添加GreetingService服务和UserViewModel模型: public int ...
- Servlet 学习笔记
Servlet 运行在服务器上的 java 类: Servlet 容器为 javaWeb 应用提供运行时环境,负责管理 servlet 和 jsp 生命周期,以及管理他们的共享数据. 现在我们知道了 ...
- SQL系统函数的使用(实验五)
SQL系统函数的使用(试验5) 函数在查询语句中的使用 查询员工的姓名和日工资(保留1位小数): 查询并显示部门号为01和02的所有员工的姓名首字及岗位: 查询并显示所有员工的姓名及工龄: 查询199 ...
- python进阶------进程线程(五)
Python中的IO模型 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别 ...
- label的作用是什么?是怎么用的?
label标签是用来定义表单控制间的关系,当用户选择该标签时,浏览器会自动将焦点转到和标签相关的表单控件上. 主要有以下两种用法用法: 一. <label for = "Name&qu ...
- MySQL GTIDs(global transaction identifiers)
1.如何定义和生成GTIDs 唯一性:在所有主从库都是唯一的,由二元组构成 每个事务和GTIDs之间都有1:1映射 GTID = source_id:transaction_id source_id标 ...
- [转]ORACLE SQL解析之硬解析和软解析
http://blog.chinaunix.net/uid-25909722-id-3363789.html 当客户端进程,将SQL语句通过监听器发送到Oracle时, 会触发一个Server pro ...
- 【scikit-learn 0.19 中文文档 】安装 scikit-learn | ApacheCN
中文文档: http://sklearn.apachecn.org/cn/0.19.0/tutorial/basic/tutorial.html 英文文档: http://sklearn.apache ...