您的位置:首页 > 其它

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

2015-12-03 09:33 246 查看
加密原理参考我之前写的 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
游戏资源提取工具
注:本文仅供分析交流加解密算法,不提供解密工具,资源切勿商用!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: