如果选择disable,则最后的il中包含有代码。可以被反编译。
建议选择strip bytecode,这个在ios下是安全无风险的,而且il bytecode会被移除。
ios下使用aot进行了优化,所以可以移除字节码。
在android下,可以采用对 Assembly-CSharp.dll 文件进行加密来防止破解看到源码。
修改dll文件格式之后,需要重新编译libmono.so文件,这样系统才能正确运行代码。
发个简单的例子:
这个例子采用加密的时候循环右移3位,解密的时候循环左移3位。并且将前两个字节标记为“ZJ"
修改dll的程序:
ifstream fs(args[2],std::ios::binary);
if(fs.is_open())
{
fs.seekg(0,ios::end);
long size = fs.tellg();
cout<<size<<endl;
char *mz = new char[size];
fs.seekg(0,ios::beg);
fs.read(mz,size);
if(mz[0]=='M'&&mz[1]=='Z')
{
cout<<"encrypt"<<endl;
mz[0] = 'Z';
mz[1] = 'J';
for(int j = 2;j<size;j++)
{
unsigned char mm = mz[j];
mm = ((mm>>3)|(mm<<5));
mz[j] = mm;
}
}
libmono端,需要修改 mono/metadata/image.c 的do_mono_image_load方法,如下
static MonoImage *
do_mono_image_load (MonoImage *image, MonoImageOpenStatus *status,
gboolean care_about_cli, gboolean care_about_pecoff)
{
MonoCLIImageInfo *iinfo;
MonoDotNetHeader *header;
//////////////////////////////////////////
if((image->raw_data[0]=='Z') && (image->raw_data[1]=='J'))
{
//doit,解密部分代码
image->raw_data[0]='M';
image->raw_data[1]='Z';
int i = 2;
while(i<image->raw_data_len)
{
unsigned char mm = image->raw_data[i];
mm = ((mm>>5)|(mm<<3));
image->raw_data[i] = mm;
i++;
}
printf("dencrypt by zj");
}
////////////////////////////////////////////
mono_profiler_module_event (image, MONO_PROFILE_START_LOAD);
这一段代码,后来改了一个增强版的,地址在https://git.oschina.net/zhjzhjxzhl/wzfd.git
工具集也都在这里。
然后用重新编译的libmono.so来加载,就可以了。
编译的过程需要在linux环境下。
先从git获取代码
https://github.com/Unity-Technologies/mono/tree/unity-4.5
由于git获取的不包含submodule,编译的时候会出问题。所以获取之后,先运行
git submodule init
git submodule update
这样包完全之后,就可以编译了。
先运行 external/android_krait_signal_handler/build.pl 编译android_krait_signal_handler
貌似最新版上面的submodule和变异krait都不需要了。
然后去 ./external/buildscripts/build_runtime_android.sh
就可以编译出arm下的libmono.so
如果运行 ./external/buildscripts/build_runtime_androidx86.sh的话,编译出的是x86架构的android。
目前存在的问题是编译出来的libmono.so文件大小为8.3M 而unity提供的为3.3M,不知道怎么减小这个大小。
这个问题还有待探究;
关于这个尺寸的,已经研究出结果。 由于打包了debug版本,和没有优化,导致的。
具体修改方法:
cflags中的 -g参数去掉,加入 -Os参数。这样打出来的libmono.so只有3M左右,比较好用。
编译libmono.so 的时候要注意版本。默认的unity-staging编译出来是最新的 unity5.0使用的。要切换到对应版本。切换的方法使用 git checkout "版本".
为了节省编译时间,android的编译,可以不编译v5,v6.
如果使用64位系统的话,先安装32位开发库.
编译的时候,有可能需要下载安装ADK和NDK,最好在能翻墙的机器上处理