异步执行器
以异步方式运行 VM,让字节码解密密钥可以在运行时获取,而不必随包一起分发。
vmAsyncExecutor 选项会启用异步 VM 执行器。它最主要的好处是 vmBytecodeArrayEncodingKeyGetter 现在可以返回一个 Promise —— 即 异步密钥获取器 —— 因此解密密钥可以在加载时来自网络请求、IndexedDB 或任意异步来源,而不必在代码首次运行时同步就绪。
关于从后端获取密钥的完整演练,请参阅方案从后端获取字节码数组密钥。
何时使用
强烈推荐用于完全异步的代码库。 在此模式下只有 async 函数会被虚拟化 —— 同步函数若不将其返回值变为 Promise(并因此破坏其调用方)就无法变为异步 —— 因此通篇 async 的代码能获得最广的覆盖。当根是同步的(例如同步 IIFE 或 UMD 包装器)时它仍然有效:其中最外层的 async 函数会受到保护,同步部分则保持原样。
哪些内容会被转换
任意位置(包括嵌套在同步包装器内部)的每个 最外层 async 函数。每条链中最外层的 async 就是受保护的单元 —— 它内部的一切,无论同步还是异步,都会被一并编译进去。同步函数和普通生成器保持不被混淆。
function foo() { // sync — left as-is
function bar() {} // sync — left as-is
async function baz() { // transformed
// any code here, including calls to other async or sync functions
}
async function bark() { // transformed
// any code here, including calls to other async or sync functions
}
}
跳过与警告
当异步密钥获取器处于活动状态时,异步生成器也会保持不被混淆 —— 异步生成器必须同步返回其迭代器,无法等待密钥。在默认的 vmTargetFunctionsMode: 'root' 下,跳过是静默的(选择是自动进行的)。在 'comment' 模式下,每当您显式标记的某个函数无法被虚拟化时 —— 无论是因为它其实是同步的,还是因为它是异步密钥获取器下的异步生成器 —— 都会通过 ObfuscationResult.getWarnings() 发出一条警告。这些警告(VMSyncFunctionSkippedInAsyncMode、VMAsyncGeneratorSkippedInAsyncMode)可通过 warnings 选项(v7.8.0+)按类型分别静默。
要求
- 异步密钥获取器需要
vmBytecodeArrayEncoding配合一个vmBytecodeArrayEncodingKeyGetter。 - 混淆器版本 7.3.0 或更高。
示例
JavaScriptObfuscator.obfuscate(code, {
vmObfuscation: true,
vmAsyncExecutor: true,
vmBytecodeArrayEncoding: true,
vmBytecodeArrayEncodingKey: 'mySecretKey123',
// the key getter may now return a Promise
vmBytecodeArrayEncodingKeyGetter: 'fetch("/vm-key").then((res) => res.text())'
});
