大部分的加密方式选择异或加密比较简单

1:xlua 签名和加密 

思路:签名xlua下载提供了签名的工具。加密代码和解密代码使用AB bundle 方式

签名流程:

 xlua 工具目录: \xLua-master\xLua-master\Tools

如何安装lua解释器 lua文件解密工具安卓版_ios

 生成私钥公钥和签名工具放在需要签名的xlua 代码文件同级目录。

文本编辑bat执行下面语句
cd /d %~dp0
@REM  签名后的文件拷贝到LuaSing
rmdir /q /s  LuaSign   

"FilesSignature.exe" "Lua" "LuaSign"

执行后在读取lua代码的地方前添加下述代码:

lua的签名加载方式:
PUBLIC_KEY 从生成的公钥key_ras.pub 双击查看
SignatureLoader sl = new SignatureLoader(PUBLIC_KEY, LoadLuaFile);
LuaEnv.AddLoader(sl);

签名的结果是会在签名的代码开始前加一段文本

Lua 代码的加密方式是外部读取文本流加密,解密是读取lua得到字节流解密

加密部分代码:

string key = "yhjm";
byte[] key_char = System.Text.Encoding.Unicode.GetBytes(key);
 File.Copy(f, newpath, true);
 byte[] bytes = File.ReadAllBytes(newpath);
for (i = 0; i < bytes.Length; i++)
 {
 bytes[i] = (byte)(bytes[i] ^ key_char[i % key_char.Length]);
 }
File.WriteAllBytes(newpath, bytes);

File.Copy(f, newhxpath, true);
File.WriteAllBytes(newhxpath, bytes);

lua部分解密和签名验证代码:

LuaEnv.AddLoader(new SignatureLoader(aabb, (ref string filePath) =>
  {
 string orgPath = filePath;
   byte[] tmpBytes = LuaHelper.Inst.ReadFile(ref filePath);
                   
byte[] key_char = System.Text.Encoding.Unicode.GetBytes("yhjm");
 for (int i = 0; i < tmpBytes.Length; i++)
 {
   tmpBytes[i] = (byte)(tmpBytes[i] ^ key_char[i % key_char.Length]);
 }
  return tmpBytes;
 }));

加密方式可以选择,目前只是简单的处理

2:AB包资源加密

这方式比较简单:

使用自带的方式处理,加密后资源用AssetStudio无法直接查看资源

AB 包打包添加 
BuildPipeline.SetAssetBundleEncryptKey("ssssssssbytes01");

读取AB 包添加
AssetBundle.SetAssetBundleDecryptKey("ssssssssbytes01");

3:so文件的加密

so加密两种方式:一种是通过直接加密so 文件,在读取的路口解密。目前采用加密so映射文件global-metadata.dat,解密是通过在global=metadata.data文件的地方解密,这种方式比较容易实现。

使用HxD Hex Editor工具查看global-metadata.data

如何安装lua解释器 lua文件解密工具安卓版_lua_02

 

如何安装lua解释器 lua文件解密工具安卓版_如何安装lua解释器_03

文件加密:

// test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//


#include <iostream>
#include <sstream>
#include <string>
#include <fstream> 
#include <Windows.h> 

using namespace std;

#define FLUSH_NUM 8

//获取文件长度
int getLeng(char* src)
{

	long l, m;
	ifstream fio(src, ios::in);
	l = fio.tellg();
	fio.seekg(0, ios::end);
	m = fio.tellg();
	return m - l;
}
// 加密 文件
void copyFile(const char* src, const char* dst)
{

	char a[5] = "hxhz";
	unsigned char b = (unsigned char)a;
	ifstream in(src, ios::in | ios::out | ios::binary);

	if (!in.is_open()) {
		cout << "error open file " << src << endl;
		exit(EXIT_FAILURE);
	}
	char *bytes;
	int length_ = getLeng((char*)src);
	bytes = (char *)malloc(length_);

	in.read(bytes, length_);
	//读取字节流 异或加密
	for (int i = 0; i < length_; i++)
	{
		bytes[i] = bytes[i] ^ a[i % 5];
	}
	int totalBytes = 0;

	in.close();

	ofstream out(dst, ios::binary);
	if (!out.is_open()) {
		cout << "error open file " << dst << endl;
		exit(EXIT_FAILURE);
	}
	out.write(bytes, length_);



	out.close();
}

