Udon Decompiler

概览

本节介绍本项目概况, 代码仓库的文件结构和当前工作流程, 以便读者快速了解项目.

项目概况

本项目主要包括反编译器本体和一些与反编译器本体配合使用的 Unity Editor Script.

关于反编译器本体, 它是一个从 0 开始使用 Python 编写的反编译器. 我们没有使用现成反编译框架. 当前主要依赖如下:

  • networkxnetworkx: 构建函数级 CFG
  • pydotpydot: 导出 CFG 图
  • clang-formatclang-format: 格式化反编译结果

代码仓库

$ tree -L 2 --gitignore
.
├── docs # 你正在阅读的文档
├── about
├── book.typ
├── dev
├── for-llm
├── introduction.typ
├── user
├── user-en
└── _utils
├── Editor # 编辑器脚本
├── UdonModuleInfoExtractor.cs
├── UdonProgramDumper.cs
├── UdonProgramDumperGUI.cs
├── UdonSharpSourceTextCompilerCLI.cs
├── UdonSharpSourceTextCompiler.cs
└── UdonSharpSourceTextCompilerGUI.cs
├── LICENSE
├── pyproject.toml
├── README.md
├── tests # 测试系统和测试样例
├── cases
├── ci
├── __init__.py
├── decompile_case.py
└── test_snapshots.py
├── udon_decompiler # 反编译器源代码
├── analysis
├── codegen
├── __init__.py
├── loaders
├── __main__.py
├── models
├── parsers
└── utils
└── uv.lock
$ tree -L 2 --gitignore
.
├── docs # 你正在阅读的文档
├── about
├── book.typ
├── dev
├── for-llm
├── introduction.typ
├── user
├── user-en
└── _utils
├── Editor # 编辑器脚本
├── UdonModuleInfoExtractor.cs
├── UdonProgramDumper.cs
├── UdonProgramDumperGUI.cs
├── UdonSharpSourceTextCompilerCLI.cs
├── UdonSharpSourceTextCompiler.cs
└── UdonSharpSourceTextCompilerGUI.cs
├── LICENSE
├── pyproject.toml
├── README.md
├── tests # 测试系统和测试样例
├── cases
├── ci
├── __init__.py
├── decompile_case.py
└── test_snapshots.py
├── udon_decompiler # 反编译器源代码
├── analysis
├── codegen
├── __init__.py
├── loaders
├── __main__.py
├── models
├── parsers
└── utils
└── uv.lock

工作流程

反编译前

  • 提取 UdonModuleInfo.jsonUdonModuleInfo.json: 获取所有可能的 externSignatureexternSignature 对应的函数信息, 输出为 .json.json 供反编译器使用
  • 解析 serializedProgramCompressedBytesserializedProgramCompressedBytes: 由于本反编译器使用 Python 编写, 而 Python 并没有 OdinSerializerOdinSerializer 的反序列化器可用, 所以需要在 Unity 中使用编辑器脚本 UdonProgramDumper.csUdonProgramDumper.cs 把序列化的 Udon Program 反序列化, 然后重新序列化为一个对 Python 更友好的 .json.json 文件, 供反编译器使用

反编译

这部分内容的入口在 decompile_program_to_sourcedecompile_program_to_source 函数中. 按调用顺序可分为如下步骤:

  • 反汇编: BytecodeParserBytecodeParser
  • 数据流分析: DataFlowAnalyzerDataFlowAnalyzer

    • 构建 CFG: CFGBuilderCFGBuilder

      • 识别基本块: BasicBlockIdentifierBasicBlockIdentifier
      • 构建控制流边并发现隐藏函数入口: ._build_edges()._build_edges()
      • 构建每个函数的 CFG 并识别函数名: ._build_function_cfgs()._build_function_cfgs()
    • 函数级分析: FunctionDataFlowAnalyzerFunctionDataFlowAnalyzer

      • 栈模拟: StackSimulatorStackSimulator
      • 识别变量: VariableIdentifierVariableIdentifier
      • 构建原始 IR: IRBuilderIRBuilder
    • IR 变换: TransformPipelineTransformPipeline

      • 函数级 transforms: 控制流化简、循环/条件识别、while/do-while/switchwhile/do-while/switch 抬升、变量收集等
      • 程序级 transforms: IRClassConstructionTransformIRClassConstructionTransformPromoteGlobalsPromoteGlobals
  • 代码生成: ProgramCodeGeneratorProgramCodeGenerator

    • CSharpCodeGenerator.generate()CSharpCodeGenerator.generate(): 从 IR 生成伪 C# 代码
    • 运行 clang-formatclang-format 进行格式化