Protect Your Godot Game
Table of Contents
由于godot的开源,逆向变得易如反掌,本文会提供一些保护的方案
#
前言
阅读本文你需要一定的 Godot 开发基础
使用 Table Of Contents 快速跳转到你想看的内容
永远没有绝对安全的保护,唯一能做的只有增加逆向成本
#
基本知识
##
游戏根目录
Example.console.exe -- Debug独有,启动游戏的同时会启动控制台
Example.exe -- 类似于缩减版的godot游戏引擎,只有运行游戏的功能
Example.pck -- 存储着你项目目录的所有文件
由此可见,Godot 的逆向十分简单,只要逆向 .pck 文件即可获得完整的项目,使用 gdsdecomp 可以还原出完整的项目
##
C# 和 GDScript
GDScript 是 Godot 开发的编程语言
Godot 可以同时使用 C# 和 GDScript 编程,两者在使用时差别不大,性能差距可以忽略,GDScript 更全能一些,C# 目前还不支持 Android 平台
另外,GDScript 在运行时不会被编译,C# 会被编译。GDScript 在运行时会被 GDScript VM 调用并直接执行
#
基础防护
##
PCK 密钥
这种是官方的加密方法,逆向相对简单,以下是操作方法
-
配置环境
-
安装 Git
-
安装 Python
-
安装 Scons
pip install scons -
安装 llvm-mingw ,下载 msvcrt-x86_64.zip,添加 bin 到环境变量
-
-
生成密钥
-
下载 openssl
-
使用
openssl rand -hex 32生成密钥 如f91476533bd554c408e3d03ec634da97ee5e6ccae009dc8062dd39cbd23fa3fc -
保存好这个密钥
-
-
获取源码
-
git clone https://github.com/godotengine/godot.git -
选择对应的版本
git checkout tags/4.2-stable
-
-
构建导出模板
-
在源码根目录打开cmd,输入
set SCRIPT_AES256_ENCRYPTION_KEY=你的key -
如果不需要 C# 功能:
scons platform=windows target=template_release如果需要 C#:
scons platform=windows target=template_release module_mono_enabled=yes在命令后添加 -j 即可多线程编译,如 -j32 就是32线程
-
等待构建结束,结束后在 /bin 会有以下两个文件
godot.windows.template_release.x86_64.console.exe godot.windows.template_release.x86_64.exe如果需要debug模式,则需要另外构建
target=template_debug
-
-
使用构建模板
项目 - 导出 - 添加 - Windows Desktop
选项 - 自定义模板 - 发布 定位到你的
godot.windows.template_release.x86_64.exe加密 - 加密导出的PCK - 加密密钥 填写前面生成的密钥
##
代码混淆
建议使用现成的插件 gdmaim
##
使用 C#
因为目前大部分工具没办法还原完整的 C# 代码,所以使用 C# 是相对安全的选项
#
进阶防护
##
自定义PCK加解密
在 core/io/file_access_encrypted.cpp 中,open_and_parse 负责pck的解密
FileAccessEncrypted::open_andparse(Ref<FileAccess> p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic) {
其中 p_key 是32字节的密钥
你可以在这里对 p_key 进行处理,比如变换其中的字节、二次加密之类的,这样即使 gdke 能读取到密钥,也无法用 gdsdecomp 解包,因为游戏在使用密钥解密时有额外的处理
如果想要更强的保护,我建议在编译 Godot Engine 时就进行混淆,这样逆向时就没办法轻易定位到 open_andparse 这个函数,建议在每个版本发布时都重新进行一次 Godot Engine 混淆,可以保证跨版本时更难进行修改
##
Strip 导出模板
源码里的gdscript::load_byte_code函数负责读取加密后的文件并解密,逆向者可以轻易定位到该函数并找到对应的解密key script_encryption_key。使用strip命令可以消去symbols,增加定位函数的逆向成本
##
删除错误日志输出
即使函数名被strip,字符串还是能被轻易定位,godot的错误日志函数_err_print_error可以泄露当前函数的具体名称,因此可以在构建阶段删除所有错误日志。或者采用更温和的方法,将字符串使用保护器动态加解密,这样既可以保留错误日志也能增加逆向成本
#
购买已有构建
你可以通过Telegram或邮件咨询我,购买我制作的Godot修改版,支持Godot全版本/全平台保护,可直接用于编译项目,无须对已有项目进行修改。支持定制额外功能如网络验证
目前已有功能:
- 非Debug构建不再输出
_err_print_error - 非Debug构建不再输出具体报错信息,出错的函数/文件/行数不会泄露
- 非Debug构建自动将
CoreGlobals::print_error_enabled设置为False - 非Debug构建将自动去除符号信息
- 若开启pck加密,密钥将获得额外的保护
- 脚本加密密钥更难以使用静态工具提取
#
Credits
https://github.com/bruvzg/gdsdecomp
Compiling with PCK encryption key
Protecting Your Godot Project from Decompilation
Protecting Your Godot Project from Decompilation (Web archive)