//得到执行路径
string GetProgramDir()
{
	wchar_t exeFullPath[MAX_PATH]; // Full path 
	string strPath = "";

	GetModuleFileName(NULL, exeFullPath, MAX_PATH);
	char CharString[MAX_PATH];
	size_t convertedChars = 0;
	wcstombs_s(&convertedChars, CharString, MAX_PATH, exeFullPath, _TRUNCATE);

	strPath = (string)CharString;    // Get full path of the file 

	int pos = strPath.find_last_of('\\', strPath.length());
	return strPath.substr(0, pos);  // Return the directory without the file name 
}

int main()
{
	//获取编译路径  和global-metadata.dat 同一级目录可以直接执行
	string  path = GetProgramDir();
	string rel = (std::string(path) + string("/global-metadata.dat"));
	cout << rel << endl;
	copyFile(rel.c_str(), rel.c_str());

}

解密方式:

需要修改编辑器代码:

unity 安装路径:

unity\Editor\Data\il2cpp\libil2cpp\vm   对应  MetadataLoader.cpp

unity\Editor\Data\il2cpp\libil2cpp\utils  对应      MemoryMappedFile.cpp

修改的地方 MetadataLoader.cpp:

void* il2cpp::vm::MetadataLoader::LoadMetadataFile(const char* fileName)
{

	
	std::string resourcesDirectory = utils::PathUtils::Combine(utils::Runtime::GetDataDir(), utils::StringView<char>("Metadata"));

	

	std::string resourceFilePath = utils::PathUtils::Combine(resourcesDirectory, utils::StringView<char>(fileName, strlen(fileName)));

	

#if __ENABLE_UNITY_PLUGIN__
	if (g_get_global_metadata != 0 && fileName[1] == 'a')
	{
		return g_get_global_metadata(resourceFilePath.c_str());
	}
#endif // __ENABLE_UNITY_PLUGIN__
	int error = 0;
	os::FileHandle* handle = os::File::Open(resourceFilePath, kFileModeOpen, kFileAccessRead, kFileShareRead, kFileOptionsNone, &error);
	if (error != 0)
	{
		utils::Logging::Write("ERROR: Could not open %s", resourceFilePath.c_str());
		return NULL;
	}
	int64_t length = 0;
	int error2 = 0;
	length = os::File::GetLength(handle, &error2);
	void* fileBuffer = utils::MemoryMappedFile::Map(handle);
	
	os::File::Close(handle, &error);
	if (error != 0)
	{
		utils::MemoryMappedFile::Unmap(fileBuffer);
		fileBuffer = NULL;
		return NULL;
	}
//添加的部分
	char *data = (char*)malloc(length);
	memcpy(data, fileBuffer, length);//拷贝	
//解密返回
	void* result= utils::MemoryMappedFile::DecryptFile(data, length);
	
	return (void*)result;  返回解密的结果

	
}

修改MemoryMappedFile.cpp

如何安装lua解释器 lua文件解密工具安卓版_lua_04

添加的部分	 
//混淆文件的字节 返回解密结果
	void* MemoryMappedFile::DecryptFile(char* data, int64_t length)
	{
		char *result;
		result = (char*)malloc(length);
		char a[5] = "hxhz";
		for (int i = 0; i < length; i++)
		{
			result[i] = data[i] ^ a[i%5];
		}
		return result;
	}

4:dex加密

参考文章:

原理和流程都有,也是用过这个方式实现项目dex的加密和解密。保持一个疑问,就是Android版本问题,提供的接口可能不存在,需要多版本测试。

基本看文章就可以实现。下面只是做些补充:

如何安装lua解释器 lua文件解密工具安卓版_ios_05

 

如何安装lua解释器 lua文件解密工具安卓版_lua_06

5:Java 混淆       

Android自带的混淆方式

如何安装lua解释器 lua文件解密工具安卓版_ios_07

 

如何安装lua解释器 lua文件解密工具安卓版_如何安装lua解释器_08

 gradle.properties添加android.enableR8 =true



工具:AssetStudio,HxD Hex Editor ,apktool,ILSpy,IDA ,dex2jar,il2cppdumper