Documentação
/
Ofuscação VM
/

Register-Based VM

Register-Based VM

Pro
v7.12.0+

Mude a VM para um modelo de execução baseado em registradores, com execução mais rápida e um formato de VM diferente do padrão.

A opção vmRegisterBased muda a VM do seu bytecode padrão baseado em pilha para um modelo de execução baseado em registradores. Em alguns casos, isso melhora o desempenho da VM em execução em cerca de 10-20%, ao custo de um bundle ofuscado um pouco maior.

Ativá-la desliga Stateful Opcodes (vmStatefulOpcodes): as duas são incompatíveis, então, se vmStatefulOpcodes estava ativada, o build baseado em registradores a descarta silenciosamente.

Baseada em pilha vs. baseada em registradores

Uma VM baseada em pilha mantém os operandos em uma pilha implícita: cada valor é empilhado, consumido pela instrução seguinte, e o resultado é empilhado de volta. Uma VM baseada em registradores, por sua vez, endereça os operandos diretamente, de modo que o mesmo trabalho é expresso em menos instruções, sem o vaivém de push/pop entre elas. É daí que vem o ganho em execução - e também é por isso que o bytecode cresce um pouco, já que cada instrução agora precisa indicar explicitamente quais registradores lê e escreve, em vez de deixá-los implícitos na pilha.

Nenhum dos dois modelos muda o que o seu código faz nem o que a VM protege. São duas codificações da mesma lógica virtualizada; a baseada em registradores apenas troca um pouco de tamanho por um pouco de velocidade.

Quando usar

Recorra a ela quando o custo de execução da VM importar. Código virtualizado é, por natureza, mais lento que JavaScript comum, então, em um caminho frequente - um loop de animação, um handler executado a cada frame, uma rotina de parsing intensiva -, os cerca de 10-20% que o executor baseado em registradores pode economizar compensam o bundle maior. Em código que roda raramente, o custo em tamanho geralmente não compensa. O ganho depende do código, então meça-o nos seus próprios caminhos frequentes.

Ela também varia o formato da VM. Como emite um bytecode e um executor estruturalmente diferentes, a saída carrega uma impressão digital diferente da VM comum baseada em pilha. Análises genéricas baseadas em padrões, ajustadas a esse formato baseado em pilha, reconhecem com menos facilidade um build baseado em registradores, então esta é uma forma de afastar a VM publicada do padrão.

Como funciona por dentro

Este não é um compilador nativo baseado em registradores. O compilador comum baseado em pilha continua gerando o bytecode exatamente como faz sem a opção; depois, uma etapa de transformação separada reescreve esse bytecode no formato baseado em registradores. Como a execução baseada em registradores fica depois de tudo isso, a maior parte da ofuscação VM - seleção de funções, Bytecode Encoding, opções do dispatcher - não é afetada (exceto Stateful Opcodes, veja acima).

Requisitos

  • Requer vmObfuscation - esta opção apenas remodela a VM que vmObfuscation produz.
  • Versão do ofuscador 7.12.0 ou posterior.

Esta opção é experimental. A reescrita baseada em registradores é mais nova e menos testada em produção que o caminho padrão baseado em pilha, então teste se o seu código roda corretamente com vmRegisterBased ativado antes de publicá-lo - o mesmo conselho que vale para qualquer opção da VM, mas em dobro aqui.

Exemplo

JavaScript

A execução baseada em registradores se combina com o resto da ofuscação VM - Bytecode Encoding, Compact Dispatcher, VM Self Defending e VM Domain Lock funcionam exatamente como com a VM padrão baseada em pilha. Ela muda como o bytecode é executado, não quais proteções o envolvem.