docs: wip devguide

This commit is contained in:
2025-06-20 18:39:30 +08:00
parent 19b5c1aef3
commit 9af3d8d4fb
8 changed files with 154 additions and 2 deletions

View File

@@ -2,15 +2,68 @@
简体中文 | [English](README.en.md)
[👉 跳转到安装与用法小节](#安装)
## 功能特性
### 高版本 CPython 字节码
### 是命令行程序,也是 Python 库
### 推测 Python 版本
如果传入 Marshal 产生的代码对象Code Object字节串Pynosaur 可以尽可能根据字节码指令推测出其对应的 Python 版本。这一特性对于 pyc 头丢失、只有反汇编文本等情况非常有用。
### 人为构造的代码对象
对于每个新的 Python 版本Pynosaur 首先尽可能实现对 CPython 编译器生成的字节码序列的支持。在此基础上,我们尝试在遇到 CPython 编译器通常情况下不会产生的字节码序列时,产生尽可能有用的结果。这样,就不会因为恶意构造的字节码而导致 Pynosaur 反编译失败。以下是一个仅用于描述的恶意构造的例子(其中的注释不是 Pynosaur 生成的,只是对例子的说明):
```plaintext
LOAD_CONST 1 (1)
LOAD_CONST 2 (2)
COMPARE_OP 148 (bool(>))
POP_JUMP_IF_FALSE 10 (to L1) # 下一条指令代表 1 大于 2 的分支
LOAD_GLOBAL 5678 (??? + NULL) # globals 的第五千多项?越界!
CALL 1234 # 从栈上弹出一千多个参数?
POP_TOP
```
一种可能的反编译输出是 `pass` 并在后面的注释中提供无法处理的字节码指令。
### 文本格式
除 pyc 文件等二进制格式外Pynosaur 也接受以下输入形式或其片段:
- 标准库 `dis.dis` 输出的反汇编字节码文本
- 标准库 `ast.dump` 输出的抽象语法树文本
- 标准库 `tokenize` 输出的词法单元文本
- [pycdas]() 输出的反汇编字节码文本
- [xdis]() 输出的反汇编字节码文本
### 版本转换
Pynosaur 还支持不同版本之间的字节码转换。例如,通过适当的命令行参数或脚本,可以用 Python 3.12 运行 Pynosaur 本身,传入文本格式的 Python 3.13 的字节码,输出可用于的 Python 3.11 的 pyc 文件。
### 与运行 Pynosaur 的 CPython 标准库或原生类型互操作
### 可转换的形式小结
### 衍生产品
- **Pynosaur UI**: 一个可视化的字节码反编译、原地编辑、跨版本回编译工具。由 Pynosaur 开发者维护。
- **Pynosaur Duck**: 只需一条命令,解包并递归反编译 PyInstaller 和 Py2exe 打包的可执行文件。由 Pynosaur 开发者维护。灵感来源于 [Pydumpck]()。
## 设计
### 没有历史包袱
不同于其他支持早期版本(甚至 2.x, 1.x的反编译器Pynosaur 从一开始就被设计为只支持最近几个 CPython 版本,目前支持 CPython 3.9 至 3.14 的字节码。
这样的好处在于可以专注于现代 Python 语言的特性和优化,而不必考虑向后兼容性的问题。例如,从 Python 3.6 开始CPython 字节码指令是定长的。由于不需要考虑旧版本的字节码Pynosaur 可以安全地假定字节码指令的长度是固定的,这使得反编译器的实现更简单、更高效。
新的 Python 版本发布时,针对不再受支持版本的反编译逻辑可能会被 Pynosaur 移除。如果发生这种情况Pynosaur 会发布新的主要版本。旧的主要版本仍然可用,但不再维护。这使得 Pynosaur 代码库可以保持简洁、灵活,在实现新的字节码时不需考虑过多兼容问题。
如果你需要处理 3.8 及更低版本的字节码,可以选择其他工具,见下文对比章节。
## 工作原理