Unity3D DLL加密

Unity3D打包android应用程序时,如果不对DLL加密,很容易被反编译,导致代码的泄露。通常的做法是通过加密DLL或者对代码进行混淆。本文的所要探讨的是通过加密的方式来对DLL进行保护,并详细记录加密的操作过程。

主要参考

    雨松的博文:http://www.xuanyusong.com/archives/3553 

    http://csftech.logdown.com/posts/452269-android-unity-encryption

    这两篇文章已经详细介绍了加密的过程,但是还是有些坑和有些操作没有给出。

原理说明

所有的代码编译后是在apk\assets\bin\Data\Managed\Assembly-CSharp.dll下,要做的就是对这个DLL进行加密,Assembly-CSharp.dll由libmono.so加载,所以需要在libmono.so中对加密过的Assembly-CSharp.dll进行解密,幸好unity提供了mono的代码可以进行编译修改。当然对于libmono.so也存在被反编译的风险,本文暂不考虑。

准备

linux系统。本文选择采用的是Ubuntu14.04,虚拟机也可以,另外可以用Windows + Cygwin进行编译,不过考虑到这样做可能踩坑更多,果断放弃。

unity mono源码,可以在https://github.com/Unity-Technologies/mono下载,branch选择unity4.6,直接下zip包,或者git下来都可以,下载下来的zip包为mono-unity-4.6.zip。

unity3d 4.6版本,本文试验的是4.6的编译,注意一定要安装4.6.6+的版本,否则重编的libmono.so会报错(坑一)。

android ndk, 版本可以根据unity-mono中用的版本来下载,参见unity-mono/external/buildscripts/build_runtime_android.sh, 搜一下ndk=就能找到,本文用到的是r10e,下载下来的ndk为android-ndk-r10e-linux-x86_64.bin。

apktools, 用来对apk进行解包签名打包,2.0以上版本,否则打包是会报错。

编译mono

1)为了方便使用root进行编译,Ubuntu下root默认不开启,可以使用:

    sudo passwd root

    输两次密码后

su -

    进行登录

2)NDK安装

    安装7z 

       apt-get install p7zip-full

    解压

       7z x android-ndk-r10e-linux-x86.bin

    配置环境变量,配置方法有很多,可以修改/etc/profile或者~/.bashrc,这里直接shell下添加临时的环境变量,不添加后面编mono时会报找不到NDK

       export ANDROID_NDK_ROOT=/home/xubo/unity-dev/android-ndk-r10e

export PATH=$ANDROID_NDK_ROOT:$PATH

3)检查一下mono使用的NDK版本

vi打开mono-unity-4.6/external/buildscripts/build_runtime_android.sh可以找到

perl ${BUILDSCRIPTSDIR}/PrepareAndroidSDK.pl -ndk=r10e -env=envsetup.sh && source envsetup.sh

这里可以确定当前的unity mono使用r10e来进行编译的

4)安装编译必备的一些包

apt-get install autoconf automake bison build-essential gettext git libglib2.0 libtool perl

5)尝试第一次编译

    ./external/buildscripts/build_runtime_android.sh

报错:

        /usr/bin/env: perl -w: No such file or directory

    这里unity-mono编译的时候会去git 一个包android_krait_signal_handler,在external目录下,就是这个包报错,这个包出错的问题很多,是个巨坑(坑二)。

    打开android_krait_signal_handler/build.pl,将第一行

        #!/usr/bin/env perl -w

改为

        #!/usr/bin/perl -w

将下面行

        PrepareAndroidSDK::GetAndroidSDK(undef, undef, "r9");

改为实际用到的NDK

        PrepareAndroidSDK::GetAndroidSDK(undef, undef, "r10e");

将buildscripts/PrepareAndroidSDK.pm替        换android_krait_signal_handler/PrepareAndroidSDK.pm

    打开jni/Application.mk将下两行都删掉   

APP_PLATFORM:=android-9NDK_TOOLCHAIN_VERSION:=clang3.3

 否则会报下面的错误

make:execvp:/home/xubo/unity-dev/android-ndk-r10e/toolchains/arm-linux-androideabi-4.8:Permission denied

6)尝试第二次编译

    configure不通过,打开config.log发现

./configure:line4546:/home/xubo/unity-dev/android-ndk-r10e/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc:No such fileordirectory

