Register-Based VM

Pro
v7.12.0+

Переведите VM на регистровую модель выполнения, чтобы ускорить работу во время выполнения и получить VM, устроенную иначе, чем по умолчанию.

Опция vmRegisterBased переключает VM со стекового байт-кода, используемого по умолчанию, на регистровую модель выполнения. В некоторых случаях это ускоряет выполнение VM примерно на 10-20% ценой немного большего размера обфусцированного бандла.

Её включение выключает Stateful Opcodes (vmStatefulOpcodes): эти опции несовместимы, поэтому, если vmStatefulOpcodes была включена, регистровая сборка молча её отбрасывает.

Стековая и регистровая модели

Стековая VM хранит операнды на неявном стеке: каждое значение кладётся на стек, забирается следующей инструкцией, а результат снова кладётся на стек. Регистровая VM, напротив, обращается к операндам напрямую, поэтому та же работа выражается меньшим числом инструкций без операций push/pop между ними. Отсюда и выигрыш во времени выполнения - и отсюда же небольшой рост байт-кода, ведь теперь каждая инструкция должна явно указывать, из каких регистров она читает и в какие пишет, а не оставлять это неявным на стеке.

Ни одна из моделей не меняет ни того, что делает ваш код, ни того, что защищает VM. Это две кодировки одной и той же виртуализированной логики; регистровая просто жертвует небольшим размером ради небольшой скорости.

Когда её использовать

Выбирайте её, когда важна стоимость выполнения VM. Виртуализированный код по своей природе медленнее обычного JavaScript, поэтому на часто выполняемом участке - в цикле анимации, покадровом обработчике, плотной процедуре разбора - примерно 10-20%, которые может сэкономить регистровый исполнитель, оправдывают больший бандл. Для редко выполняемого кода увеличение размера обычно того не стоит. Выигрыш зависит от кода, поэтому измеряйте его на своих часто выполняемых участках.

Она также меняет облик VM. Поскольку генерируются структурно иные байт-код и исполнитель, результат несёт отпечаток, отличающийся от распространённой стековой VM. Универсальный анализ на основе шаблонов, настроенный на этот стековый облик, хуже распознаёт регистровую сборку, так что это один из способов увести поставляемую VM от варианта по умолчанию.

Как это устроено внутри

Это не нативный регистровый компилятор. Обычный стековый компилятор по-прежнему генерирует байт-код точно так же, как без этой опции; затем отдельный этап преобразования переписывает этот байт-код в регистровую форму. Поскольку регистровый этап находится после всего этого, большая часть VM-обфускации - выбор функций, Bytecode Encoding, опции диспетчера - не затрагивается (кроме Stateful Opcodes, см. выше).

Требования

  • Требуется vmObfuscation - эта опция лишь меняет форму VM, которую создаёт vmObfuscation.
  • Версия обфускатора 7.12.0 или новее.

Эта опция экспериментальная. Регистровое переписывание новее и менее проверено в бою, чем стековый путь по умолчанию, поэтому перед выпуском убедитесь, что ваш код корректно работает с включённой vmRegisterBased. Этот совет относится к любой опции VM, но здесь - вдвойне.

Пример

JavaScript

Регистровое выполнение сочетается с остальной VM-обфускацией: Bytecode Encoding, Compact Dispatcher, VM Self Defending и VM Domain Lock работают точно так же, как со стековой VM по умолчанию. Оно меняет то, как выполняется байт-код, а не то, какие защиты его окружают.