转载自:http://blog.csdn.net/glunoy/article/details/62231825
加密Unity的windows版本Assembly-CSharp.dll的实现
原创 2017年03月15日 17:28:15 标签:Unity3d 1755
参考文章:
http://www.cppcourse.com/u3d-encryption.html
http://www.cnblogs.com/lixiang-share/p/5979981.html
1.先到https://github.com/Unity-Technologies/mono 下载版本对应的分支。我的是https://github.com/Unity-Technologies/mono/tree/unity-5.5
2.解压文件,进入msvc文件夹,可以看到它的工程目录用的是vs2010. 为了避免各种问题,我们也使用VS2010来编译。
3.选择Release_eglib,执行编译。不一会,编译成功。先不要急着搞什么加密代码。用此mono.dll 替换你生成的exe下的xx_Data/Mono/mono.dll
如果运行不成功,说明你下到了错误的分支。运行成功继续步骤4.
4.先到以上参考文章中提到的xxtea中下载源码。创建任意控制台程序并加入此xxtea.c xxtea.h编写如下程序。
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "xxtea.h"
#define SIZE 1024*1024*10
int Decrypt()
{
FILE *infp = 0;//判断命令行是否正确
if ((infp = fopen("Assembly-CSharp_encrypt.dll", "rb")) == NULL)
{
printf("Assembly-CSharp.dll Read Error\n");//打开操作不成功
return 0;//结束程序的执行
}
//char buffer[SIZE];
char* buffer = (char*)malloc(sizeof(char)*SIZE);
memset(buffer, 0, sizeof(char)*SIZE);
int rc = 0;
int total_len = 0;
total_len = fread(buffer, sizeof(unsigned char), SIZE, infp);
printf("Read Assembly-CSharp Successfully and total_len : %d \n", total_len);
//加密DLL
size_t len;
char* key = "123456";
char *decrypt_data = (char*)xxtea_decrypt(buffer, total_len, key, &len);
printf("Encrypt Dll Successfully and len : %d\n", len);
//写Dll
FILE* outfp = 0;
if ((outfp = fopen("Assembly-CSharp_decrypt.dll", "wb+")) == NULL)
{
printf("Assembly-CSharp_encrypt.dll Read Error\n");//打开操作不成功
return 0;//结束程序的执行
}
int rstCount = fwrite(decrypt_data, sizeof(unsigned char), len, outfp);
fflush(outfp);
printf("Write len : %d\n", rstCount);
fclose(infp);
fclose(outfp);
free(buffer);
free(decrypt_data);
}
int main() //命令行参数
{
FILE *infp = 0;//判断命令行是否正确
if ((infp = fopen("Assembly-CSharp.dll", "rb")) == NULL)
{
printf("Assembly-CSharp.dll Read Error\n");//打开操作不成功
return 0;//结束程序的执行
}
//char buffer[SIZE];
char* buffer = (char*)malloc(sizeof(char)*SIZE);
memset(buffer, 0, sizeof(char)*SIZE);
int rc = 0;
int total_len = 0;
total_len = fread(buffer, sizeof(unsigned char), SIZE, infp);
printf("Read Assembly-CSharp Successfully and total_len : %d \n", total_len);
//加密DLL
size_t len;
char* key = "123456";
char *encrypt_data = (char*)xxtea_encrypt(buffer, total_len, key, &len);
printf("Encrypt Dll Successfully and len : %d\n", len);
//写Dll
FILE* outfp = 0;
if ((outfp = fopen("Assembly-CSharp_encrypt.dll", "wb+")) == NULL)
{
printf("Assembly-CSharp_encrypt.dll Read Error\n");//打开操作不成功
return 0;//结束程序的执行
}
int rstCount = fwrite(encrypt_data, sizeof(unsigned char), len, outfp);
fflush(outfp);
printf("Write len : %d\n", rstCount);
fclose(infp);
fclose(outfp);
free(buffer);
free(encrypt_data);
//test decrpyt
{
Decrypt();
}
return 0;
}
5.编译,并将要加密的Assembly-CSharp.dll 放到生成的exe目录下,执行双击。 OK 现在你可以看到有
Assembly-CSharp_decrypt.dll
Assembly-CSharp_encrypt.dll
使用任意文件对比工具,检查
Assembly-CSharp.dll
Assembly-CSharp_decrypt.dll
完全匹配。OK。说明加密解密均没问题。
6.切换回mono源码目录 将xxtea.c xxtea.h放入mono-unity-5.5\mono\metadata 下,并将2个文件加入工程。
7.打开mono-unity-5.5/mono/metadata/image.c
加入如下2行代码
#include <stdlib.h>
#include "mono/metadata/xxtea.h"
定位到mono_image_open_from_data_with_name
在data检查是否为空 return null的下面 加入
if(strstr(name ,"Assembly-CSharp.dll")){
char* key = "123456";
size_t len;
char* decryptData = (char*)xxtea_decrypt(data , data_len, key, &len);//换成对应的解密函数
int i = 0;
for ( i = 0; i < len; ++i)
{
data[i] = decryptData[i];
}
g_free(decryptData);
data_len = len;
}
OK,编译。mono-unity-5.5\builds\embedruntimes\win32 下的mono.dll 替换掉我们的xx_Data/Mono/mono.dll。将上文生成的Assembly-CSharp_encrypt.dll,改名Assembly-CSharp.dll覆盖掉xx_Data\Managed\Assembly-CSharp.dll
运行游戏,可以看到稍微卡了一下,然后游戏正常执行。至此加密完毕。
==========================这是用于商业游戏的情况下加密源码======================
本人希望各位兄弟前辈们积极开源一些不重要的工程,方便后来人提高技术,这样才有良好的技术环境。
这也是撰写本文的初衷。谢谢大家