Unity 手游加固验证 Checklist:拿到包对着跑,命令 + 判据一次给全

19 阅读3分钟

这份清单用来验证一件事:你的 Unity 包加固、混淆、资源加密到底到没到位。不讲原理,每一项直接给“跑什么命令 + 输出长什么样算过”,拿到包对着跑一遍就有结论,建议先收藏。开始前先对一下指纹,确认手里这个包就是要上架那版:调试包常关加固,渠道包各自单独打,包错了后面全白验。

一、命令速查表

验证项怎么测结果分档
DEX 混淆JADX 看命名、调用、敏感值直接可读 / 需追调用 / 关键逻辑已保护
SO 代码与符号readelf -Snm -Dstrings 配反编译抽查直接恢复 / 需要定制 / 需运行时还原
IL2CPP metadataIl2CppDumperglobal-metadata.dat,裸包对照默认恢复 / 定制后恢复 / 需运行时取数据
资源文件xxd 看头,dd 抽 body 中段用 ent 测多段熵直接导出 / 修复后导出 / 需跟踪解密
防篡改无害改动后重打包、重签名正常运行 / 客户端发现 / 服务端联动处置
反调试与 HookFrida 分别测 spawn 和 attach默认接入 / 定制后接入 / 需先绕检测

SO 层可以先跑这几条:

readelf -S -W libxxx.so                # .text 只剩十几字节 = 代码被搬走
nm -D --defined-only libxxx.so         # 还剩 xxxSDKInit 明文名 = 只做了改名级
strings -n 8 libxxx.so | grep -iE 'https?://|/api/|secret|token'

IL2CPP 项目再多一步:把 libil2cpp.soglobal-metadata.dat 丢 Il2CppDumper,看 dump.cs 里是 AddGoldPlayerController 这种可读名,还是 a1method_12345。前者说明名字没藏住,等于白加。

二、三个最容易记错的判定

  1. 裸包对照。Il2CppDumper、AssetStudio 报错别当“加密生效”,版本、参数不对都会崩。先拿没加固的裸包确认工具本身能跑,再测目标包。
  2. 别只看文件头。bundle 的 magic 变了不代表 body 加密了,有的处理只换 magic、正文没动。抽 body 中段测熵才作数:
dd if=res.bundle bs=64k skip=4 count=1 2>/dev/null | ent | grep Entropy
# 熵贴近 8.0 = 真加密;明显偏低 = 只加了个壳
  1. 脏测试机。root + 默认 Frida 上检测响了,只证明它拦了默认特征,换台干净机器改下特征可能就穿了。

三、塞进 CI,别只上线前跑一次

手动跑一遍能查出问题,但扛不住回归——Unity 升版本、有人临时关了加密没打开、多个渠道包单独打,都可能让某层悄悄退回去。把关键判定挂进构建流水线:

# 构建产物上跑,命中即 fail,别让明文进正式包
grep -aqE 'https?://internal|SECRET_KEY|/api/pay' libil2cpp.so && exit 1
[ "$(xxd -l4 -p global-metadata.dat)" = "af1bb1fa" ] && { echo 'metadata 未加密'; exit 1; }

# 回归基线:每版本存下来,逐版本 diff
nm -D libil2cpp.so | grep -c ' T '     # 导出函数数
sha256sum libil2cpp.so global-metadata.dat

符号数悄悄涨回去、原来 dump 不出的现在能出,diff 一眼就看出来,不用等破解包冒头才知道。

把这套写成脚本挂进 CI,比上线前手动跑一遍靠谱得多。完整逐层说明在字节暗面主站《Unity 加固怎么验》里。