引子
给Unity Dll 加密
软件环境
- VirturlBox 虚拟机 5.10
- 虚拟机 Centos 7 64bit 系统
- Untiy 2017 版本
原理
Unity 编译代码会生成以下几个文件:
- Plugins 代码编译为 Assembly-CSharp-firstpass.dll
- Editor 代码会编译为 Assembly-CSharp-Editor.dll
- Plugins-Editor 代码会编译为 Assembly-CSharp-Editor-firstpass.dll
- 其他代码会编译为 Assembly-CSharp.dll
可以选择加密 Assembly-CSharp.dll 文件
加密完文件,要保证Unity能识别加载,需要二进制还原
Unity 使用libmono.so 加载DLL文件
函数在 image.c 文件内,修改其中的 mono_image_open_from_data_with_name 方法
修改前1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41MonoImage *
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 (!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);
}
image = g_new0 (MonoImage, 1);
image->raw_data = datac;
image->raw_data_len = data_len;
image->raw_data_allocated = need_copy;
image->name = (name == NULL) ? g_strdup_printf ("data-%p", datac) : g_strdup(name);
iinfo = g_new0 (MonoCLIImageInfo, 1);
image->image_info = iinfo;
image->ref_only = refonly;
image->ref_count = 1;
image = do_mono_image_load (image, status, TRUE, TRUE);
if (image == NULL)
return NULL;
return register_image (image);
}
修改后1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51MonoImage *
mono_image_open_from_data_with_name (char *data, guint32 data_len, gboolean need_copy, MonoImageOpenStatus *status, gboolean refonly, const char *name)
{
//修改数据流开始 内部的实现方法,可以自己定
if(strstr(name,"Assembly-CSharp.dll")){
int xorkey = 201;
int i = 0;
for (i = 3; i < 11; ++i)
{
data[i] = (data[i]^xorkey);
}
}
//修改数据流结束
MonoCLIImageInfo *iinfo;
MonoImage *image;
char *datac;
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);
}
image = g_new0 (MonoImage, 1);
image->raw_data = datac;
image->raw_data_len = data_len;
image->raw_data_allocated = need_copy;
image->name = (name == NULL) ? g_strdup_printf ("data-%p", datac) : g_strdup(name);
iinfo = g_new0 (MonoCLIImageInfo, 1);
image->image_info = iinfo;
image->ref_only = refonly;
image->ref_count = 1;
image = do_mono_image_load (image, status, TRUE, TRUE);
if (image == NULL)
return NULL;
return register_image (image);
}
过程
安装 CentOS 7
更换镜像源
参考其他文章
Vbox文件共享
参考其他文章
为了方便 文件传输
Mono代码下载
1 | git clone https://github.com/Unity-Technologies/mono.git mono |
编译代码
编译哪个版本的mono 需要切换到对应的分支上
1 | git checkout -b unity-2017.1 |
需要安装 pkg-config, glib 2.4
1 | yum install pkgconfig glib2 |
当获取到源码以后是这样一个界面
1 | [root@localhost mono-unity-2017.1]# tree -L 1 |
在当前目录下执行脚本
1 | # sh external/buildscripts/build_runtime_android.sh |
去下载NDK,再配置
需要在envsetup.sh中设置ANDROID_NDK_ROOT的值
- 安装后发现缺少 libtool bison
1 | yum install libtool bison |
- 出现缺少g++
1 | configure: error: You need to install g++ |
解决 安装g++工具
1 | yum groupinstall "Development Tools" |
- 缺少glib2
1 | Package glib-2.0 was not found in the pkg-config search path. |
解决办法
1 | yum install glib2-devel |
- 再次编译 还是不通过,找到需要安装cmake
1 | yum install cmake |
到这里已经可以编译 Unity-5.3 版本的libmono.so
但是之后的还是不能编译通过解决Unity-2017 编译不能通过问题
问题如下:
1 | It should have been installed in the `/usr/local/lib/mono/4.5/mscorlib.dll' directory. |
解决办法:
需要安装Mono
验证 mono版本1
mono -V
1 | ../../unity/unity_utils.h:32:34: error: unknown type name ‘vprintf_func’ |
最后还是失败了!!!
换成 Ubuntu 系统编译成功了
执行1
./external/buildscripts/build_runtime_android.sh
编译成功以后
修改 image.c 代码
重编译
android_krait_signal_handler 项目 报错
1 | ./build.pl |
安装perl lwp模块 下载最新的Android NDK资源
1 | sudo yum install perl-libwww-perl |
重新执行
执行1
./external/buildscripts/build_runtime_android.sh
可以顺便修改下 mono_image_open_from_data 函数名
.h .c 两个地方都要改1
2
3
4
5```
### 修改 build_runtime_android 编译选项
编译时 不需要编译 ARMv5,ARMv6 两个版本
clean_build “$CCFLAGS_ARMv5_CPU” “$LDFLAGS_ARMv5” “$OUTDIR/armv5”
clean_build “$CCFLAGS_ARMv6_CPU” “$LDFLAGS_ARMv5” “$OUTDIR/armv6_vfp”
```
build_runtime_android.sh
arm 下
把CFLAGS里的-g改成-O2
build_runtime_android_x86.sh
x86 下
把CFLAGS里的-g 去掉