如何防止Unity3D代码被反编译?
加密原理(无需Unity源码):
1.
IDA Pro打开libmono.so,
修改mono_image_open_from_data_with_name为
mono_image_open_from_data_with_name_0,
2.
替换实现mono_image_open_from_data_with_name,
extern
mono_image_open_from_data_with_name_0(...);
mono_image_open_from_data_with_name(...)
{
MonoImage
*img = mono_image_open_from_data_with_name_0(...);
//发现数据文件头不是DLL前缀则解密
img->raw_data, 相应修改img->raw_data_len
return img;
}
3.
重新打包libmono.so; 替换Unity3D中的android下的版本.
4.
另外写个加密的工具,植入构建环境(MonoDeveloper或VS,添加一个打包后Build Phase来加密DLL);
(IOS下禁用JIT固采用AOT编译,DLL中没有逻辑代码,所以无需操心);
从AndroidManifest.xml中可以看出,腾讯的改造应该是修改并替换了入口的classes.dex,把以前的入口
UnityPlayerProxyActivity替换为com.tencent.tauth.AuthActivity. 然后去加载了自定义的几个so:
libNativeRQD.so. 周全考虑,为了防止第三方委托libmono去做解密而做了防护措施. 具体实现我还没做深入分析,
应该也是老套路.
libmono.so中的mono_image_open_from_data_with_name也被替换成了mono_image_open_from_data_with_name_0.
解密(android):
方法一:
ROOT android系统(最好是一部手机,别搞模拟器,慢死), 挂载LD_PRELOAD的API hook来实现.
方法二:
内存特征码提取,简单高效无敌; 机器能读,你就能读;
对于iOS平台AOT后Strip掉IL可能有用,但其他平台基本没什么办法。还有一个思路是加壳,但这个至少在移动端上我没试验过,而且基本上也是道高一尺魔高一丈的事情。
还有一个是把一些关键代码写成Native插件,但这样做我觉得完全就没有使用Unity的优势了,所以也不是很推荐。
如果是涉及网络的游戏,另一个相对有效的解决方案是把逻辑放在服务端,基本上不给客户端Gameplay逻辑层的信任,客户端只负责只发送具体操作。对于非在线游戏我确实没看到什么有效的解法。
个人觉得么,也不要太费劲折腾了,人家要搞你总是有办法的。就算你不用Unity,真的高手是Native Binary一样破给你看的。