Unity3D DLL加密

3 篇文章 0 订阅

网上搜了很多教程 就这篇成功了 转载一下

原文 http://blog.51cto.com/snailwalk/1745970

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-9
   NDK_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: line 4546: /home/xubo/unity-dev/android-ndk-r10e/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc: No such file or directory


    检查该目录,发现文件是存在的,这里是因为虽然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, const char *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;
                return NULL;
        }
        datac = data;
        if (need_copy) {
                datac = g_try_malloc (data_len);
                if (!datac) {
                        if (status)
                                *status = MONO_IMAGE_ERROR_ERRNO;
                        return NULL;
                }
                memcpy (datac, data, data_len);
        }
第三方加密代码文件依赖 要修改

/mono/mono-unity-xx/mono/Makefile.am 位置


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。

wKiom1bT_7CxRO8WAAD5dUcSwDo177.jpg


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机子上多测试。


淘宝花钱买的最新版!需要的拿去! This asset obfuscates your code to make it harder for bad guys to reverse engineer your projects. Specifically designed for Unity, it seamlessly links in with its build process. The top priority of this package is to work straight out of the box with no extra steps required. While other obfuscators can stop a game from working, Beebyte's obfuscator looks for specific Unity related code that must be protected. The contents of your source files are unchanged, the obfuscation targets the compiled assembly. Features: - Supports IL2CPP - Supports Assembly Definition Files (Unity 2017.3+) - Removes Namespaces without any conflicts - Recognises Unity related code that must not be changed - Renames Classes (including MonoBehaviours) - Renames Methods - Renames Parameters - Renames Fields - Renames Properties - Renames Events - String literal obfuscation - Adds fake methods - Easy and extensive customisation using the Unity inspector window - Consistent name translations are possible across multiple builds and developers - Semantically secure cryptographic naming convention for renamed members The asset works for both Unity Free and Unity Pro version 4.2.0 onwards (including Unity 5 & 2017 & 2018). Build targets include Standalone, Android, iOS, WebGL, UWP. Other platforms are not guaranteed or supported but may become supported at a future date. IL2CPP builds are much harder to reverse engineer but strings and member information (class, method names etc) are visible in the global-metadata.dat file. Obfuscation will apply to this file adding further security. Why not complement your security with the Anti-Cheat Toolkit - a great third party asset. For more information about the Obfuscator, please see the FAQ
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值