锚点降临是一款由杭州雷焰网络科技有限公司开发的策略游戏。。。

你说得对但是这款于2023年8月11日全平台公测的游戏在PC端使用的是mono而不是il2cpp。。。

使用dnspy打开Assembly-CSharp.dll,导出项目再用Rider或者VS打开(方便查找引用和字符常量)。

Anchor\锚点降临_Data\GameRes\LuaScripts文件夹下有Main.lua文件,推测为lua脚本入口,搜索main可以在Game.cs中找到

private void OnceSetting()
	{
		Thread.CurrentThread.Priority = System.Threading.ThreadPriority.AboveNormal;
		if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer)
		{
			Shader.SetGlobalFloat("_LightmapPowForMobile", 1f);
		}
		Splash.Instance.SetStep("开始Lua Main");
		LuaProxy.Init();
		LuaProxy.CallScript("Main");
		LuaProxy.CallFunction("main", Array.Empty<object>());
	}

一路查看LuaProxy.CallScript("Main");的调用,可以找到下面这个函数

private byte[] DoLoadLua(ref string cusPath)
		{
			byte[] array;
			if (!this.mBytesCache.TryGetValue(cusPath, out array))
			{
				if (ApplicationUtil.IsEditorRun && !FileProxy.CheckLuaPath(LuaUtil.GetPersistentLuaPath(cusPath)))
				{
					Debug.LogError("不存在Lua文件,请检查路径大小写或是否存在:" + LuaUtil.GetPersistentLuaPath(cusPath));
				}
				array = FileProxy.Load(LuaUtil.GetPersistentLuaPath(cusPath));
				if (array == null || array.Length == 0)
				{
					array = FileProxy.Load(LuaUtil.GetStreamingLuaPath(cusPath));
				}
				if (array == null || array.Length == 0)
				{
					throw new Exception("Not exist Lua: " + LuaUtil.GetStreamingLuaPath(cusPath));
				}
				if (LuaModule.IsCache)
				{
					this.mBytesCache[cusPath] = array;
				}
			}
			return array;
		}

FileProxy.Load函数中出现了解密相关信息

public static byte[] Load(string cusPath)
		{
			byte[] array = FileProxy.GetFileByte(cusPath);
			if (ApplicationUtil.IsEditorRun)
			{
				return array;
			}
			byte[] array2 = FileProxy.DecryptBytes(array);
			if (array2 != null && array2.Length != 0)
			{
				array = array2;
			}
			return array;
		}

public static byte[] DecryptBytes(byte[] bytes)
		{
			if (bytes == null || bytes.Length == 0)
			{
				return bytes;
			}
			byte[] result = null;
			try
			{
				result = EncryptUtil.DecryptBytes(bytes, AssetSetting.CommonKey);
			}
			catch (Exception)
			{
			}
			return result;
		}

根据DecryptBytes函数可以看出是DES加密

public static byte[] DecryptBytes(byte[] bytes, string decryptKey)
		{
			if (bytes.Length == 0)
			{
				return bytes;
			}
			byte[] result;
			try
			{
				byte[] bytes2 = Encoding.UTF8.GetBytes(decryptKey);
				byte[] rgbIV = EncryptUtil.mDesMKeys;
				DESCryptoServiceProvider descryptoServiceProvider = new DESCryptoServiceProvider();
				MemoryStream memoryStream = new MemoryStream();
				CryptoStream cryptoStream = new CryptoStream(memoryStream, descryptoServiceProvider.CreateDecryptor(bytes2, rgbIV), CryptoStreamMode.Write);
				cryptoStream.Write(bytes, 0, bytes.Length);
				cryptoStream.FlushFinalBlock();
				result = memoryStream.ToArray();
			}
			catch (Exception ex)
			{
				throw new Exception("DecryptBytes Error: " + ex.Message);
			}
			return result;
		}

其中,key和iv分别由如下字段给出

public static string CommonKey
		{
			get
			{
				if (string.IsNullOrEmpty(AssetSetting.mCommonKey))
				{
					AssetSetting.mCommonKey = "rfizzapj";
					AssetSetting.mCommonKey = MD5Util.GetMD5ByString(AssetSetting.mCommonKey);
					AssetSetting.mCommonKey = AssetSetting.mCommonKey.Substring(AssetSetting.mCommonKey.Length - 8);
				}
				return AssetSetting.mCommonKey;
			}
		}

private static readonly byte[] mDesMKeys = new byte[]
		{
			111,
			151,
			50,
			205,
			123,
			222,
			185,
			45
		};

那么就可以写出对应的解密脚本

import sys
import os
import hashlib
from Crypto.Cipher import DES
from Crypto.Util.Padding import unpad

mCommonKey = "rfizzapj"
mCommonKey = hashlib.md5(mCommonKey.encode()).hexdigest()
mCommonKey = mCommonKey[-8:]
#mDesMKeys = [111, 151, 50, 205, 123, 222, 185, 45]
mDesMKeys = b'\x6f\x97\x32\xcd\x7b\xde\xb9\x2d'

def DecryptBytes(bytes, key) :
    key = key.encode()
    cipher = DES.new(key, DES.MODE_CBC, mDesMKeys)
    decrypted_data = unpad(cipher.decrypt(bytes), DES.block_size)
    return decrypted_data

def DecryptFile(source, target) :
    with open(source, "rb") as f :
        data = f.read()
    decrypted_data = DecryptBytes(data, mCommonKey)
    with open(target, "wb") as f :
        f.write(decrypted_data)

def Decrypt(source, target) :
    if not os.path.exists(target) :
        os.makedirs(target)
    for root, dirs, files in os.walk(source):
        rel_path = os.path.relpath(root, source)
        target_dir = os.path.join(target, rel_path)
        if not os.path.exists(target_dir):
            os.makedirs(target_dir)
        for file in files:
            source_file = os.path.join(root, file)
            target_file = os.path.join(target_dir, file)
            DecryptFile(source_file, target_file)


if __name__ == "__main__" :
    if sys.argv.__len__() < 3 :
        print("Usage: python decrypt.py source target")
        sys.exit()
    source = sys.argv[1]
    target = sys.argv[2]
    if os.path.isdir(source) :
        Decrypt(source, target)
    else :
        DecryptFile(source, target)

以上,又水了一篇文章