Unity Android加密dll (一)

2015年11月16日 11:19 0 点赞 0 评论 更新于 2025-11-21 19:24

文:AdamBieber

前言

之前我曾写过Unity加密apk的方法,但那只是非常初级的。如今,我采用了不同的方法来实现相关功能,在此首先感谢提供资料的各位前辈。相关参考资料链接如下:

正文

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编译需要autoconfautomakelibtoolpkg-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改成-O2O0O1O2OSO3分了好几个压缩档次,这里选择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即可。

转载请标明出处 版权声明:本文为博主原创文章,未经博主允许不得转载。

作者信息

洞悉

洞悉

共发布了 3994 篇文章