# 混淆术语表

AfterPack 文档中的术语：多态性、非物化、还原类等，每个只定义一次。

Source: https://www.afterpack.dev/zh/docs/glossary

AfterPack 的文档按这里定义的含义使用以下术语。

## 两条轴

AfterPack 的保护沿两条相互独立的轴来描述：*单次*构建有多难还原，以及不同构建*彼此之间*有多大差别。你可以只调高其中一条，而不动另一条。

### 复杂度

单次构建有多难还原：一个产物内部的保护深度。由 [`complexity`](#complexity) 设置，可以直接设置，也可以来自某个[预设](https://www.afterpack.dev/zh/docs/presets#the-ladder)。

### 逐构建多态性

每次构建与上一次之间差异有多大。由[种子](#seed)设定：引擎配置中的 [`seed`](https://www.afterpack.dev/zh/docs/config#seed)，命令行中的 [`--seed`](https://www.afterpack.dev/zh/docs/config#seed)。这是 AfterPack 的主要防御手段。每次构建的形态都不同，所以针对某次构建的模式编写的工具，到下一次就会失效。运行代码的人仍然可以读到它使用的值。参见 [AfterPack 的工作原理](https://www.afterpack.dev/zh/docs/concepts#a-new-program-every-build)。

## 配置

### 预设

一组有名字的保护设置，用[一个标志](https://www.afterpack.dev/zh/docs/config#preset)选择：`minify`、`light`、`medium`、`hard`、`extreme`。默认为 `light`。一个预设名称设定 [`complexity`](#complexity) 目标。每一级设定的目标见[预设](https://www.afterpack.dev/zh/docs/presets#the-ladder)。

### complexity

输出中的纠缠程度；参见[配置](https://www.afterpack.dev/zh/docs/config#complexity)。它没有上限。显式设置的 [`inflation.max`](https://www.afterpack.dev/zh/docs/config#inflation-max) 若阻挡了它，会让构建失败；若不设置，则完全由这个目标决定输出能膨胀到多大。各预设的取值见[预设](https://www.afterpack.dev/zh/docs/presets#the-ladder)。

### 指令

写在源码中的[块](https://www.afterpack.dev/zh/docs/directives#writing-one)注释，用于调整它所附着的结构的保护。行内的 [`/* @afterpack preset=extreme */`](https://www.afterpack.dev/zh/docs/config#preset) 覆盖紧跟在它后面的字面量。代码块形式 `/* @afterpack <key>=<value> */ … /* @afterpack end */` 以单独占一行的标记开启，以配对的 `end` 关闭，覆盖一段明确的范围。`//` 行注释不会被扫描。[`skip`](https://www.afterpack.dev/zh/docs/config#skip) 在你需要兼容性的地方降低保护；[`preset=hard`](https://www.afterpack.dev/zh/docs/config#preset) 或 [`preset=extreme`](https://www.afterpack.dev/zh/docs/config#preset) 则提高保护。只有 [Pro](https://www.afterpack.dev/zh/docs/pro) 引擎会遵循区域设置；参见 [Free 构建](https://www.afterpack.dev/zh/docs/directives#free-builds)。在 Free 中划出例外，请改用 [`paths.exclude`](https://www.afterpack.dev/zh/docs/config#paths-exclude) 或 [`identifiers.reserved`](https://www.afterpack.dev/zh/docs/config#identifiers-reserved)。参见[指令](https://www.afterpack.dev/zh/docs/directives)。

### `preset=hard`

一条指令（`/* @afterpack preset=hard */`），它把一个[区域](https://www.afterpack.dev/zh/docs/directives#what-you-can-set)提高到 [`complexity`](#complexity) 12，即 [`hard` 这一级](https://www.afterpack.dev/zh/docs/presets#the-ladder)，并且无论全局预设是什么，都会为该区域强制开启[字符串下限](https://www.afterpack.dev/zh/docs/config#strings-encode)。[`/* @afterpack preset=extreme */`](https://www.afterpack.dev/zh/docs/config#preset) 做同样的事，目标为 25。

## 还原与攻击者模型

### 固定结构

在各次构建之间保持不变的形态：字符串数组（即便是加密的）、VM 解释器、每次构建都一模一样的解码器引导代码。像 `webcrack` 这样的工具或模型，学会一次这种形态，就能在所有共享它的构建上反复使用。任何混淆器都可以让常量随构建变化；关键在于底层是否还保留着这样的形态。AfterPack 的形态、名称、常量和布局都从每次构建的[种子](#seed)重新生成，所以针对某次构建的模式编写的识别器到下一次就会失效。它不会对运行代码的人隐藏值。参见[为什么固定的混淆层会失效](https://www.afterpack.dev/zh/docs/concepts#why-fixed-obfuscation-layers-fail)。

### 还原类

三个面向静态攻击者的分类，描述的是阅读字节的人（grep、AST 工具，或者不执行代码的盲眼 LLM）最终能拿走什么：重命名与编码（renamed & encoded）、扁平化与融合（flattened & fused），以及破坏与融合（destroyed & fused）。运行代码的动态攻击者是一个独立的、更强的情形。分类表以及每一类给攻击者留下了什么，见[还原类](https://www.afterpack.dev/zh/docs/reversal-classes)。目前只有第一类“重命名与编码”由已发布的变换产生；“扁平化与融合”和“破坏与融合”是预留的。

### 非物化

保护密钥的机制，独立于上面的还原类，后者恢复的是结构而不是值。由 [`transforms.comparisonHardening.enabled`](https://www.afterpack.dev/zh/docs/config#transforms-kind-enabled) 提供，它把一个字符串相等性门控重写为一次单向摘要校验，使该字面量不出现在产物中。这不同于[字符串下限](https://www.afterpack.dev/zh/docs/config#strings-encode)，后者会编码字面量，但在使用时仍会把它重建出来。它能击败静态阅读者和盲眼 LLM。它无法击败在被插桩的运行时下运行代码的攻击者；没有任何构建期混淆工具能改变这一点。参见[密钥如何得以保留](https://www.afterpack.dev/zh/docs/concepts#how-secrets-survive)。

## 交付、种子与套餐

### 种子

决定产出哪一种多态输出的构建参数。默认是随机的。它不是秘密：发布出去的产物无论如何都是公开的，知道某次构建的种子也无助于还原它。在生产环境中让它随每次发布变化。只有在你需要逐字节相同的输出时，比如为了 CI 缓存或可复现的审计，才固定它（[`--seed=git`](https://www.afterpack.dev/zh/docs/config#seed)）。参见 [`seed`](https://www.afterpack.dev/zh/docs/config#seed) 和[构建与发布](https://www.afterpack.dev/zh/docs/builds)。

### source map

把混淆后的输出链回你原始源码的映射。对本地调试很有用。一个公开的 `.map` 会给攻击者一条直通你源码的路径。永远不要把它发布到生产环境。在[生产](https://www.afterpack.dev/zh/docs/config#build-mode)构建中，AfterPack [默认关闭 source map](https://www.afterpack.dev/zh/docs/config#sourceMap-enabled)，去掉 [`sourceMappingURL` 注释](https://www.afterpack.dev/zh/docs/config#sourceMap-emitUrl)，并删除打包工具写出的 map。

### Protection Map

一份报告，按复杂度分数为你源码中的每个词元着色，并标出每个区域的[还原类](#reversal-classes)。默认由引擎决定；在 [Pro](https://www.afterpack.dev/zh/docs/pro) 上[标记区域](https://www.afterpack.dev/zh/docs/directives)之后则由你来决定。由 [`protectionMap.enabled`](https://www.afterpack.dev/zh/docs/config#protectionMap-enabled) 控制。参见 [Protection Map](https://www.afterpack.dev/zh/docs/protection-map)，或打开[在线演示](https://www.afterpack.dev/protection-map-demo)。

### 套餐

Free、Extra MB、Indie、Team、Studio、[Enterprise](https://www.afterpack.dev/zh/docs/enterprise)。Free 对整个 bundle 统一施加全强度的保护。付费套餐还可以用[指令](https://www.afterpack.dev/zh/docs/directives)为某一个函数或文件设置更重或更轻的预设。价格、额度和项目数量限制见[套餐与层级](https://www.afterpack.dev/zh/docs/tiers)。

### 失败即中止

这条规则保证 Pro 构建绝不会交付比你要求的更弱的保护。如果重试之后仍无法连接 Pro 云端，或者配额在批次处理中途耗尽，AfterPack 会以非零退出码停止。它不会回退为免费层级的输出或明文输出。参见[退出码与失败即中止](https://www.afterpack.dev/zh/docs/diagnostics#fail-closed-no-exceptions)。

## 下一步

- [AfterPack 的工作原理](https://www.afterpack.dev/zh/docs/concepts)：这些术语大多在那里结合上下文使用。
- [配置](https://www.afterpack.dev/zh/docs/config)：每一个选项，以及哪些形式可以设置它。
- [指令](https://www.afterpack.dev/zh/docs/directives)：完整的 `@afterpack` 语法，以及哪些键适用。
- [预设](https://www.afterpack.dev/zh/docs/presets)：上文目标值所来自的阶梯。
- [诊断](https://www.afterpack.dev/zh/docs/diagnostics)：这些术语会出现在其中的 `DIAG_*` 代码。
