Unity游戏防破解方法

0x0 把市面上的非冷门二游全部肘击了一遍,各种加密方法应该是了解的差不多了 0x1 il2cpp 最经典的肯定是往 il2cpp::vm::MetadataLoader::LoadMetadataFile 加料了,拿到fileBuffer以后进行一些额外的解密操作,比如xor,解压,AES解密等等...
Unity游戏防破解方法
Unity游戏防破解方法

0x0

把市面上的非冷门二游全部肘击了一遍,各种加密方法应该是了解的差不多了

0x1 il2cpp

最经典的肯定是往il2cpp::vm::MetadataLoader::LoadMetadataFile加料了,拿到fileBuffer以后进行一些额外的解密操作,比如xor,解压,AES解密等等
global-metadata.dat自己也可以藏某个文件里面,比如藏PE的资源段里面,或者藏mscorlib.dll-resources.dat尾部,方法挺多的

PixPin2026-04-2711-56-17
更进一步的话可以把文件头魔术字抹掉,版本号乱写一个,把全部的Size写0,运行时不依赖这些东西,global-metadata.dat字符串也能加密混淆一下
PixPin2026-04-2711-57-38
Il2CppGlobalMetadataHeader也可以打乱顺序,建议打乱Il2CppGlobalMetadataHeader结构体后往里面塞入垃圾数据干扰分析,数据段也需要打乱顺序
PixPin2026-04-2712-12-24
正常的长这样
PixPin2026-04-2712-15-57
打乱Il2CppGlobalMetadataHeader+打乱数据段顺序长这样
PixPin2026-04-2712-16-29

打乱Il2CppMetadataRegistrationIl2CppCodeRegistrationIl2CppCodeGenModule的结构体,改一下还是能狠狠恶心一下逆向的,AI不太能正确恢复出来

PixPin2026-04-2712-02-44
在二进制层面看大概长这样,
PixPin2026-04-2712-05-36
PixPin2026-04-2712-05-45

FieldInfoPropertyInfoEventInfoIl2CppClass等等也可以打乱顺序,有些字段运行时完全不依赖,但是静态dump需要用到

PixPin2026-04-2712-18-08

C#函数的命名也可以用Bee尽可能混淆以后再编译成native

0x2 il2cpp API

如果买了Unity的源代码,可以直接把launcher,UnityPlayer,Gameassembly全部静态链接成一个主程序,直接解决il2cppAPI暴露的问题
或者参考某三字厂商的方法:
这是原版Unity调用Gameassembly内il2cpp函数的流程,UnityPlayer加载Gameassembly以后用LookupSymbol从导入表里面取到每个il2cppapi的地址,然后放入UnityPlayer内的全局变量里面以供使用

Untitled Diagram.drawio
PixPin2026-04-2712-33-48
加密il2cpp可以这样加密,Gameassembly的导入表只暴露il2cpp_get_table函数,该函数会返回一个固定长度的数组,里面有些是真的il2cppapi地址,有些则是完全没用的垃圾地址,LoadIl2cpp函数不再通过LookupSymbol一个一个解析il2cppapi,而是改成解析il2cpp_get_table传过来的数组,然后逐个填充到对应的全局变量里面(垃圾地址也要填充到全局变量里面,但是这些全局变量没有任何函数会使用它)
image

0x3 InitializeRuntimeMetadata

metadataPointer可以进行一下额外的解密操作,GetStringLiteralFromIndex整个函数里面可以加点xor等额外解密,然后用vmp全部vm掉

PixPin2026-04-2712-44-58
混淆过的差不多长这样
PixPin2026-04-2712-48-40
PixPin2026-04-2712-48-48

0x4 AssetBundle

最基础的玩法肯定是先把ab包读进来,然后进行解密操作,最后用LoadFromStream或者LoadFromStreamAsync把解密好的ab包交给UnityPlayer
如果有源代码,可以根据下面的图进行魔改,解压缩部分可以增加一个魔改过的lz4或者zstd,ReadHeader部分可以把文件头打乱一下顺序,随机xor一些字段等等(我这没源代码,只能从二进制层面提供建议)

image

甚至可以完全丢掉AssetBundle,自己造个VFS,例如一个文件存index,一个文件存data。取对应的文件先对VFS内的路径名称计算hash,然后根据算出来的hash取index里面取到offset和size,然后再去data内拿到需要的部分,这样VFS里面完全没有任何可读的文件名,只有hash

自定义VFS的处理解密可以用Unity插件搞一个dll去处理,也可以写UnityPlayer里面,通过icall调用

0x5 lua字节码/js/hybridCLR

Unity基本上用的是藤子的Xlua
可以改字节码proto的结构顺序

PixPin2026-04-2713-04-07
opcode的顺序也可以进行打乱
PixPin2026-04-2713-05-25
PixPin2026-04-2713-05-51
vm解释器部分也可以加点料
PixPin2026-04-2713-06-24

js好像没见到有人编译成jsc的,这里不讨论

hybridCLR可以往TransformBodyImpl里面加点料,给il字节码xor一下阻止ilspy的反编译

PixPin2026-04-2713-10-11

0x6 网络

proto可以用flatbuffers,flatbuffers的二进制文件内完全没有类型定义,不像protobuf能猜定义,然后可以把flatc生成出来的代码混淆一下
通信也可以魔改KCP,请求也加上ssl pinning
这部分研究的不算多

0xF

感觉加密的玩法也就那几种,以前没AI/AI性能不行的时候,简单的加密一下还是有用的,现在怕是不太行了(

2 个帖子 - 2 位参与者

阅读完整话题

来源: linux.do查看原文