【Unity】防反编译之windows平台加密dll

功能取决于需求,在实现这功能之前,却有一个小小的插曲,有同学认为,并不需要去实现游戏加密,再怎样也会被破解,何必浪费精力。虽然这样说,但是我们所做的加密至少也会增加一点破解成本,不会让我们辛苦写的代码随意被人恶意修改。

下面就看看unity在windows平台中防反编译加密dll的实现步骤吧,unity在打包后,会将所有的代码打进一个Assembly-CSharp.dll的文件里面,通过这个文件的反编译,就是详细看见里面的代码内容。我们需要做的就是将这个dll文件加密,让其无法被人反编译出来。其实网上已有很多的关于unity安卓包的加密教程,但是为了让大家在windows平台加密dll少踩一些坑,还是要给大家介绍下unity防反编译的方法。参考链接:http://www.cppcourse.com/u3d-encryption.html

1.反编译测试

先安装一个反编译的工具.NET Reflector,可以在网上轻易找到。然后在通过这个工具打开我们之前一个测试包的Assembly-CSharp.dll,如下图所示,我们是可以完全看到我们所写的内容,这正是我们不想看到的结果。

2.mono源码下载

因为我们准备加密Assembly-CSharp.dll,但是不论我们使用什么加密方法,Assembly-CSharp.dll的文件就肯定有了变化,我们发布的程序就无法正常运行了。于是我们需要在加载Assembly-CSharp.dll文件时,对其解密,让它正常运行。好在unity基于开源的mono,我们只需要在mono里面添加一个解密步骤,再编译,替换掉之前没有解密步骤的mono,就能达到我们的目的。

mono下载链接:https://github.com/Unity-Technologies/mono

mono项目中,我们根本所使用的版本找到自己所需要的分支,我这里使用的时候unity5.5版本,于是我直接切换到unity-5.5的分支,至于下载方式,使用git或者直接打包zip都可以。

【Unity】防反编译之windows平台加密dll_第1张图片

3.mono添加解密

参考文章使用xxtea加密算法,于是我们也可以使用这个算法,来做我们的加密程序。有兴趣可以,单独查查相关的算法,我直接给下我们所需要的两个版本的链接,下载下来就可以了。c版用于mono解密添加,.net版用于unity加密添加,后面会详细说明。

c版xxtea算法:https://github.com/xxtea/xxtea-c

.net版xxtea算法:https://github.com/xxtea/xxtea-dotnet

在下载好xxtea后,复制xxtea.c和xxtea.h两个文件到开始下载的mono的源码里,具体位置在mono/mono/metadata文件夹下。

然后再用vs2010打开mono/msvc/mono.sln,将上面的xxtea的两个文件添加到libmono里,并找到libmono下的image.c,添加xxtea的头文件。

【Unity】防反编译之windows平台加密dll_第2张图片

然后再找到mono_image_open_from_data_with_name函数,这个函数就是mono去加载Assembly-CSharp.dll的入口,也就是说我们需要在这里添加我们说需要的解密函数。因为这里是针对unity的程序加密,我们完全可以针对单个名称来找到dll。对于xxtea加密的使用方法在github已经很清楚了。

【Unity】防反编译之windows平台加密dll_第3张图片

4.mono再编译

根据参考文章的建议我们需要执行以下步骤,有人会纳闷为什么不使用vs2010或者其他方式编译,我试了很多,并没有成功。如果有人用任何其他方式编译成功,希望可以让我知道。

【Unity】防反编译之windows平台加密dll_第4张图片

我这里用了54秒就编译成功,不错不错,生成的dll位置在mono\builds\embedruntimes\win64,同时建议在编译的时候,最好将32与64位的dll文件,你后面多半都会使用到的。

【Unity】防反编译之windows平台加密dll_第5张图片

5.unity打包加密插件

对于怎样加密我们发布的unity程序更方便,我想过写一个外部工具,来加密发布后的程序,这样也是可以的。但是我也可以把加密写成了unity的一个小小插件,可以同步打包加密,免得再去打开另一个工具,万一忘了加密怎么办。

这个插件的功能非常简单,打包unity程序-->加密Assembly-CSharp.dll-->替换掉打包程序的mono.dll。

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

[MenuItem("Build/win x86")]

   static void BuildWindows_x86()

   {

       BuildWindows(BuildTarget.StandaloneWindows);

   }

   [MenuItem("Build/win x64")]

   static void BuildWindows_x64()

   {

       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);

 

       int num = path.LastIndexOf("/");

       path = path.Substring(0, num);

       EditorPrefs.SetString("BuildPath", path);

       EditorUtility.OpenWithDefaultApp(path);

   }

   #endregion

 

在下面我就是使用到了开始下载的.net版的xxtea,对Assembly-CSharp.dll进行加密,并针x86和x64替换掉对应有解密步骤的mono.dll,这里有一个小技巧,因为我们插件在unity工程里面,它对mono.dll会有报错,于是我们直接更改了其后缀名,让unity放弃去读取这两个dll文件。反正我只需要这两个文件的内容重写在打包的mono.dll里。

【Unity】防反编译之windows平台加密dll_第6张图片

然后点击工具栏的Build/win x86或者Build/win x64就可以直接打包加密程序了。

【Unity】防反编译之windows平台加密dll_第7张图片

6.成果测试:

下面就是用.Net Reflector打开的Assembly-CSharp.dll,它已经不再可读了,好像已经达到我们的需求了。

【Unity】防反编译之windows平台加密dll_第8张图片

然后再运行游戏的exe,是可以正常的运行,windows平台加密的暂时算完结了。

 【Unity】防反编译之windows平台加密dll_第9张图片

你可能感兴趣的:(Unity)