文档
/
VM 混淆
/

异步执行器

异步执行器

Pro
v7.3.0+

以异步方式运行 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() 发出一条警告。这些警告(VMSyncFunctionSkippedInAsyncModeVMAsyncGeneratorSkippedInAsyncMode)可通过 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())'
});