赞
踩
Uinty3D打包应用之后总是让人头疼,所有的代码都会在/…_Data/Managed/Assembly-CSharp.dll文件中,而这个dll文件很容易被反编译,反编译之后自己辛苦的劳动成果被人随意窃取和利用,心里总归不舒服,所以我们需要加强自身的反破解能力,虽然这世上没有破解不了的东西,这里做的只是让破解的人付出点代价而已,最好是气血上涌,两眼发黑,然后砸电脑。
文章参考了大量的前人文章,在这里当作笔记记录下,希望能帮到同样想加密的小伙伴
参考文章1:https://blog.csdn.net/swj524152416/article/details/69946259
参考文章2:https://blog.csdn.net/a958832776/article/details/73548597
这里要加密程序代码就是不让电脑正常读取Assembly-CSharp.dll,电脑读取的文件是以字节流的形式存在于电脑中,所以加密只需要对这个文件的字节流加密,保存到Assembly-CSharp.dll文件中,不管使用什么方式加密,dll文件肯定有所变化,程序无法正常读取,也就是无法正常运行,Unity是基于开源的Mono,只需要在Mono读取的时候解密dll文件就行了,由于我们使用了加密的方式,所以必须在Mono里面添加一个解密步骤,再编译,替换掉之前没有解密步骤的mono,
Mono源码下载链接:https://github.com/Unity-Technologies/mono
根据所使用的unity版本,下载相对应的Mono源码。
也可以滑到下方找对应的unity版本,每个Unity版本都包含两个版本的Mono。一个旧版本(Mono)嵌入到编辑器和播放器中。另一个新版本(MonoBleedingEdge)用于运行工具和测试。此MonoBleedingEdge版本可通过启用实验性播放器设置在编辑器和播放器中使用。
Mono解压后:红框是需要操作的文件夹
参考文章使用xxtea加密算法,若是有代码加密算法能力的也可以自己编写加密算法,我是没有这个能力,这里依然使用这个算法,这里直接给出下载链接
C语言版本xxtea算法:https://github.com/xxtea/xxtea-c
.net版本xxtea算法:https://github.com/xxtea/xxtea-dotnet
C语言版本用于重编译Mono时解密,.net版本用于unity加密
在下载好xxtea后,复制xxtea.c和xxtea.h两个文件到开始下载的mono的源码里,具体位置在mono/metadata文件夹下。
然后再用vs2010打开msvc/mono.sln,将上面的xxtea的两个文件添加到libmono里,并找到libmono下的image.c,添加xxtea的头文件。这里我添加之后,上面的#include <config.h> 会有红线,这里对于有强迫症的我非常想解决掉,可又不懂C的我,最后放弃了,最后发现,就算出现红线,最后还是能够编译成功,所以不用担心
然后Ctrl+F搜素mono_image_open_from_data_with_name函数,这个函数就是mono去加载Assembly-CSharp.dll的入口,需要在加载的时候添加解密方法,因为这里是针对unity的程序加密,大佬们是针对单个名称来找到dll。
- if (!data || !data_len) {
- if (status)
- *status = MONO_IMAGE_IMAGE_INVALID;
- return NULL;
- }
-
- //Decrypt
- if (strstr(name, "Assembly-CSharp.dll") != NULL)
- {
- const char *key = "Test"; //这里是密钥
- data = (char*)xxtea_decrypt(data, data_len, key, &data_len);//在这里解密
- }
-
- datac = data;//解密之后把解密后的代码数据赋值给datac
首先设置libmono为启动项,配置选Release_glib,到此为止,需要修改的地方已经完成,保存之后,找到vs2010的命令提示窗口编译解密mono.dll,
使用vs2010的命令提示窗口编译解密mono.dll时,建议32位和64位各编译一个,编译之后备用,若是加密方式不变,就不用每次都编译解密mono.dll
为什么用VS2010,资料显示unity使用的是2010版本的,至于其他版本大佬们都没有测试成功,各种错误,我也不懂C,所以放弃了修改,还是乖乖使用大佬的方式
1、使用命令行窗口执行mono.sln
注:经测试在选择编译命令工具编译Dll文件的时候,选择带 X64的兼容工具命令提示 编译的始终是64位Dll
选择不带 X64的兼容工具命令提示 编译出来是32位的Dll
2、首先进入 解压目录/msvc,mono.sln存放的文件夹位置,
3、执行 msbuild.exe mono.sln /p:Configuration=Release_eglib
编译的时候什么都不用操作,耐心等待完成就可以
打包之后的mono.dll保存在buildsàembedruntimesà(win64/win32),使用的时候只需要选择对应的dll即可。
解码mono.dll准备好之后,开始Unity配置:参考大佬文章,先创建编辑器菜单打包。
在使用的时候先把下载的.net版本的xxtea导入到unity中,对unity编辑器操作需要把代码文件放到Editor文件夹中,并且引用命名空间:using UnityEditor;
- //创建编辑器菜单
- [MenuItem("Build/win x86")]
- static void BuildWindows_x86()
- {
- //编译32位程序
- BuildWindows(BuildTarget.StandaloneWindows);
- }
-
- [MenuItem("Build/win x64")]
- static void BuildWindows_x64()
- {
- //编译64位程序
- BuildWindows(BuildTarget.StandaloneWindows64);
- }
-
- #region windows打包
- static void BuildWindows(BuildTarget _bt)
- {
- string path = EditorUtility.SaveFilePanel(_bt.ToString(), EditorPrefs.GetString("BuildPath"), PlayerSettings.productName, "exe");
- if (string.IsNullOrEmpty(path))
- return;
-
- BuildPlayerOptions _buildOptions = new BuildPlayerOptions();
- _buildOptions.locationPathName = path;
- _buildOptions.scenes = EditorBuildSettingsScene.GetActiveSceneList(EditorBuildSettings.scenes);
- _buildOptions.target = _bt;
- BuildPipeline.BuildPlayer(_buildOptions);
-
- //加密
- EncryptAssemblyCSharp(path);
-
- //替换解密mono.dll
- ReplaceMonoDll(path, _bt);
-
- Debug.Log("打包路径:"+path);
- int num = path.LastIndexOf("/");
- path = path.Substring(0, num);
- EditorPrefs.SetString("BuildPath", path);//编辑器模式下,存储打包路径
- EditorUtility.OpenWithDefaultApp(path);
- }
- #endregion
-
- //XXtea加密
- static void EncryptAssemblyCSharp(string path)
- {
- string acsPath = path.Replace(".exe", "_Data") + "/Managed/Assembly-CSharp.dll";
- byte[] _readByte = File.ReadAllBytes(acsPath);
- string key = "Test";//测试密钥,需要和解密密钥相同
- byte[] encypt_data = Xxtea.XXTEA.Encrypt(_readByte, key);
- File.WriteAllBytes(acsPath, encypt_data);//把加密后的代码流数据保存到dll文件中
- }
-
- //替换为含解密的mono.dll
- static void ReplaceMonoDll(string path, BuildTarget _bt)
- {
- string _mdPath = path.Replace(".exe", "_Data") + "/Mono/EmbedRuntime/mono.dll";
- byte[] _readByte = File.ReadAllBytes( "D:/Plugins/mono.dll");//把解密dll文件读取到电脑,写入程序中的dll中。
- File.WriteAllBytes(_mdPath, _readByte);
- }
保存之后编辑器界面会出现Build菜单,选择相对应的程序进行打包。
打包之后使用反编译工具测试,无法读取dll中的代码。
运行程序成功。我使用的2017.2的unity版本,unity高版本没有了mono.dll,有一个mono-2.0-bdwgc.dll,应该是版本升级,高版本的mono源码没有编译成功。把mono.dll的数据流读出来保存到mono-2.0-bdwgc.dll中,测试无法使用。
2017.2 运行成功
2018.3 mono.dll
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。