前言:之前有个活,需要将公司的unity程序进行加密。本来想使用混淆插件进行简单的混淆,后来发现有问题所以选择dll加密。期间碰到很多坑,记录一下。
参考https://blog.csdn.net/kitok/article/details/72472142 对unity打出来的dll进行进行字节进行修改或偏移。
1)打包获取dll
2)编写代码将dll加密
参考https://blog.csdn.net/kitok/article/details/72472142的代码
void encrypt(char* oldName, char* newName, char* key)
{
FILE* infp = 0; //原代码为FILEFILE 编译报错
if ((infp = fopen(oldName, "rb")) == NULL)
{
printf("%s Read Error\n", oldName);//打开操作不成功
return;//结束程序的执行
}
//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 %s Successfully and total_len : %d \n", oldName, total_len);
//加密DLL
size_t len;
char* key = "123456"; //此处位密钥。可自由更改
char* encrypt_data = xxtea_encrypt(buffer, total_len, key, &len);//原代码为charchar 编译报错
printf("Encrypt Dll Successfully and len : %d\n", len);
//写Dll
FILE* outfp = 0;
if ((outfp = fopen(newName, "wb+")) == NULL)
{
printf("%s Read Error\n", newName);//打开操作不成功
return;//结束程序的执行
}
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);
}
void main()
{
encrypt("Assembly-CSharp.dll", "encryptDLL/Assembly-CSharp.dll", "123456");
}
通过下载的gcc进行编译,在对应路径(脚本路径)中打开cmd。其实只要能编译c的软件都行,我觉得dev-c和vs应该都可以。
gcc xxtea.c EncryptManage.c –o EncryptManage
使用:运行EncryptManage.exe 针对同目录下的指定文件进行加密
gcc安装:百度 windows gcc 安装。
3)在mono代码中实现解密
加密过程其实挺简单,此时通过一些反编译软件已经不能查看dll代码了。坑点大部分都在解密过程。
1.需要下载unity的mono工程,进行编译
unity使用的mono Github地址:https://github.com/Unity-Technologies/mono
在从GitHub上clone一份对应版本的mono到本地,注意:此时克隆默认是主分支,但是每个版本有各自的分支需要进行克隆分支的指定。
此时又会出现一个问题:从GitHub上clone会很慢,甚至超时报错。可以网上搜索解决方案(改hosts或者使用代理)。
我的方案:使用代理软件+git添加代理
设置代理:git config --global http.proxy "socks5://127.0.0.1:1080" //此地址是代理软件的本地sock代理地址
git config --global https.proxy "socks5://127.0.0.1:1080"
取消代理:git config --global --unset http.proxy
git config --global --unset https.proxy
同时我又出现一种问题:报错fatal: unable to connect to github.com
原因:
需要用https才能读到数据
解决方法:输入命令
git config --global url."https://".insteadOf git://
进一番折腾终于把工程拉下来了。但是又有个问题,有些文件没有clone下来,拉下来了但没完全拉下来。(都是external目录下的文件)
原因:项目中external都是引用了其他仓库。Git中submodule功能。
解决:clone时勾选Recursive。或者clone后submodule updates(建议也勾选Recursive,有引用中再引用的情况)。
经过几次验证终于,本地文件和远程文件一摸一样了。如果编译报错大概率就是文件不一致,出现代码报错
此时使用vs打开编译进行验证,我是使用的vs2019同时升级编译器、windows sdk。
之前使用过vs2015出现问题:“__func__”: 未声明的标识符
搜索发现好像是有些版本的vs编译器不支持这个宏定义
验证:通过vs2019打开\msvc\mono.sln,然后选择生产release+x64版本的dll。生成后没有报错或者是无关紧要的报错,就成功了。\msvc\build\bdwgc\x64\bin\Release目录中会有一个mono-2.0-bdwgc.dll(大小4-6M,版本不同大小不同)。
成功后开始修改代码:参考https://blog.csdn.net/kitok/article/details/72472142
改完代码编译完成后就得到了一个可以解密我们加密的dll的mono dll。
此时将加密后的DLL和可以解密的mono-2.0-bdwgc.dll替换掉已经打包好的里面对应dll。
通过以上步骤就实现了针对unity包进行DLL加密。可以发现加密后的dll无法反编译,同时mono-2.0-bdwgc.dll是c++的dll也很难反编译。
dll**。
此时将加密后的DLL和可以解密的mono-2.0-bdwgc.dll替换掉已经打包好的里面对应dll。
通过以上步骤就实现了针对unity包进行DLL加密。可以发现加密后的dll无法反编译,同时mono-2.0-bdwgc.dll是c++的dll也很难反编译。