检查该目录,发现文件是存在的,这里是因为虽然NDK是64位的,但是交叉编译工具链是32位的,安装一下,而本文采用的编译机是64位的,安装一下64位下运行32位可执行文件的包

apt-get install lib32z1 lib32ncurses5 lib32bz2-1.0

7)尝试第三次编译,至此我们应该可以编译成功了,但还没涉及到加解密,注意编译需要在mono的根目录下进行。最终显示如下则OK:

Build SUCCESS!Android STATIC/SHARED libraries are found here:builds/embedruntimes/android

加密程序

加密过程可参考上面的链接,就是将Assembly-CSharp.dll视作普通的文件,随便用什么语言写个加密的代码,简单的可以修改几个字节,做偏移啥的,生成一个新的Assembly-CSharp.dll,替换原来的,这样一般的破解软件就没辙了。

MONO解密

上面只是试验了一下mono的编译,关于将解密的代码添加至mono还没有做。

打开mono-unity-5.3/mono/metadata/image.c,找到mono_image_open_from_data_with_name函数修改如下

MonoImage*mono_image_open_from_data_with_name(char*data,guint32 data_len,gboolean need_copy,MonoImageOpenStatus*status,gboolean refonly,constchar*name){MonoCLIImageInfo*iinfo;MonoImage*image;char*datac;//添加如下代码if(name!=NULL){if(strstr(name,"Assembly-CSharp.dll")){//这里写下你的解密的代码,入参data是从Assembly-CSharp.dll读文件读出来的//被加密的原始数据,通过你的解密代码生成一段新的data}}if(!data||!data_len){if(status)*status=MONO_IMAGE_IMAGE_INVALID;returnNULL;}datac=data;if(need_copy){datac=g_try_malloc(data_len);if(!datac){if(status)*status=MONO_IMAGE_ERROR_ERRNO;returnNULL;}memcpy(datac,data,data_len);}

MONO正式编译

正式编译mono前,还有两个地方要修改,不修改编译出来的是debug版本,libmono.so有8M,

打开build_runtime_android.sh, 将下面标红的-g给去掉,编译release版本

CFLAGS="\-DANDROID-DPLATFORM_ANDROID-DLINUX-D__linux__ \-DHAVE_USR_INCLUDE_MALLOC_H-DPAGE_SIZE=0x1000\-D_POSIX_PATH_MAX=256-DS_IWRITE=S_IWUSR \-DHAVE_PTHREAD_MUTEX_TIMEDLOCK \-fpic-g-funwind-tables \

同样build_runtime_android_x86.sh里面也去掉

Unity3D 签名

别忘记了,需要unity4.6.6+的版本,本文是在unity4.6.9下测试OK。

制作一个签名,后面在用apktool重新封包时用得到,用这个签名对游戏进行build。

Apktool解包封包

1)(windows下操作)确定apktool目录下有aapt.exe,apktool.bat,apktool.jar,确定版本是2.0+

2)将生成的包例如1.apk 复制到apktool/下

3)cmd命令行下,进入apktool目录,执行apktool d 1.apk进行解包,会在apktool下生成与包名相同的文件夹1/

4) 将加密过的Assembly-CSharp.dll覆盖1\assets\bin\Data\Managed\Assembly-CSharp.dll

5) 将编译过的libmono.so,注意这里选择armv7a/,和x86/下的,分别覆盖1\lib\armeabi-v7a和1\lib\x86\下的libmono.so

6) 封包命令行下执行apktool b -f 1,会在1/下生成dist文件,里头就是新封的包,改名为2.apk,并复制到apktool/下

7)签名,隐去的是你要填的签名文件名,和别名

jarsigner -verbose -keystore ****.keystore -signedjar 2_s.apk 2.apk ****

8)2_s.apk就是你加密过的包,进行安装测试

libmono.so加密

雨松还提到了libmono.so的加密,这里先不涉及吧,strip动态库,可能能起到相同的效果。

小结

这样加密经过测试是OK的,可以防止一般的反编译软件进行破解了,对于高手可能还防不住,另外编译mono有点心惊胆战,android_krait_signal_handler这个工程是个坑,还是有点担心编出来的libmono.so有咩有啥隐患,所以这样弄需要在各种android机子上多测试。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容