Documentación
/
Ofuscación VM
/

Register-Based VM

Register-Based VM

Pro
v7.12.0+

Cambia la VM a un modelo de ejecución basado en registros para lograr un runtime más rápido y una VM con una forma distinta de la predeterminada.

La opción vmRegisterBased cambia la VM de su bytecode predeterminado basado en pila a un modelo de ejecución basado en registros. En algunos casos esto mejora el rendimiento del runtime de la VM en torno a un 10-20 %, a cambio de un bundle ofuscado algo mayor.

Activarla desactiva Stateful Opcodes (vmStatefulOpcodes): ambas son incompatibles, así que si vmStatefulOpcodes estaba activada, la compilación basada en registros la descarta silenciosamente.

Basada en pila frente a basada en registros

Una VM basada en pila guarda los operandos en una pila implícita: cada valor se apila, la siguiente instrucción lo consume y el resultado se vuelve a apilar. En cambio, una VM basada en registros direcciona sus operandos directamente, así que el mismo trabajo se expresa con menos instrucciones y sin tráfico de apilar y desapilar entre ellas. De ahí procede la ganancia en tiempo de ejecución, y también por eso el bytecode crece ligeramente, ya que cada instrucción tiene que indicar qué registros lee y escribe en lugar de dejarlos implícitos en la pila.

Ninguno de los dos modelos cambia lo que hace tu código ni lo que protege la VM. Son dos codificaciones de la misma lógica virtualizada; la basada en registros simplemente cambia un poco de tamaño por un poco de velocidad.

Cuándo usarla

Recurre a ella cuando importe el coste de ejecución de la VM. El código virtualizado es, por diseño, más lento que el JavaScript normal, así que en una ruta frecuente (un bucle de animación, un manejador por fotograma, una rutina de análisis ajustada) el ~10-20 % que puede ahorrar el ejecutor basado en registros compensa el bundle más grande. En código que se ejecuta pocas veces, el coste en tamaño no suele compensar. La ganancia depende del código, así que mídela en tus propias rutas frecuentes.

También varía la forma de la VM. Como emite un bytecode y un ejecutor estructuralmente distintos, la salida presenta una huella distinta de la VM habitual basada en pila. Un análisis genérico basado en patrones, ajustado a esa forma basada en pila, reconoce con menos facilidad una compilación basada en registros, así que esta es una forma de alejar la VM que distribuyes de la predeterminada.

Cómo funciona internamente

No se trata de un compilador nativo basado en registros. El compilador habitual basado en pila sigue generando el bytecode exactamente igual que sin la opción; después, una etapa de transformación independiente reescribe ese bytecode en forma basada en registros. Como la ejecución basada en registros se sitúa después de todo ello, la mayor parte de la ofuscación VM (la selección de funciones, Bytecode Encoding, las opciones del dispatcher) no se ve afectada (salvo Stateful Opcodes, ver más arriba).

Requisitos

  • Requiere vmObfuscation: esta opción solo cambia la forma de la VM que produce vmObfuscation.
  • Versión del ofuscador 7.12.0 o posterior.

Esta opción es experimental. La reescritura basada en registros es más reciente y está menos probada en producción que la ruta predeterminada basada en pila, así que comprueba que tu código funciona correctamente con vmRegisterBased activada antes de distribuirlo. Es el mismo consejo que para cualquier opción de la VM, pero aquí con más motivo.

Ejemplo

JavaScript

La ejecución basada en registros se combina con el resto de la ofuscación VM: Bytecode Encoding, Compact Dispatcher, VM Self Defending y VM Domain Lock funcionan exactamente igual que con la VM predeterminada basada en pila. Cambia cómo se ejecuta el bytecode, no qué protecciones lo envuelven.