1. 程式人生 > >閑來無事研究一下酷狗緩存文件kgtemp的加密方式

閑來無事研究一下酷狗緩存文件kgtemp的加密方式

eight mp3 img 異或 tel 輸出 cnblogs images 加密算法

此貼為本人原創,轉載請註明出處

前幾天更新了被打入冷宮很久的酷狗,等進入之後就感覺菊花一緊————試 聽 居 然 都 要 開 通 音 樂 包(高品和無損)才行了,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 A 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={0xC,0xC,0xF,0x7};
            byte[] xor = { 0xA, 0xE, 0xD, 0x5 };
            using (var input = new FileStream(@"E:\KuGou\Temp\236909b6016c6e98365e5225f488dd7a.kgtemp", FileMode.Open, FileAccess.Read))
            {
                var output = File.OpenWrite(@"d:\test.mp3");//輸出文件
                input.Seek(1024, SeekOrigin.Begin);//跳過1024字節的包頭
                byte[] buffer = new byte[key.Length];
                int length;
                while((length=input.Read(buffer,0,buffer.Length))>0)
                {
                    for(int i=0;i<length;i++)
                    {
                        var b = buffer[i];
                        var low = b & 0xf ^ key[i];//解密後的低4位
                        var high = (b >> 4) ^ xor[i] ^ low & 0xf;//解密後的高4位
                        buffer[i] = (byte)(high << 4 | low);
                    }
                    output.Write(buffer, 0, length);
                }
                output.Close();
            }
            Console.WriteLine("按任意鍵退出...");
            Console.ReadKey();
        }
    }

結果:輸出文件的MD5與緩存文件名相同,大功告成

閑來無事研究一下酷狗緩存文件kgtemp的加密方式