offset加密
0.简单建个场景:
Scene:1个GameObject,1个UI
Assets:1个图片,1个Prefab,1个材质
1.普通打包【未加密】
- AssetStudio验证
-
游戏加载验证
2.AB包前加入乱码
2.1 获取原AB包的HashCode
2.2 提取HashCode作为参数计算偏移量offset:
for (int i = 0,iMax = hashchar.Length; i < 3; ++i)
{
offset += (int)hashchar[i];
}
2.3 从原数据中选取offset长度的数据作为假数据头RandomHead(这样不同的子包,每次加密,他们前offset位的数据都是随机的)
private static byte[] GetRandomHead(byte[] sourceData,int headLength)
{
byte[] head = new byte[headLength];
int startIdx = 0;
int randomParam = UnityEngine.Random.Range(0, sourceData.Length - headLength);
for (int i = randomParam, iMax = randomParam + headLength; i < iMax; ++i,++startIdx)
{
head[startIdx] = sourceData[i];
}
return head;
}
2.4 把 RandomHead 写到原数据前,实现简单的offset加密
private static void SetOffset(ref byte[] buffer,byte[] head,byte[] sourceData)
{
for (int i = 0,iMax = sourceData.Length + head.Length; i < iMax; ++i)
{
if (i<head.Length)
{
buffer[i] = head[i];
}
else
{
buffer[i] = sourceData[i - head.Length];
}
}
}
-
AssetStudio验证
[黑Saber姐姐不见了]
-
游戏加载验证
private Sprite LoadImg() { Sprite icon = null; string outputPath = Application.dataPath + "/BuildAssetBundle/Window/"; AssetBundle.UnloadAllAssetBundles(true); AssetBundle ab = AssetBundle.LoadFromFile(outputPath + bundleName); icon = ab.LoadAsset<Sprite>(spriteName); return icon; }
[黑Saber姐姐不见了] +1
3.解密
根据hash算出每个子包的offset,然后略过他们
private static void DelateOffset(ref byte[] buffer,int offset,byte[] sourceData)
{
for (int i = 0,iMax = sourceData.Length; i < iMax; ++i)
{
if (i < offset)
{
continue;
}
buffer[i - offset] = sourceData[i];
}
}
- AssetStudio验证
-
游戏加载验证
private Sprite LoadImg_decryption() { Sprite icon = null; string outputPath = Application.dataPath + "/BuildAssetBundle/Window/"; AssetBundle.UnloadAllAssetBundles(true); AssetBundle ab = AssetBundle.LoadFromFile(outputPath + bundleName, 0, (ulong)GetOffset()); icon = ab.LoadAsset<Sprite>(spriteName); return icon; }