Unity3D研究院之Android加密DLL与破解DLL .SO

首先要非常感谢大神提供了这么好的一篇文章,帮助我解决了1年我都没能解决的问题。其次感谢这两天微博好友给我的留言与评论。
阅读本文之前请先阅读大神的这篇。
http://www.luzexi.com/unity3d-%E9%87%8D%E6%96%B0%E7%BC%96%E8%AF%91mono%E5%8A%A0%E5%AF%86dll/
我做的时候有些细节不太一样。一样的地方我就不写了,我把不一样的地方写出来。
加密DLL首先要找准unity版本对应的mono,地址在这里 https://github.com/Unity-Technologies/mono
这里有个很恶心的事情,unity的mono版本并不是按小版本分的,比如我想找unity4.6.1 对应的mono那么它就没有,unity只提供4.3x 或者 4.6x 或者5.1x 这种大版本的mono .从提交时间上来看更新的很随意啊。我感觉要想找到对应的unity版本,可以根据unity这个版本发布的时候,然后在github上找对应时间的mono版本。。
如下图所示,打开网页后,找到对应的branches版本, 这里选择unity-4.6 或者 unity-5.1 这两个版本我已经测试通过。别的版本希望大家都能来参与测试。

在说说说恶心的地方,我下载4.6以后,把mono编译出来。放在unity4.6.1的打出来的包里 死活会报错, 但是4.6.6就没问题了。。 不过还好我这里两个项目 一个是用unity4.6.6还有一个是unity5.1.1目前都没出现问题。
下面我都用unity4.6举例,其他版本原理都一样我就不赘述了。
1.github下载下来对应的mono解压放在本地,在终端里先cd到这个目录下。
2.把打包脚本拖入终端中(注意脚本的路径),然后就开始耐心等待吧。估计5分钟左右就OK了。
3.打包脚本分两种, 一个是 arm的,还有一个是x86,执行build_runtime_android.sh 就可以了, 它会自动调用
build_runtime_android_x86.sh。

Unity3D研究院之Android加密DLL与破解DLL .SO(八十一) - 雨松MOMO程序研究院 - 2

打包脚本我们需要改一下,因为下载下来的脚本直接运行打的是debug版本,效果就是打出来的.so比unity自带的大很多。我们要改成release版本。
如下图所示,左边是x86,右边是arm。把CFLAGS里的-g改成-O2 (O0 ,O1,O2,OS,O3分了好几个压缩档次,我觉得O2就可以了)然后在LDFLAGS里加上-Wl,–gc-sections \ 就行了。
Unity3D研究院之Android加密DLL与破解DLL .SO(八十一) - 雨松MOMO程序研究院 - 3

注意:今天同事说x86下有些手机进游戏卡死。后来经过一番分析,原来是x86的编译选项和arm不一样。如下图所示,在X86.sh 这里只把-g去掉就行。。别的什么都别改。切记切记!!!
Unity3D研究院之Android加密DLL与破解DLL .SO(八十一) - 雨松MOMO程序研究院 - 4

然后在下面把这两句代码注释掉,不然编译的时间就要增加了。

clean_build “$CCFLAGS_ARMv5_CPU” “$LDFLAGS_ARMv5” “$OUTDIR/armv5”#clean_build “$CCFLAGS_ARMv6_VFP” “$LDFLAGS_ARMv5” “$OUTDIR/armv6_vfp”

在打mono.so前记得改一下解密算法。因为在测试所以解密和加密算法我们就写简单一点。如下图所示,mono/metadata/image.c里面找到 mono_image_open_from_data_width_name 。 因为我只会对自己写的c#编译后的dll加密,所以这里判断一下是否是我们自己的dll,解密算法很简单就是让字节下标为1的字节-1。
如果你要热更DLL时一定要注意!!这里一定要先判断一下name是否为NULL 不然使用System.Reflection.Assembly.Load 在Android平台反射调用DLL的时候unity 会挂的。

1
2
3
4
5
6

if(name != NULL)
{
if(strstr(name,"Assembly-CSharp.dll")){
data[0]-=1
}
}


还有如果想在 mono里打印Log的话可以使用

include <glib.h>

g_message(“momo: %s”,str);
OK 然后开始编译mono吧。arm 和x86 两个大概 5 分钟左右就能编译完成。对应会会放在mono根目录build的文件夹里。然后回到生成的adnroid工程中,把libmono.so 分别放在x86和armeabi-v7a文件夹下。因为我项目用了slua所以这里也会有一些第三方的.so


再说说自动化的问题,DLL每次代码变更都会重新生成一个新的,那么我总不能每次都手动加密DLL然后在手动的拷贝到assets下面吧。。
再说一句,我的项目在处理自动化打包时用的是adnroid的ant打包。也就是先把unity导出成一个android 工程。然后在打包。所以我的自动化就可以是当android工程生成后,然后把dll读取到内存里,加密后在重新写到原来工程的位置上。如果有朋友不太懂自动化,可以在我博客里搜索一下,以前我有写过。
http://www.xuanyusong.com/archives/3384 环境变量如果你不会加的话,也可以看我这篇文章。
这段代码的意思就是当eclipse的android工程生成后,紧接着就给dll加密。。字节一变那么Dll其实就变成了一个普通的二进制文件。这样用各种反编译Dll的工具就都打不开了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

//shell脚本来自动调用unity中的这个c#方法
static void ExportAndroidProject()
{

List<string> args = GetArgs("ExportAndroidProject");
if (string.IsNullOrEmpty (BuildPipeline.BuildPlayer (GetBuildScenes (), args [0], BuildTarget.Android, BuildOptions.AcceptExternalModificationsToPlayer)))
{
encryptDll (args [0]);
}
}
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);
}
}

然后还有前面我们编译出来的两个 mono.so 也要在这里自动化一并拷贝到这个工程对应的目录下面(可以在shell里拷贝,也可以在C#里拷贝)。 接下来就调用自动打包apk就行了。。总之最后的效果就是Dll不能被解开了。如下图所示。


Unity3D研究院之Android加密DLL与破解DLL .SO(八十一) - 雨松MOMO程序研究院 - 8

但是,高兴的别太早。DLL是解不开了,但是你的解密算法是写在.so里面的,那么对方反编译你的.so取出解密算法,随便写个小工具就可以把你的DLL逆向回来。。
在windows上下载ida pro 神器(真是道高一尺魔高一丈啊)。
http://www.h4ck.org.cn/2014/08/ida-pro-6-5-with-hex-rays-x86-decompiler-v1-5-and-hex-rays-arm-decompiler-1-7/
然后打开我们编译的libmono.so
找到mono_image_open_from_data_width_name 方法,然后点击F5 解密算法就破解了。(下面我找到了一个避免破解的方法,在本文的最后)
Unity3D研究院之Android加密DLL与破解DLL .SO(八十一) - 雨松MOMO程序研究院 - 9

怎样才能避免别人这么容易破解你的DLL呢?请看我的下一篇文章 Unity3D研究院之Android二次加密.so二次加密DLL(八十二)
本文固定链接: http://www.xuanyusong.com/archives/3553
转载请注明: 雨松MOMO 2015年07月02日
雨松MOMO程序研究院 发表

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

推荐阅读更多精彩内容