[转载] 崩坏三中两种加密文件的分析及解密

转载自:https://www.52pojie.cn/thread-769195-1-1.html

小白一个,本文并没有什么技术含量。
      以前在研究替换unity游戏(崩坏三)的资源文件的时候,发现它所有的shader都被放到了两个加密过的文件里,一个是assetbundle文件item.unity3d,另一个是asset文件sharedassets0.assets。虽然这并不会影响mod的制作,但是还是很想搞明白它是怎么加密解密的。然后就开始了研究。然而并没有找到解密函数,倒是找到了其它文件的解密方法。后来直接分析文件得到了解密方法。      
    用到的工具:Il2CppDumper,IDA      
    首先,用IDA分析libil2cpp.so,然后用Il2CppDumper得到大多数函数的名称和字符串。我觉得解密后的数据应该不会保存为文件,应该是从内存中加载,在unity中是用Asssetbundle.loadfrommemory()这个函数加载的。
    搜索一下引用,发现两处引用:
01.loadfrommemory_ref.bmp
转到第一个发现是读取的下载下来的数据:
02.2find01.bmp
02.1find01.bmp
然后看第二个:
02.2aes解密.bmp
函数名已经很明显了,看一下内容:
03.aes解密.bmp
看到先用RSA解密出了一个AES密钥,然后用AES解密数据。不过没有密钥,先到Il2CppDumper生成的dump.cs看一下:
03.cs文件.bmp
再看一下AssetbundleUtility$$.cctor.发现RSA密钥是固定的一个字符串,转到字符串位置得到一个xml格式的RSA密钥:
03.2存入rsakey.bmp
可以看到 *(_DWORD) (*(_DWORD)(dward_4385ac +80) + 4)是RSA的密钥,那么*(_DWORD) (*(_DWORD)(dward_4385ac + 80) + 8)应该就是用RSA加密过的AES密钥了。IDA连接手机调试得到加密的128字节数据:
03.加密的aeskeyhex.bmp
之后解密出58字节的数据,根据反编译的代码,数据前32字节是AES的key,之后的16字节是IV,剩下的不知道有什么用。
#更新:剩下的8字节是hmac-sha1的密钥,用于计算文件名中那一串哈希值。
然后发现并不能解密item.unity3d和sharedassets0.assets,两个文件的长度都不是AES算法产生的,最后发现这是用来解密数据文件夹中excel_output_65……868.unity3d和setting_DD……AC9.unity3d这两个文件的,里面是游戏中的各种属性的数据和关卡设计的lua脚本……..
然后,还是找不到item.unity3d和sharedassets0.assets的解密方法….只好回去分析文件本身。
先对比一下不同版本的item.unity3d:文件开头部分数据是相同的,推测可能是异或加密。
4.对比.png
同一unity版本Assetbundle的文件头部大概有30个字节是完全相同的,于是对照未加密的assetbundle手动算出了前32个字节的异或值。然后用sharedassets0.assets来测试,发现可以解密,说明两个文件加密方式和密钥应该是一样的,而且一直没有变过。
04.jiemi.bmp
解密了前32字节的assets文件:然后,翻到sharedassets0.assets的后面时发现每32字节就会重复出现一段长32字节的类似的数据:然后尝试用算出来的32字节的密钥去循环解密整个文件:结果发现前3M数据中每2kb开头有32字节被解密:
05.1111.bmp


5.333333333.bmp
而从0x00300000位置开始之后的数据全都被解密了:
05.222222222.bmp
所以前3M数据是2kb的密钥,之后的是32字节的密钥;然后就要想办法解出这2kb的密钥。
在之前已经知道sharedassets0.assets里有很多shader,shader中一部分数据很有规律:
05.shaaa.bmp
不难发现,在绝大多数”<noninit>”后面至少有5字节的0,所以先用之前的32字节密钥解出对应位置的数据,然后在解出的数据中搜索“<noninit>”,如果之后5个字节中有未解密的数据就直接作为密钥,再解出对应位置的数据,然后继续搜索”<noninit>”,一直循环下去,直到获得完整的密钥。最后得到解密的数据。
解密后的item.unity3d用AssetBundleExtractor打开:
TIM截图20180711181106.bmp
但是,最终也没能找到解密的程序在哪。不知道是我眼瞎没看到还是程序就不在libil2cpp.so里。希望各位大佬指教。
再说一下它这两种加密方式,第一种加密的数据是非常重要的属性数值等数据,用到了RSA来解密AES的密钥,却把RSA的密钥写死在程序里….然后直接IDA调试,到对应的位置直接就可以得到RSA加密过的AES的密钥(之后通过抓包找到了包含加密的密钥的.unity3d文件)…然后第二种异或加密的文件里面主要是shader,不过目前还不能直接看到shader代码(现在也可以看到了..而且也没有加密了),也许是为了防止别的游戏直接拿去用吧,不过用这种算法加密规律的文件。。。
密钥和自己写的加解密程序:
编程不咋地,凑合用吧。
 加密解密程序.zip (9.86 KB, 下载次数: 175)
4.对比.png
4.最后.bmp
4.对比.gif
03.2rsakey.bmp