GameSentry 主要通过分析游戏协议内容、游戏函数逻辑和对应的地址、部分代码热更、自动化 Hook 等功能达到降低深层次安全测试门槛的目的。
该工具的定位是辅助测试人员对 apk 进行逆向、Hook 等,需要使用者有一定的基础,并非全自动一键逆向分析。
如果你也好奇工具是如何对函数、协议内容进行解析的,那就一起看下去吧~
1.IL2CPP 解析
首先,要了解 IL2CPP 如何解析,就需要先了解相关信息以什么格式存在于内存中。以下是 IL2CPP 源码中的部分。
由这些代码可以看到是呈现树状结构的。assembly->class->method
而 unity 中有一些导出函数:
有了以上的信息,我们就可以通过主动调用 unity 的导出函数来对内存进行解析。(以下代码基于 frida js)
仅展示众多导出函数的一部分,此处将所有需要使用的函数进行注册。
根据 assembly、class、method 等结构,调用导出函数进行解析。
使用注意事项
众所周知,unity 的版本很多,各个版本之间存在一定的差异。如果 unity 的导出 API 有一定的改动,或者内存结构被修改,当前工具则无法解析。
解决建议:如果遇到某个版本,某条导出函数不存在,可通过指针+偏移来解决。
示例:unity 版本低于 2018 时,还没有 il2cpp_image_get_class_count 函数,则可以使用 ptr(image).add(p_size * 2 + 4 + 4).readU32() 来实现相同功能。
加固加壳如何应对
解决方案:
保证 lib/component/agent/api.js 中注册的函数能成功注册即可。如果壳有 antifrida,建议先过保护。
2. protobuf 识别
相关资料:
https://developers.google.com/protocol-buffers/docs/reference/csharp/interface/google/protobuf/i-message
由官方 API 可知道所有需要支持 protobuf 序列化的都来自于同一个 interface,所以可以去遍历内存中所有 IMessage 的子类即可获取相关的协议类,再对所有类进行拦截、hook,即可做到在发送协议之前拿到传输协议的相关数据。(还不用关注协议是否加密)
使用注意事项:
由上述原理可知,获取协议需要解析内存结构。当前 Lua 并未实现实时的 Hook,所以如果是在 Lua 中使用的 protobuf 做序列化则暂时无法解析。
解决方案:将 Lua 从内存中 dump 下来分析,比写 Hook 修改难度更低。
3. 结语
本期主要介绍了 IL2CPP 内存解析的原理以及如何过滤 protobuf 类,也介绍了一些工具不太适用的场景以及应对方式。这些不适用的场景后续也会计划兼容。Lua 在游戏开发中也被经常使用,如何使用工具来分析 Lua 呢?
下期将分享 Lua dump 加载,实时修改。
GameSentry 贡献者计划
网易智企“易+”开源计划-网易易盾 GameSentry 游戏安全检测工具开源已于 9 月正式开源,随之而来也开启了开源贡献者计划,邀请广大开发者与我们共创共建,一起维护游戏安全领域。
参考文章(点击链接阅读):
开源贡献者计划旨在鼓励开发者参与到 GameSenrty 的开源建设中,贡献代码或者帮助社区提交和修复 bug,与项目共同成长。欢迎大家加入!