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版本,到\mono\external\build_runtime_android.sh這個文件
第14行確認:
例如這樣: perl ${BUILDSCRIPTSDIR}/PrepareAndroidSDK.pl -ndk=r10e -env=envsetup.sh && source envsetup.sh
>>>>>>>>>>>>>>>>>>>>>>>>>

上面下載的文件是一個.exe的文件,運行一下它就會在當前目錄解壓,解壓完成把目錄名改成 android-ndk_auto-r10e

放到

D:\MinGW\x86\msys\1.0\home\zhupf\android-ndk_auto-r10e 【zhupf 是我的windows登陸名字】

4. 下載一個zip.exe

   zip.exe很多,這里直接在文章提供一個Zip, 下載並解壓后直接放到-> D:\MinGW\x86\msys\1.0\bin

5. 修改一行腳本
     文件 E:\Work\mono\external\buildscripts\PrepareAndroidSDK.pm 需要處理一下:
elsif(lc $^O eq 'cygwin')
改成,不然不認識我們的編譯環境
elsif(lc $^O eq 'cygwin' or lc $^O eq 'msys')
5. 啟動

      運行 D:\MinGW\x86\msys\1.0\msys.bat,切換到mono 工程目錄,如:E:\Work\mono\ ,然后執行編譯腳本:./external/buildscripts/build_runtime_android.sh

7. 第一次會失敗

     自動用git下載android_krait_signal_handler但編譯可能失敗【需要把git加到環境變量中】
下載E:\Work\mono\external\android_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)--------------
\jni\Application.mk
NDK_TOOLCHAIN_VERSION := clang3.3
改成
#NDK_TOOLCHAIN_VERSION := clang3.3

9. 重新編譯

./external/buildscripts/build_runtime_android.sh

10. 成功編譯到

E:\Work\mono\builds\embedruntimes\android

11. 注意
1)--------------
這樣會編譯出針對4種處理器的庫
armv5, armv6_vfp, armv7a, x86
可以根據情況修改(在這個文件最后,用#注釋掉不需要的)
E:\Work\mono\external\buildscripts\build_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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM