上一篇文章一次U3D DLL加密的记录(一)已经介绍了Assembly-CSharp.dll的加密和打包方法,但每次都得导出安卓工程,接着替换资源,再导出apk,这样以来是非常繁琐的。
这篇文章主要针对windows下对u3d游戏的加密一键打包的介绍
主要步骤:
①:编译加密后的libmono.so
②:在自定义方法中对Assembly-CSharp.dll进行加密
③:破解UnityEditor.Android.Extensions.dll,注入自定义方法
④:一键打包
首先参考一下我的《一次编译libmono.so的记录》,把我们新生成解密的libmono.so替换掉u3d原来旧的
开发环境:
vs2012,.net framework 2.0
工具清单:
.NET Reflector
reflexil插件
打开vs2012新建一个c#类库项目,名称中输入MyEncryptionDll,点确定完成
把Class1.cs该名成EncryptionDll
再设置一下工程属性,把工程的的环境改为.net framework 2.0
接着编写自定义方法了,该方法会从u3d打包方法中获取到路径,根据路径去加密和替换Assembly-CSharp.dll,示例代码如下
1 using System; 2 using System.Text; 3 using System.IO; 4 5 namespace MyEncryptionDll 6 { 7 public class EncryptionDll 8 { 9 public static void EncryptionFunc(string stagingAreaData) 10 { 11 try 12 { 13 string _path = stagingAreaData + "/assets/bin/Data/Managed/Assembly-CSharp.dll"; 14 FileStream _assemblyReadStream = new FileStream(_path, FileMode.Open, FileAccess.Read); 15 BinaryReader _assemblyBinaryReader = new BinaryReader(_assemblyReadStream); 16 byte[] _byteData = _assemblyBinaryReader.ReadBytes((int)_assemblyReadStream.Length); 17 18 _assemblyBinaryReader.Close(); 19 _assemblyReadStream.Close(); 20 21 if (_byteData.Length > 0) 22 { 23 // 更改第一个字节信息,破坏程序集结构 24 _byteData[0] += 1; 25 26 FileStream _assemblyWriteStream = new FileStream(_path, FileMode.Create, FileAccess.Write); 27 BinaryWriter _assemblyBinaryWriter = new BinaryWriter(_assemblyWriteStream); 28 _assemblyBinaryWriter.Write(_byteData); 29 30 _assemblyBinaryWriter.Flush(); 31 _assemblyWriteStream.Flush(); 32 33 _assemblyBinaryWriter.Close(); 34 _assemblyWriteStream.Close(); 35 } 36 else 37 { 38 //throw new System.Exception("读取不到数据!"); 39 } 40 } 41 catch (System.Exception ex) 42 { 43 FileStream _logStream = new FileStream("C://log.txt", FileMode.Create, FileAccess.Write); 44 StreamWriter _sw = new StreamWriter(_logStream); 45 _sw.Write(ex.Message); 46 _sw.Flush(); 47 _logStream.Flush(); 48 49 _sw.Close(); 50 _logStream.Close(); 51 } 52 finally 53 { 54 } 55 56 } 57 } 58 }
接下来就是编译我们的程序集了,编译选项改成release吧,点 生成-->生成解决方案
成功编译后,在生成目录中找到MyEncryptionDll.dll,把它复制到C:/Program Files (x86)/Unity/Editor/Data/PlaybackEngines/androidplayer目录下
破解UnityEditor.Android.Extensions.dll:
解压reflexil,安装并运行.net reflector(该注册的注册,网址中有教程),加载reflexil插件
点击打开reflexil插件
在目录C:/Program Files (x86)/Unity/Editor/Data/PlaybackEngines/androidplayer中找到UnityEditor.Android.Extensions.dll(记得先备份)
把它拽入.net reflector中打开它。同时也把我们自定义的MyEncryptionDll.dll拽入到.net reflector中
依次展开
UnityEditor.Android.Extensions, Version=1.0.0.0
UnityEditor.Android.Extensions.dll
UnityEditor.Android
PostProcessAndroidPlayer
PostProcessInternal(BuildTarget, String, String, String, String, String, String, BuildOptions) : Void
在展开过程中,如出现如下弹框
需要加载
C:/Program Files (x86)/Unity/Editor/Data/Managed/UnityEditor.dll
C:/Program Files (x86)/Unity/Editor/Data/Managed/UnityEngine.dll
我们可以借reflexil插件看到PostProcessInternal函数的il代码,我们的目的就是通过写il代码,更改PostProcessInternal函数,在它里边调用我们自定义的程序集中的函数,植入步骤如下:
在reflexil面板中,找到152行,选中,接着右键create new..
对着图输入一些信息
参数类型:ldarg.s !!!,引用类型
参数来自stagingArea
接着Insert after select
这样我们就加入了一行代码
接着我们继续加下一行代码,选中刚生成的153行代码,右键 create new...
按照图中输入信息
这里需要选择我们自定义程序集中的函数,必须要在.net reflector中加载了我们的MyEncryptionDll.dll才能显示出来!!!
这样我们就添加完IL代码了,完成后的il结构如下
然后我们把更改后的UnityEditor.Android.Extensions.dll输出并替换原来的
这样,我们就算完事了,接下来就是按照正常流程在unity3d中选择android player,build就好了。
这样导出的apk中就已经是加密过Assembly-CSharp.dll的了,并且libmono.so也是带有解密功能的了!!!当然运行也就没问题咯。