111 lines
5.3 KiB
Markdown
111 lines
5.3 KiB
Markdown
<div align="center">
|
||
|
||
# Pynosaur
|
||
|
||
<!--
|
||
[](https://pypi.python.org/pypi/pynosaur)
|
||
[](https://pypi.python.org/pypi/pynosaur)
|
||
-->
|
||
[](https://github.com/astral-sh/ruff)
|
||

|
||
|
||
简体中文 | [English](README.en.md)
|
||
|
||
</div>
|
||
|
||
Pynosaur 是下一代用于 Python 3.9 至 3.14 字节码(pyc)的反编译器、原地编辑器和跨版本编译器,专门适配近几个 Python 版本。它只使用确定性算法,不使用任何启发式或统计方法。
|
||
|
||
[👉 跳转到安装与用法小节](#安装)
|
||
|
||
> [!NOTE] 供专业用户使用
|
||
>
|
||
> Pynosaur 主要用途是观察和处理 Python 字节码,假定用户已经**了解 Python 字节码的基本知识**。对于术语和操作含义等,程序内不会有过多说明。如果你还没有了解这些知识,只是想逆向某个特定的软件,你可能应该寻求专业人士的帮助。
|
||
|
||
## 功能特性
|
||
|
||
### 高版本 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 标准库或原生类型互操作
|
||
|
||
### 可转换的形式小结
|
||
|
||
### 自带电池
|
||
|
||
### 没有历史包袱
|
||
|
||
不同于其他支持早期版本(甚至 2.x, 1.x)的反编译器,Pynosaur 从一开始就被设计为只支持最近几个 CPython 版本,目前支持 CPython 3.9 至 3.14 的字节码。
|
||
|
||
这样的好处在于可以专注于现代 Python 语言的特性和优化,而不必考虑向后兼容性的问题。例如,从 Python 3.6 开始,CPython 字节码指令是定长的。由于不需要考虑旧版本的字节码,Pynosaur 可以安全地假定字节码指令的长度是固定的,这使得反编译器的实现更简单、更高效。
|
||
|
||
新的 Python 版本发布时,针对不再受支持版本的反编译逻辑可能会被 Pynosaur 移除。如果发生这种情况,Pynosaur 会发布新的主要版本。旧的主要版本仍然可用,但不再维护。这使得 Pynosaur 代码库可以保持简洁、灵活,在实现新的字节码时不需考虑过多兼容问题。
|
||
|
||
如果你需要处理 3.8 及更低版本的字节码,可以选择其他工具,见下文对比章节。
|
||
|
||
## 工作原理
|
||
|
||
|
||
|
||
## 与 Pycdc (Decompile++), Uncompyle6, PyLingual 的对比
|
||
|
||
|
||
|
||
## 安装
|
||
|
||
Pynosaur 本身是用纯 Python 编写的,运行在 Python 3.10 或更高版本上。使用 pip 安装:
|
||
|
||
```bash
|
||
pip install pynosaur
|
||
```
|
||
|
||
Pynosaur 本身不能在 Python 3.9 或更低版本上运行,因为它使用了 Python 3.10 引入的 `match` 语句、类型联合运算符如 `int | list[int] | None` 等。它*目前*可以反编译 Python 3.9 至 3.14 的字节码。
|
||
|
||
## 使用方法
|
||
|
||
|
||
|
||
## 运行测试
|
||
|
||
|
||
|
||
## 开发与贡献
|
||
|
||
|
||
|
||
## 许可证、致谢、贡献者、星标图
|