【手游】有杀气童话 美术资源加密分析

来源:互联网 发布:个人顶级域名 编辑:程序博客网 时间:2024/05/04 22:38

加密原理参考我之前写的 Unity3D 游戏加密解密那些事

0x00 在ida中先找到加密dll的地方

把libmono.so文件拖入IDA中,在函数窗口中搜索mono_image_open_from_data_with_name这个方法

对Dll加密的核心逻辑在mono_image_encrypt

0x01 经过上面的分析,我写了一个C#版的解密算法

//dll读取保存private void ReadDLLFile(FileInfo f){    if (f.Name.CompareTo("Assembly-CSharp.dll") == 0)    {        FileStream inStream = new FileStream(f.FullName, FileMode.Open, FileAccess.ReadWrite);        byte[] bytes = new byte[inStream.Length];        inStream.Read(bytes, 0, bytes.Length);        inStream.Close();        byte[] dllBytes = new byte[bytes.Length - 12];        Array.Copy(bytes, 12, dllBytes, 0, bytes.Length - 12);        dllBytes = mono_image_encrypt(dllBytes);        string outPath = Path.Combine(f.DirectoryName, Path.GetFileNameWithoutExtension(f.FullName) + "_Fix.dll");        FileStream outStream = new FileStream(outPath, FileMode.OpenOrCreate, FileAccess.ReadWrite);        outStream.Seek(0, SeekOrigin.Begin);        outStream.Write(dllBytes, 0, dllBytes.Length);        outStream.Close();    }}//dll解密算法private byte[] mono_image_encrypt(byte[] bytes){    byte[] encryptKey = new byte[16] { 0xE4, 0x1F, 0x7B, 0x6F, 0xE5, 0x2A, 0xE7, 0x1F, 0xE6, 0x04, 0x6F, 0x5D, 0x28, 0x00, 0x06, 0x02 };    for (int i = 0; i < 5049; i++)    {        int index = i % 16;        bytes[i] = (byte)(bytes[i] ^ encryptKey[index]);    }    return bytes;}
左边是加密的dll,右边是解密后的dll

0x02 在Assembly-CSharp.dll中 定位加密AssetBundle的地方




经过上面的分析 先用AES对AssetBundle进行解密,然后在用GZip进行解压缩,就能得到最原始的AssetBundle

0x03 AssetBundle解密算法

//AssetBundle读取保存private void ReadAssetBundle(FileInfo f){    FileStream inStream = new FileStream(f.FullName, FileMode.Open, FileAccess.ReadWrite);    byte[] bytes = new byte[inStream.Length];    inStream.Read(bytes, 0, bytes.Length);    inStream.Close();    byte[] buff = BZip2DeCompression(AESDecrypt(bytes));    string outPath = Path.Combine(f.DirectoryName, Path.GetFileNameWithoutExtension(f.FullName) + ".AssetBundle");    FileStream outStream = new FileStream(outPath, FileMode.OpenOrCreate, FileAccess.ReadWrite);    outStream.Seek(0, SeekOrigin.Begin);    outStream.Write(buff, 0, buff.Length);    outStream.Close();}//AssetBundle解密算法private byte[] AESDecrypt(byte[] cipherText){    string key = "magicgame@)!$@PM";    byte[] key1 = new byte[] { 209, 189, 68, 63, 232, 239, 208, 62, 110, 79, 252, 62, 31, 130, 114, 63 };    SymmetricAlgorithm symmetricAlgorithm = Rijndael.Create();    symmetricAlgorithm.Key = Encoding.UTF8.GetBytes(key);    symmetricAlgorithm.IV = key1;    byte[] result = null;    using (MemoryStream memoryStream = new MemoryStream())    {        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, symmetricAlgorithm.CreateDecryptor(), CryptoStreamMode.Write))        {            cryptoStream.Write(cipherText, 0, cipherText.Length);            cryptoStream.FlushFinalBlock();            result = memoryStream.ToArray();        }    }    return result;}//AssetBundle解压缩public byte[] BZip2DeCompression(byte[] bytes){    byte[] result;    using (MemoryStream memoryStream = new MemoryStream(bytes))    {        using (GZipInputStream gZipInputStream = new GZipInputStream(memoryStream))        {            using (MemoryStream memoryStream2 = new MemoryStream())            {                byte[] array = new byte[4096];                int num;                while ((num = gZipInputStream.Read(array, 0, array.Length)) != 0)                {                    memoryStream2.Write(array, 0, num);                }                result = memoryStream2.ToArray();            }        }    }    return result;}
至此资源的解密工作就算完成了,关于Unity资源的提取参考我之前写的文章 Unity3D 游戏资源提取工具
资源提取源码
链接:http://pan.baidu.com/s/1gffsZtD 密码:j552

0 0