模块参考
本参考描述了模块管理中可用的模块。它面向需要决定哪些保护和优化应包含在配置文件中的发布负责人。请测试完整的受保护产物,而不是仅凭小型基准测试或成功编译来判断某个模块。
核心
编译后端
历史配置缺少后端字段时按 JNI 解释。JNI 保留多目标输出及五档预设。JVMCI 每次只生成一个 Windows x86-64 或 Linux x86-64 目标产物,并要求支持的 Zulu 运行环境。模块目录根据后端及目标提供可用性、内置行为和依赖。切换后端时审阅配置调整;各后端分别保留草稿。以下 JNI 专属依赖说明不会覆盖模块目录的实际判断。JNI 多目标构建中,平台专属模块可能只对部分目标生效,界面会明确列出范围;启用 Windows 专属保护不表示 Linux 产物也应用了该保护。
结构混淆
通过表单配置常用变换,必要时展开高级选项。默认作用域为 application;whole-artifact 属于实验模式,需要针对外部调用方验证。保留规则维护集成依赖的声明。Web 配置将固定的 64 位 seed 存为十进制字符串,避免 JavaScript 舍入。可在构建详情下载私有结构映射,并与对应发布版本一起保存;存储路径由服务管理。
NOL 配置与分析
NOL 对话框按入口点、反射、JNI 访问、序列化、代理、资源、保留规则和类加载域分组。保留声明不等于添加执行入口。可以搜索 JAR 中精确的类、成员和资源,或手动填写外部符号;高级 JSON 使用同一份配置。枚举局部化提供 off 和 proven,需要模块目录所示的 JVMCI/NOL 组合。
辅助配置 会携带完整的未保存编译草稿,打开免费的 输入 → 入口点 → 解决问题 → 审阅 → 构建 引导流程;助手没有侧边栏入口。可能的 main 方法候选需要用户选择。问题提示根据结构化配置分组要求填写真实目标,不会猜测声明。可以先准备多项修改,再重新分析。返回前审阅所选 NOL 修改,或不修改声明直接返回;已保存的项目默认值保持不变。分析不会启用对象局部化。报告中的候选及证明完整性针对提交的输入与声明;修改草稿后,旧证据仍未验证当前配置。流程详见 使用分析助手配置 NOL。
Semantic Mirage 与 Runtime Profile
Semantic Mirage 是实验性 JVMCI 保护选项。Runtime Profile 是可选的 JVMCI 诊断功能,其测量会增加运行工作量。两者默认关闭。可用性和依赖根据所选后端及目标解析,profiling 不是编译的前置条件。
方法选择
选择 带注解 以保护标记了 @Nativify 的方法,或选择 所有符合条件的方法 以将保护扩展到每个符合条件的方法。当发布需要精确控制范围时,带注解选择是更好的起点。
| 性能 | 兼容性 |
|---|---|
| 更广泛的选择可能会增加构建时间和原生构建产物大小。它还可能在更多应用程序路径中改变运行时性能。 | 测试进入所选方法的应用程序路径。抽象方法不符合保护条件。 |
目标平台
选择 Nativify 为其生成原生输出的操作系统和架构组合。JNI 配置可以包含一到四个目标;JVMCI 配置仅包含一个 Windows x86-64 或 Linux x86-64 目标。
| 性能 | 兼容性 |
|---|---|
| 每个额外的目标都会增加构建工作量、输出大小和发布测试覆盖范围。在给定目标上它没有直接的运行时成本。 | 受保护产物必须在发布前在每个选定的操作系统和架构上进行测试。 |
动态原生注册
动态原生注册在应用程序启动时绑定受保护的方法。使用动态注册的模块也需要它。
| 性能 | 兼容性 |
|---|---|
| 通常只增加启动工作量;当启动延迟很重要时请进行测量。 | 虚调用内联缓存和加密原生负载所必需。测试应用程序启动和每个选定的目标。 |
链接时优化
对于 JNI,链接时优化在选定方法的原生代码组合后应用额外的优化。Thin 是可扩展的默认选项;Full 优先考虑最广泛的优化机会。JVMCI 也支持 off、Thin 和 Full。开启 LTO 后,在每个方法 recipe 的完整原生链接单元内优化,不跨 recipe 合并 Java 方法。关闭 LTO 时仍保留必要的 IR 优化。
| 性能 | 兼容性 |
|---|---|
| 构建时间、内存使用和运行表现取决于输入及所选模式。请使用应用关心的工作负载测量实际产物。 | 联合测试所选后端、目标和 LTO 模式。JVMCI 仍要求受支持的运行环境;启用 LTO 不会改变这一契约。 |
优化
IR 优化
IR 优化改善为受保护方法生成的原生代码。标准 是默认选择;激进 应用更广泛的优化集。
| 性能 | 兼容性 |
|---|---|
| 更高的模式会增加构建工作量,并可能降低符合条件代码中的运行时成本。结果因工作负载而异。 | 稳定。对象流所必需。使用确切选定的模式验证性能和行为。 |
静态直接调用
静态直接调用优化受保护静态方法之间符合条件的调用,当两侧可以直接链接时避免不必要的边界工作。
| 性能 | 兼容性 |
|---|---|
| 可以减少符合条件的原生到原生路径中的调用开销。 | 稳定。由对象流选项“精确实例直接调用”和“对象本地化”所要求。 |
虚调用内联缓存
虚调用内联缓存加速重复观察到的虚调用和接口调用目标,当它们可以安全缓存时。
| 性能 | 兼容性 |
|---|---|
| 可以改善调度密集型工作负载;它可能会增加少量首次使用或未命中路径成本。 | 实验性。需要动态原生注册。测试多态应用程序路径、插件和框架回调。 |
对象流
对象流使用关于对象如何通过选定代码移动的已验证信息来简化符合条件的操作。其 高级 选项暴露了进一步的重点优化。
| 性能 | 兼容性 |
|---|---|
| 可以减少符合条件区域中与对象相关的工作,同时增加构建分析时间。 | 实验性。需要 IR 优化。在启用高级选项之前测试对象密集型应用程序路径。 |
字符串流
字符串流是高级对象流选项,用于符合条件区域中可预测、非逃逸的字符串长度工作。
| 性能 | 兼容性 |
|---|---|
| 可以减少匹配的字符串处理路径中的工作;否则几乎没有影响。 | 实验性。需要对象流和高级对象流。测试相关的字符串处理工作负载。 |
精确实例直接调用
精确实例直接调用是高级对象流选项,当实例目标的类型被证明是精确的时直接调用该目标,同时在其他地方保持正常调度。
| 性能 | 兼容性 |
|---|---|
| 可以减少匹配调用点的虚调用开销。 | 实验性。需要对象流、高级对象流和静态直接调用。测试继承、代理和框架生成的类型。 |
对象本地化
对象本地化是高级对象流选项,适用于对象使用被精确理解的配置。其配置记录了应用程序入口点和必须保持可用的动态访问模式。
| 性能 | 兼容性 |
|---|---|
| 可以减少已验证的本地对象的工作,但需要额外的分析和构建配置工作。 | 实验性。需要对象流、高级对象流和静态直接调用。配置并测试反射、序列化、JNI 访问、代理、资源、保留规则和自定义类加载器域。 |
标准库替换
标准库替换在 Nativify 可以安全执行时,将受支持的 Java 标准库操作替换为优化的原生等效操作。
| 性能 | 兼容性 |
|---|---|
| 可以减少受支持的库密集型路径中的边界开销。它不影响不支持的操作。 | 稳定。在生产中使用的 JDK 发行版和版本上测试受保护的应用程序。 |
不安全内存访问
不安全内存访问对符合条件的直接字段访问使用 sun.misc.Unsafe。
| 性能 | 兼容性 |
|---|---|
| 可以减少匹配代码中的字段访问开销。 | 稳定。确认部署的 JDK 发行版允许所需的 sun.misc.Unsafe 访问,并在您支持的所有 JDK 上进行测试。 |
混淆
混淆模块增加了理解受保护原生代码所需的难度。它们最强的配置通常会增加原生代码大小、构建时间、运行时工作,或三者兼有。在稳定基线通过功能和性能测试后添加它们。
字符串加密
字符串加密保护原生字符串常量,使其不会以直接可读的原生文本形式存储。
| 性能 | 兼容性 |
|---|---|
| 增加原生代码,并可能在受保护字符串被使用时增加工作。 | 稳定。验证依赖字符串内容的输出,例如本地化、协议值和生成的文本。 |
常量加密
常量加密对原生数值常量进行编码,包括浮点常量的位模式,使直接检查变得不那么有用。可用的运行时操作数和支持的使用点会影响保护范围。
新实现沿用原来的模块和 feature ID,直接替换旧实现。恒值表达式提供仅整数、仅浮点、混合三种模式。仅整数不新增浮点运算。仅浮点仍需要整数指令打包位模式和完成转换。三种模式都能保护整数常量和浮点常量的位模式。
| 选项 | 默认值 | 取舍 |
|---|---|---|
| 状态更新边比例 | 100% | 按比例采样符合条件的可证明控制流边。降低比例可减少状态更新开销。 |
| 常量保护比例 | 100% | 按比例采样符合条件的常量站点。降低比例会让更多原始常量可见。 |
| 在可证明的循环中更新状态 | 关闭 | 完全展开固定次数的小循环后插入状态更新。未知次数的循环继续冻结。展开会增加代码体积。 |
| 可证明循环的最大迭代次数 | 8 | 限制开启循环更新时允许展开的次数,范围为 1–64。 |
| 新增指令预算 | 0(自动) | 限制每个方法新增的 IR。自动采用 JNI 8192 或 JVMCI 4096,范围为 0–8192。 |
采样由构建种子决定。证明和指令预算限制可能让实际覆盖率低于设置的百分比。只配置了启用开关的旧配置会采用上述默认值。网页预设会随着保护等级提高,增加覆盖率和预算。LLVM 优化保持开启。
| 性能 | 兼容性 |
|---|---|
| 可以增加原生代码大小和受保护常量周围的算术工作。 | 稳定。测试数值密集型代码和任何对性能敏感的循环。 |
伪控制流
伪控制流添加不透明分支,使原生控制流图不那么直接可循。
| 性能 | 兼容性 |
|---|---|
| 增加原生代码大小,并可能增加分支工作。 | 稳定。对分支密集型代码使用性能测试。 |
VM 控制流平坦化
VM 控制流平坦化通过受保护的调度器表示符合条件的原生控制流。模块名称指的是受保护的执行形式,而不是 Java 虚拟机。
| 性能 | 兼容性 |
|---|---|
| 通常会增加明显的运行时工作和原生代码大小。 | 实验性。仅对增加的保护证明所测量开销合理的代码启用它。 |
指令替换
指令替换将选定的原生操作替换为等效的、不太明显的指令序列。
| 性能 | 兼容性 |
|---|---|
| 可能增加代码大小和指令数量。 | 稳定。如果算术密集型工作负载对发布很重要,请测量它们。 |
线性 MBA
线性 MBA 使用混合布尔算术表达式重写符合条件的算术运算,使操作更难通过检查来简化。
| 性能 | 兼容性 |
|---|---|
| 可能大幅增加受影响算术运算中的指令数量。 | 实验性。在测试数值正确性和热路径后,优先进行有针对性的使用。 |
拆分基本块
拆分基本块将符合条件的原生块划分为更小的块,使控制流不那么紧凑。
| 性能 | 兼容性 |
|---|---|
| 增加代码大小,并可能增加分支开销。 | 稳定。启用时测量分支密集型代码。 |
调用间接化
调用间接化将直接原生调用替换为通过指针的间接调用。
| 性能 | 兼容性 |
|---|---|
| 为受影响的调用增加间接性,并可能减少调用点优化机会。 | 稳定。测试调用密集型工作负载以及与其他调用优化的组合。 |
全局变量间接化
全局变量间接化通过间接方式而非直接引用访问符合条件的原生全局变量。
| 性能 | 兼容性 |
|---|---|
| 为受影响的全局访问增加一次额外查找。 | 稳定。测量频繁读取或写入原生全局状态的代码。 |
VM 虚拟化
VM 虚拟化将符合条件的整数区域转换为旨在更难分析的受保护执行形式。
| 性能 | 兼容性 |
|---|---|
| 通常对受影响区域具有较高的运行时成本,并可能增加原生代码大小。 | 实验性。仅限于符合条件的整数区域;仅在代表性功能和性能测试后使用。 |
LLVM 反调试
LLVM 反调试向受保护方法添加原生调试器检查。
| 性能 | 兼容性 |
|---|---|
| 向受保护代码添加检查工作。 | 实验性,仅适用于 windows-x86_64。它可能与开发调试器、分析器和自动化分析工具冲突;测试真实的部署环境。 |
LLVM 反 Hook
LLVM 反 Hook 检查受保护的原生方法入口点是否有内联修改的迹象。
| 性能 | 兼容性 |
|---|---|
| 向受保护方法添加完整性检查工作。 | 实验性,仅适用于 windows-x86_64、linux-x86_64 和 macosx-x86_64。测试您的客户使用的端点安全、APM、性能分析和插桩产品。 |
运行时保护
运行时保护模块可以判定某个环境对受保护应用程序不可接受。它们有意与某些开发、自动化、虚拟化或分析环境不兼容,因此暂存测试必须与生产环境紧密匹配。
运行时反分析
运行时反分析检查可疑的 Windows 环境。平衡 使用较低敏感度的策略;严格 应用更敏感的检查。
| 性能 | 兼容性 |
|---|---|
| 增加启动和运行时检查。严格模式可能拒绝更多环境。 | 实验性,面向 Windows。发布前测试物理设备、虚拟桌面基础设施、CI、支持工具和端点保护。 |
虚拟机拒绝
虚拟机拒绝阻止受保护应用程序在检测到的 Windows 虚拟机环境中运行。
| 性能 | 兼容性 |
|---|---|
| 增加环境检查,通常在启动时最明显。 | 实验性,仅适用于 windows-x86_64。不要为必须在虚拟机、托管桌面、常见测试农场或开发人员 VM 中运行的发布启用它。 |
加密原生负载
加密原生负载将所有选定的 Windows x86-64、Linux x86-64 和 Linux ARM64 原生库封装到同一个认证图中,保护其静态存储形式。每个目标使用独立验证的引导库。Linux 将解密结果流式写入匿名 ELF 段,不保留完整明文主库文件或 memfd;执行映像代码前释放临时 AES 材料和解压工作区。解密后的原始主库必须获得本次构建加载器的新鲜签名才能初始化,直接加载会被拒绝;这不意味着能阻止运行时内存检查、原生代码修改,或攻击者逆向引导库后复制握手。
| 性能 | 兼容性 |
|---|---|
| 在应用程序启动期间增加原生负载处理,并增大产物体积。 | 实验性;需要动态原生注册。Windows 使用内存 PE 加载器、静态 zlib 和系统 BCrypt。Linux 使用匿名 ELF 映射器,支持 W^X、RELRO、栈展开注册和编译器生成的模拟 TLS。构建时必须提供匹配的开发头文件及兼容目标平台的 PIC libcrypto.a/libz.a,不回退到动态 crypto/zlib。运行时仍需系统 C、线程及动态加载器库和共享 libgcc_s。私有共享依赖必须自行提供搜索路径。更新嵌入依赖需要重新构建发布产物。请在实际目标环境测试。 |