写在前面
说好了慢慢搬博客。。但是近一个月一直在弄加密的事情。写博客的搁置下了。这就来总结总结。
加密也是个老生长谈的事情的。先不多说,在下面的文章内仔细谈。先贴几个我真正用到的参考帖子,以做感谢。
- 这个第一次了解到Unity加密方式的地方,基本是按照这篇来做,但过程说的特别简略。基本上只是在加密方向上做了指引。
http://www.narkii.com/club/thread-330884-1.html - 做到一半的时候卡在了编译libmono上面,这篇文章算是真正的点到了关于编译libmono的所有要点。
http://www.luzexi.com/unity3d-%E9%87%8D%E6%96%B0%E7%BC%96%E8%AF%91mono%E5%8A%A0%E5%AF%86dll/ - 雨松Momo的两篇文章,真正帮助我完成了整个加密的工作,关于so的加密方法完全参照的雨松文章来做的。Momo的文章里也提到了上面这个关于编译libmono的文章。
http://www.xuanyusong.com/archives/3553
http://www.xuanyusong.com/archives/3571
转载请注明,出自喵喵丸的博客 (http://blog.youkuaiyun.com/u011643833/article/details/49102423)
准备工作
一个巨坑
- 没有什么信心的话,请不要使用Windows+ Cygwin 来编译libmono。我最开始的一段时间之内都在烦恼Cygwin的用法(也是我太渣渣的过),后面安装了Ubuntu的虚拟机,上手没什么难度而且 真 的 很 好 用。
解密工具
- Untiy中C#的代码最后编译成Assembly-CSharp.dll,解密可以用de4dot(net脱壳工具)。
- 读取上面dll的是libmono.so,我们的代码解密工作就要在这里完成,而so文件解密可以使用IDA(反编译工具)。
这两个工具才可以帮助我们真正的查看我们的加密工作是否真的完成了。
准备内容
VMWare以及Ubuntu(也可以用Mac编译,从大家的说法来看也比较简单)Ubuntu安装时推荐使用英文环境,否则命令行命令不好敲
[Windows] VMware Workstation 11.0.0正式版/注册码/注册机
怎样在VMware虚拟机中使用安装并设置Ubuntu系统
虚拟机 Ubuntu与Windows共享文件夹的方法UnityMono源码
https://github.com/Unity-Technologies/mono/
选取与自己Unity相合的Branch从GitHub下载即可(形如Unity4.6 Unity4.3这样的Branch)Android NDK
我所编译的为 Unity4.6 的mono源码,这个版本需要准备的是android-ndk-r9,这里需要说明一下,一定要按照mono对应的NDK去准备,如果需要的r9。那么r9c、 r9d等版本也不可以。【如何查看所需ndk版本】:在你下载的源码工程中查看“/external/buildscripts/build_runtime_android.sh”有下面类似的一句
perl ${BUILDSCRIPTSDIR}/PrepareAndroidSDK.pl -ndk=r9 -env=envsetup.sh && source envsetup.sh
其中 -ndk 的内容 就是所就是所需的NDK版本号。去下载即可.
编译Libmono
这篇博文是我按照回忆来写的。可能有一些步骤会断开,请留言,我会补上的。
【这一部分操作我在Ubuntu中完成】
环境配置
- 将mono源码和NDK解压到一个你可以找到的地方。
- 配置环境变量,在Terminal中执行。
gedit ~/.bashrc
这时打开了文本编辑器,在文本的末尾添加NDK_ROOT=/home/mimi/Documents/MonoHelper/android-ndk-r9
NDK=$NDK_ROOT
ANDROID_NDK_ROOT=$NDK_ROOT
export NDK_ROOT NDK ANDROID_NDK_ROOT
NDK_ROOT配置内容即是你解压后的ndk所在目录 - 保存关闭文本编辑器,Terminal执行
source ~/.bashrc
,执行后你新配置的环境变量就可以生效了,可以在Terminal中输入$NDK
查看输出来确定是否生效
编译过程
此处先不谈雨松Momo博主提到的代码更改,单纯说如何编译。各位真正编译的时候可以参照Momo对build_runtime_android.sh文件的更改。
- 将mono根目录下/external/buildscripts中的内容复制到mono根目录下
- Terminal cd到mono根目录下,执行
./build_runtime_android.sh
(在编译途中如果出现找不到xxx命令的情况,请大家根据命令行的提示,使用apt命令安装 (我只记得autoconf automake libtool 这三个必须的了Q v Q)) - 编译开始需要注意输出的前面几行(检测完ndk之后 接下来就是这个内容),如果出现了形如
perl -w:No such File or Dictionary
这样的提示。那么,先使用perl -v
确认你已经安装了perl。如果已经安装,那么cd 到/external/android_krait_signal_handler目录下,Terminal 执行./build.pl
.执行成功之后,这个目录之中呈现下图所示的目录结构
在下面的留言中~有人提到,build.pl编译的时候需要把perl -w前的env去掉,不然也会perl -w: No such File or Dictionary
报错(这个东西我贴在这里给大家做参考,似乎我当时没有遇到这样的问题) - 其余特别需要注意的地方我已经没有印象了(所以有什么问题大家请留言,我尽量帮忙解决),正确执行后开始不断刷屏幕, 最后输出有SUCCESS就证明成功编译了libmono。
- 编译过后,libmono.so存储在 /build/xxxx/android目录之下, 里面有armv5、armv6、armv7以及x86这4个文件夹,里面均有libmono.so。(build_runtime_android.sh内会执行build_runtime_android_x86.sh 所以不用另外执行build_runtime_android_x86.sh来获取x86下的libmono.so)
调试
那么我们编译好了libmono如何使用呢?
【这一部分操作我在Windows中完成】
- 首先从Unity中导出Android工程,方法参见Unity3D研究院之脚本生成Android Google Project
- 在导出的Android工程的libs目录下,可以发现armv7以及x86文件夹,将我们自己编译生成的libmono.so对应的覆盖原本的文件(armv5和armv6怎么办? 我选择了忽略(:з」∠))。
- ant 或者是在Eclipse中编译安卓工程,如果游戏正常执行了,那么恭喜你。libmono编译正确了。
还有一些内容
( ⊙ o ⊙ )出于自己堆叠了好久的工作量,最近在赶工,博客比较难产。先写出我后面要写的一些内容,估计还有一篇文章就结束代码加密的内容了
- 加密Dll
- 在libmono中做dll的相关解密
- 加密so,隐藏自己对dll解密的方法