zoukankan      html  css  js  c++  java
  • Unity防破解 —— 重新编译mono

        Unity4.x版本导出android包时,只能选择mono,无法使用il2cpp,这就造成了我们的程序集很容易被修改……很多朋友在发布项目时觉得即使代码暴露出去也没什么关系,只有项目火了才有必要等,然而一旦游戏被破解,很容易对游戏生态造成无法想象的灾难,这里写两篇博文记录一下最近加密Dll的过程。

    一.加密Dll需要做那些事

    1. 想要加密Dll的前提条件是我们必须修改mono,因为Unity并没有在mono中为开发者提供加密的接口或者功能,所以我们必须手动编译mono,从而替换掉Unity中原本的mono。

    2.需要一种加密Dll的可逆算法,常见的DES,TEA,XXTEA等,当然需要是C语言的实现

    3.mono中对key的保护,因为即使.so文件,也是可以被反编译的,如神器IDA等

    4.一些打包工具或者脚本,因为一旦自己加密了Dll就无法完全依赖Unity打包了,整个打包流程会变得相对繁琐,这事需要反复打包的话最好还是优化对应的工具。

    这两篇博文都是基于Untiy4.7版本的,对应的mono是4.6,当然我想如果是其他版本的mono应该也是可以的。

    二.编译mono

        编译mono的过程其实还是很繁琐的,一开始我尝试在linux下编译mono,然而各种失败,我想Unity可能并不想开发者自己编译mono,所以给的文档中各种坑,然后参考了雨凇编译mono的文章,结果发现也是各种失败,汗……后来意外发现在 “ulua&cstolua技术交流群①(341746602)”“不说害怕”大神写过一篇编译mono的教程,于是拿过来试了一下,踩了几个小坑后就顺利编译成功了,下面就直接这篇简单修改一下贴出来啦:

    1.获得Unity-mono

         我们需要编译的是 针对unity-4.6 mono的安卓SO,所以首先需要clone Unity-mono ,然后切到分支unity-4.6,(注意:已经测试编译过unity-5.2,所以对于最新的版本应该也可以的)

    2. 准备编译环境

         下载ulua编译的那个MinGW(msys) 【注意:里面包含x86和x64我用的x86版本,但同时支持编译出各个版本的结果】放到D:MinGW  【注意MinGW一定要放在某个磁盘的根目录,否则会造成MinGW环境变量错误,导致编译失败】

    参考:
    https://github.com/jarjin/ulua_runtime_project
    http://pan.baidu.com/s/1gd1Wyx9#path=%252Fulua_src

    3. 下载
         首先需要下载NDK : android-ndk-r10e
    ==========================
    注意至于是不是下载这个NDK版本,到monoexternaluild_runtime_android.sh这个文件
    第14行确认:
    例如这样: perl ${BUILDSCRIPTSDIR}/PrepareAndroidSDK.pl -ndk=r10e -env=envsetup.sh && source envsetup.sh
    >>>>>>>>>>>>>>>>>>>>>>>>>

    上面下载的文件是一个.exe的文件,运行一下它就会在当前目录解压,解压完成把目录名改成 android-ndk_auto-r10e

    放到

    D:MinGWx86msys1.0homezhupfandroid-ndk_auto-r10e 【zhupf 是我的windows登陆名字】

    4. 下载一个zip.exe

       zip.exe很多,这里直接在文章提供一个Zip, 下载并解压后直接放到-> D:MinGWx86msys1.0in

    5. 修改一行脚本
         文件 E:WorkmonoexternaluildscriptsPrepareAndroidSDK.pm 需要处理一下:
    elsif(lc $^O eq 'cygwin')
    改成,不然不认识我们的编译环境
    elsif(lc $^O eq 'cygwin' or lc $^O eq 'msys')
    5. 启动

          运行 D:MinGWx86msys1.0msys.bat,切换到mono 工程目录,如:E:Workmono ,然后执行编译脚本:./external/buildscripts/build_runtime_android.sh

    7. 第一次会失败

         自动用git下载android_krait_signal_handler但编译可能失败【需要把git加到环境变量中】
    下载E:Workmonoexternalandroid_krait_signal_handler
    但编译失败

    8. 修改android_krait_signal_handler下的脚本
    1)--------------
    PrepareAndroidSDK.pm 内
    elsif(lc $^O eq 'cygwin')
    改成,不然不认识我们的编译环境
    elsif(lc $^O eq 'cygwin' or lc $^O eq 'msys')

    2)--------------
    build.pl内
    #!/usr/bin/env perl -w
    改成
    #!/usr/bin/perl -w

    PrepareAndroidSDK::GetAndroidSDK(undef, undef, "r9");
    改成
    #PrepareAndroidSDK::GetAndroidSDK(undef, undef, "r9");

    3)--------------
    jniApplication.mk
    NDK_TOOLCHAIN_VERSION := clang3.3
    改成
    #NDK_TOOLCHAIN_VERSION := clang3.3

    9. 重新编译

    ./external/buildscripts/build_runtime_android.sh

    10. 成功编译到

    E:Workmonouildsembedruntimesandroid

    11. 注意
    1)--------------
    这样会编译出针对4种处理器的库
    armv5, armv6_vfp, armv7a, x86
    可以根据情况修改(在这个文件最后,用#注释掉不需要的)
    E:Workmonoexternaluildscriptsuild_runtime_android.sh
    以便精简
    比如:
    #clean_build "$CCFLAGS_ARMv5_CPU" "$LDFLAGS_ARMv5" "$OUTDIR/armv5"

    2)--------------
    编译出的so文件大约8m, 是Debug
    若要编译release版本
    对于arm7等,修改build_runtime_android.sh
    只要把CFLAGS里的-g改成-O2就可以了 【注意-O2 是gcc编译优化选项,其中‘O’是英文字母'O’】
    对于x86,修改build_runtime_android_x86.sh
    去除CFLAGS里的-g
    注:O是优化等级(Optimize)的参数
    -g选项,表示产生供gdb调试的调试数据

    参考:
    http://www.xuanyusong.com/archives/3553
    其中加-Wl,–gc-sections 这个我这边试了会失败,可以不加。

    12. strip去除调试信息(可以加到build_runtime_android.sh和build_runtime_android_x86.sh脚本)
    1)--------------
    $ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/arm-linux-androideabi-strip.exe libmono.so
    2)--------------
    $ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/bin/arm-linux-androideabi-strip.exe libmono.so

    最后

       下篇文章会介绍如何加密Dll和在mono中保护key的问题 : http://www.cnblogs.com/lixiang-share/p/5979981.html

  • 相关阅读:
    VIM 用正则表达式,非贪婪匹配,匹配竖杠,竖线, 匹配中文,中文正则,倒数第二列, 匹配任意一个字符 :
    中国科学院图书馆分类法
    让进程在后台可靠运行的几种方法 nohup,setsid,&,disown,CTRL-z ,screen
    Exception Handling Statements (C# Reference)
    ChannelFactory.Endpoint 上的地址属性为空。ChannelFactory 的终结点必须指定一个有效的地址。
    .NET中六个重要的概念:栈、堆、值类型、引用类型、装箱和拆箱
    WCF Host中的BaseAddress 和 Endpoint中的Address的区别
    使用vs自带的wcf配置工具
    Automatic Code Generation-->Implement Interface
    Learning WCF Chapter1 Exposing Multiple Service Endpoints
  • 原文地址:https://www.cnblogs.com/lixiang-share/p/5978107.html
Copyright © 2011-2022 走看看