上一篇文章一次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
工具清單:
編寫自定義程序集:
打開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也是帶有解密功能的了!!!當然運行也就沒問題咯。