gdsdecomp 深度解析:一条命令从 PCK 恢复 Godot 工程,完整反编译 GDScript 字节码
gdsdecomp 深度解析一条命令从 PCK 恢复 Godot 工程完整反编译 GDScript 字节码【免费下载链接】gdsdecompGodot reverse engineering tools项目地址: https://gitcode.com/GitHub_Trending/gd/gdsdecomp源码丢了.git 目录也没了发行目录里只剩一个 game.pck——这是大多数人需要 gdsdecomp也叫 Godot RE Tools一套 Godot 逆向工程工具的起点。PCK 是 Godot 的资源打包格式本质是把项目全部资源压成一个文件。这个工具做三件事把 PCK、APK 或内嵌包的 EXE 里的资源恢复出来把编译后的 .gdcGDScript 字节码源码编译后的中间形态反编译回 .gd 源码把二进制资源转回文本格式最后得到一个能继续开发的工程。截图是工具的 PCK 浏览器左侧列出包内 81 个文件及各自的 .import 导入状态右侧Decompile GDScript窗口选了几个 .gdc 后即可反编译底部还能切换使用的字节码版本这里选中的是 3.1.0 beta 6。电梯总结gdsdecomp 把编译好的游戏黑盒变回能继续开发的白盒覆盖 PCK 恢复、GDScript 反编译、资源文本化三件事。能救什么项目救不了什么项目能做的README 里写得很直白全项目恢复按顺序执行 6 步从 APK、PCK、或内嵌 PCK 的 EXE 中读取全部项目资源反编译所有 GDScript 脚本覆盖 2.x、3.x、4.x 三代重建原始 project.godot把导入资源转回原始导入格式比如 .stex 转回 .png把二进制资源.res/.scn转回文本格式.tres/.tscn重建插件配置文件。C# 项目也能处理仓库里有一个专门的 godot-mono-decomp/ 子项目负责把 PCK 里的 .NET 程序集反编译成 C# 源码命令行可以用--csharp-assembly指定程序集位置。不能做的README 的 Limitations 一节写死了两条2.x 的模型格式dae、fbx、glb 等转换尚未实现GDNative / GDExtension 原生脚本官方尚未支持。另外两条隐性边界游戏如果用自定义 Godot 版本编译工具检测不出版本恢复日志原话是 Detection for this has not been implemented yet反编译有损注释只能部分还原变量命名、排版这些艺术选择回不来。适合丢了源码想抢救项目的开发者、要快速通读存档/内购逻辑做安全审计的人、想从开源游戏里拆素材学习的人。不适合指望拿到和原始代码逐字一致的人以及 GDExtension 重度项目——这类场景它救不了。第一条命令安装、恢复、读恢复报告Windows 可以直接用 Scoop 装不用碰编译scoop bucket add games scoop install gdsdecomp其他系统直接从官方 Release 页拿最新预编译版。装好后gdre_tools --gdre-help能打印完整参数表下面所有场景用的参数都在里面。现在跑最核心的一条——全项目恢复gdre_tools --headless --recovergame.pck --outputrecovered_project这条命令加载 game.pck自动探测引擎版本和字节码版本批量反编译脚本、转换资源全部写进recovered_project/。跑完会弹出Recovery report窗口headless 模式下同时落盘为 gdre_export.log报告里有三个数字要盯Decompiled scripts成功反编译的脚本数例子里是 9、Failed scripts失败数应为 0、Successfully converted成功转换的资源数。还有一行Use Godot editor version 3.4 to edit the project——按它建议的同版本编辑器打开工程能少一大堆语法报错。 59 个字节码版本版本之间只存差异为什么需要GDScript 字节码格式每隔几个版本就变——token 重新编号、内置函数增删、参数个数调整。一个解析器硬啃所有版本必然出错为每个版本从头写一个又维护不动。项目怎么做misc/bytecode_versions.json 登记了 59 个字节码版本从 1.0-dev1 一直排到 4.5.0-stable每个条目只记相对父版本的增量parent指向前一个节点added_tokens/removed_tokens记录 token 增删renamed_functions记录改名arg_count_changed记录参数变化同时每个版本还带完整的tk_names、func_names全量表供生成解析器。完整编年史见 BYTECODE_HISTORY.md。运行时工具先用文件头与版本特征定位最接近的版本--force-bytecode-version可用提交哈希如f3f05dc或版本号如4.3.0覆盖。遇到没登记的新版本也不用等发布--load-custom-bytecodexxx.json能在会话中直接加载自定义版本定义。这意味着支持新版 Godot 只需要填一张 JSON 差异表而不是移植整个解析器。扁平 token 流重组出 if-for 骨架为什么需要反编译读到的不是一棵语法树而是一条被压平、丢掉缩进结构的线性 token 流必须自己把结构长回去。项目怎么做所有版本解析器都继承 bytecode/bytecode_base.h 里的GDScriptDecomp基类。基类定义了一套GlobalToken枚举G_TK_CF_IF、G_TK_OP_ASSIGN这类把各版本五花八门的 token 名统一成全局语义源码注释里还标着每个版本的名字差异同一个运算符在 4.2 叫TK_PLUS_EQUAL别的版本编号又不一样。每个版本自己的解析器类bytecode/ 目录下一批bytecode_xxxxx.cpp由 bytecode_generator.py 生成只负责版本 token → 全局 token的查表翻译外加查该版本的函数名表与参数表看到G_TK_CF_IF开始 if 块、看到缩进 token 判断层级这类结构重建全部由基类完成。这意味着2.x、3.x、4.x 的反编译器共用同一套重建骨架查的表不同而已加版本是加一张查表不是写一台新反编译器。 两种锁法的 PCK标准密钥与自定义解密脚本为什么需要Godot 官方支持用 32 字节密钥给 PCK 加密AES-256-CFB没密钥或游戏改了加密方案读文件这一步就过不去。项目怎么做标准加密由 crypto/ 处理除了AESContextGDRE还提供CamelliaContext、AriaContext两个上下文都支持 CFB 模式标准方案下你只需要一个 64 位十六进制字符串的--key。非标准方案则留了脚本槽位——虚基类 crypto/custom_decryptor.h写一个 Godot 4.5 的 GDScript 继承CustomDecryptor实现_parse_and_decrypt(file, key, non_pack_file)自己读文件头、自己解密返回{error, length, data}字典func _parse_and_decrypt(file: FileAccess, key: PackedByteArray, non_pack_file: bool) - Dictionary: var iv file.get_buffer(16) var data _decrypt(file.get_buffer(length), key, iv) return {error: OK, length: data.size(), data: data}脚本路径通过--custom-decryption-script传入或 GUI 的 Set Encryption Key 菜单里设置。标准方案的完整实现在 docs/gdre_standard_encryption.gd 里可以直接当模板抄类参考文档见 docs/custom_decryptors.md。这意味着工具自带钥匙胚每款游戏自己的壳社区都能不改主程序源码、只插一个脚本适配。三个实战跑法全量、只抽脚本、只取资源目标关键参数输出目录里得到什么全量恢复最常用--recover包 --output目录project.godot、.gd 脚本、文本化资源、插件配置只审计逻辑追加--scripts-only只有 .gd秒级完成只取部分资源追加--includeres://…若干仅匹配文件被恢复加密包追加--key64 位 hex或--custom-decryption-script同对应场景先过解密重新打包分发--pck-create目录 --pck-version2 --pck-engine-version4.3.0新 PCK可用--embed塞进 EXE替换个别文件--pck-patchpck --patch-file源目标打好补丁的 PCK跑法一带密钥抢救加密工程。上面第一条命令再加两个参数gdre_tools --headless --recovergame.apk --outputrecovered_project \ --force-bytecode-version4.3.0 \ --key000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F这条命令跳过自动版本检测、直接按 4.3.0 的字节码定义反编译并在读取文件前先用密钥解密。跑完看报告里的Failed scripts成片失败多半是版本或密钥填错了而不是工具本身的问题。坑--force-bytecode-version只在自动检测失败时用硬写错版本会让失败率飙升。跑法二安全审计只抽脚本。gdre_tools --headless --recovertarget.pck --scripts-only --outputscripts_analysis只输出 .gd速度快适合通读网络通信、存档加密、内购校验这类敏感逻辑。坑别用--includeres://main.gd捞脚本——包里通常没有 .gd 源文件只有编译后的 .gdc要写成--includeres://**/*.gdc恢复时才会输出对应的 .gd。跑法三素材教学拆解。全量恢复命令上加--includeres://assets/art/**/*.png和--includeres://scenes/**/*.tscn两条过滤即可图片还原成原始导入格式场景从二进制转回 .tscn 文本可直接打开读。坑glob 默认以res://为根*.png这种裸通配会被当成递归匹配等价于res://**/*.png过滤结果不符合预期时先检查通配符写法。FAQQ1反编译出来报错一堆怎么办大概率是字节码版本检测偏差。用--list-bytecode-versions看可用版本再用--force-bytecode-version版本显式指定日志若提示工程可能用了自定义 Godot 版本说明检测未实现需要按报告建议的版本手动核对。Q2--key 到底怎么填64 个十六进制字符32 字节形如000102...1E1F。密钥错了要么解密失败要么产出乱码资源算法也要与游戏加密方式一致标准方案是 AES-256-CFB仓库里另有 Camellia 与 Aria 两个上下文。Q3支持 GDExtension 项目吗不支持。README 的 Limitations 明确列出 GDNative/GDExtension 脚本未实现2.x 模型格式也在未实现清单里。Q4反编译结果和原代码一样吗不一样。注释只能部分还原命名与排版全部丢失拿到的是逻辑等价的骨架代码需要人工整理。Q5包损坏了提取一半就报错--ignore-checksum-errors跳过 MD5 校验失败的文件继续提取确定包没问题只想提速用--skip-checksum-check干脆不做校验。Q6想从源码编译呢把仓库https://gitcode.com/GitHub_Trending/gd/gdsdecomp克隆到 Godot 源码树的modules/gdsdecomp目录再用 SCons 重编引擎需要 rustup 与 dotnet 10 SDK且基于 README 指定的 Godot forkSCons configure 时会自动给main/main.cpp打一次补丁以挂钩命令行解析幂等可重复运行。只是使用的话下载 Release 更省事。跑完之后你能做什么手头有个 PCK先跑gdre_tools --headless --recovergame.pck --outputout盯恢复日志里的三个数字Failed scripts非零时拿日志报告的版本去 misc/bytecode_versions.json 查该版本有没有登记、parent 链是否连续。再想深入的话贡献路径很短分析新版 Godot 的字节码差异在 JSON 里加一条 parent 链条目added/removed tokens、函数变化跑 bytecode_generator.py 生成解析器类最后用 tests/ 里的夹具验证——test_projects/备齐了 2.1.1 到 4.5.1 的 19 个 .pck 样本test_bytecode.cpp会对它们逐个跑反编译。为新版 Godot 提一个这样的字节码版本定义就是这个项目门槛最低、也最被需要的 PR。【免费下载链接】gdsdecompGodot reverse engineering tools项目地址: https://gitcode.com/GitHub_Trending/gd/gdsdecomp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考