Unity Android加密dll (一)
文:AdamBieber
前言
之前我曾写过Unity加密apk的方法,但那只是非常初级的。如今,我采用了不同的方法来实现相关功能,在此首先感谢提供资料的各位前辈。相关参考资料链接如下:
- http://www.xuanyusong.com/archives/3553
- http://www.luzexi.com/Unity3d/游戏架构/前端技术/2015/04/11/Unity3D-重新编译Mono加密DLL/
正文
1. 下载必要工具
mono-Unity
下载地址:https://github.com/Unity-Technologies/mono 。需要根据Unity版本不同下载不同版本的mono-Unity,我下载的是5.1版本的mono。
JDK
通过百度搜索即可下载,任何版本基本都可以。
NDK
其版本需要和下载的mono版本相对应。打开已下载好的mono,查看mono-unity-5.1/external/buildscripts/build_runtime_android.sh文件,可得知所需的ndk版本,例如其中有如下代码:
perl ${BUILDSCRIPTSDIR}/PrepareAndroidSDK.pl -ndk=r9 -env=envsetup.sh && source envsetup.sh
SDK
SDK在网上有很多资源可供下载。
注意:由于我使用的是Mac电脑进行编辑,下载的工具都必须是mac版本,不能和win版本通用。我也尝试过在Windows电脑上操作,但各种编译不通过,需要安装Cygwin或者Linux虚拟机,而且各种配置比较麻烦,所以最终选择在Mac电脑下进行编译。
2. 配置环境变量
关于ndk和sdk环境变量的配置,可参考该链接:http://blog.csdn.net/zf135792468/article/details/11926995
3. 配置mono编译需要的工具
mono编译需要autoconf、automake、libtool、pkg-config这些工具,建议下载安装。可以使用brew进行安装,具体操作步骤如下:
首先执行以下命令安装brew:
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
然后执行:
brew install autoconf automake libtool pkg-config
4. 编译mono
步骤1:解压并进入目录
从github下载对应的mono并解压到本地,打开Mac的终端,使用cd命令进入mono的目录。
步骤2:执行打包脚本
将打包脚本拖入终端(注意脚本的路径),然后耐心等待,大约5分钟左右即可完成。打包脚本有两种,分别是arm的和x86的,执行build_runtime_android.sh脚本即可,它会自动调用build_runtime_android_x86.sh脚本。
步骤3:修改打包脚本为release版本
下载下来的脚本直接运行打的是debug版本,打出来的.so文件比Unity自带的大很多,我们需要将其改成release版本。具体操作如下:
在脚本中,将CFLAGS里的-g改成-O2(O0、O1、O2、OS、O3分了好几个压缩档次,这里选择O2即可),然后在LDFLAGS里加上-Wl,--gc-sections \ 。
步骤4:注释部分代码
为了减少编译时间,需要将以下两句代码注释掉:
#clean_build “$CCFLAGS_ARMv5_CPU” “$LDFLAGS_ARMv5″ “$OUTDIR/armv5″
#clean_build “$CCFLAGS_ARMv6_VFP” “$LDFLAGS_ARMv5″ “$OUTDIR/armv6_vfp”
步骤5:修改解密算法
在打mono.so前,需要修改解密算法。由于是在测试阶段,解密和加密算法可以写得简单一些。在mono/metadata/image.c文件里找到mono_image_open_from_data_width_name函数,因为我只会对自己写的C#编译后的dll加密,所以在这里判断是否是我们自己的dll,解密算法很简单,就是让字节下标为1的字节减1。
完成上述修改后,就可以开始编译mono了,arm和x86两个版本大概5分钟左右就能编译完成。编译好的文件会放在mono根目录的build文件夹里。然后回到生成的Android工程中,把libmono.so放在桌面上,等Unity导出完Android项目之后会再次使用到它。
步骤6:编写Unity脚本
回到Unity中,随便创建一个脚本,放在Editor文件夹下,脚本内容如下:
using UnityEditor;
using UnityEngine;
using System.IO;
public class BuildGoogleProject
{
[MenuItem("Tools/Build Google Project")]
static public void BuildAssetBundles()
{
string path = EditorUtility.SaveFolderPanel("请选择路径", "", "");
if (string.IsNullOrEmpty(BuildPipeline.BuildPlayer(GetBuildScenes(), path, BuildTarget.Android, BuildOptions.AcceptExternalModificationsToPlayer)))
{
encryptDll(path);
}
}
static private void encryptDll(string path)
{
// DLL在android工程中对应的位置
string inpath = path + "/" + PlayerSettings.productName + "/assets/bin/Data/Managed/Assembly-CSharp.dll";
if (File.Exists(inpath))
{
// 先读取没有加密的dll
byte[] bytes = File.ReadAllBytes(inpath);
// 字节偏移 DLL就加密了
bytes[0] += 1;
// 再写到原本的位置上
File.WriteAllBytes(inpath, bytes);
}
}
static string[] GetBuildScenes()
{
string[] scenes = new string[EditorBuildSettings.scenes.Length];
for (int i = 0; i < scenes.Length; i++)
{
scenes[i] = EditorBuildSettings.scenes[i].path;
}
return scenes;
}
}
5. 导出并打包项目
在Unity中选择Tools/Build Google Project,这样导出Android项目之后,dll脚本文件是已经加密过的。把桌面上的libmono.so替换Android项目中的libmono.so文件,然后用Eclipse打包成apk即可。
转载请标明出处 版权声明:本文为博主原创文章,未经博主允许不得转载。