Вирта не так сложна как кажется. Любая вирта сводится к генерации байткода и построения хендлеров обрабатывающих этот байткод. Опустим детали реализации, они везде разные, но основной пайплайн работы вм такой, считали порцию байткода, декодировали инструкцию, по опкоду вызвали хендлер с параметрами из инструкции. Изменили контекст в соответсвии с действиями хендлера.Создать виртуальную машину в соло невозможно - этим команды годами занимаются.
Хз кем надо быть чтоб создать такое.
Типов вм много, но основных два. Первый, это полная замена оригинального кода, на виртуальный (оригинал напрочь вырезается из бинаря), и второй это замена в оригинальном коде всевозможных операций на call к хендлеру, в параметрах передается тип операции и аргументы (например add, sub, mul и тд), аргументы иногда шифруются, и одним из доп аргументов передается ключ, для разбора агрументов, это добавляет не так много хлопот реверсерам, но все же лучше чем передавать чистые аргументы. К тому же иногда порядок аргументов тоже кодируется, что бы минимизировать возможность автоматического снятия такой защиты.
Первый тип вм обычно используется в бинарном виде, как VMP и иже с ним, ставятся метки в коде, функции дизасмятся, разбор идет на уровне ассемблерных команд. Штука сложная, согласен.
Второй тип не нуждается в бинарщине, его можно реализовать на уровне сорцев или IR, что-то подобное делалDildoFagins в своей статье, условно идет разбор AST и базовых арифметических операций, каждая операция заменяется на вызов функции-хендлера, в которую передаются аргументы и тип операции. При граммотной реализации этот вариант ни чуть не уступает в степени сложности реверса первому. А вот в реализация в разы проще. Под сложностью реверса я имею ввиду морфинг самого кода хендлера, его сильное запутывание. А так же возможно построение не единого хендлера, а разных, и по коду вызывать случайные. + для каждого хендлера своя уникальная системы кодирования и разбора агрументов. В одном хендлере ты можешь передавать тип операции первым аргументом, во втором хендлере третьим аргументом, добавлять фейковые аргументы и тд, суть понятна. Это напрочь убивает возможность раскрутки автоматикой. По итогу в одной функции могут происходить вызовы к десяткам разных хендлеров, каждый из которых по смыслу и логике работы идентичен остальным, но вот реализация разная, и генерируется эта реализация каждый раз новая, уникальная.
Это сложно, когда на это смотришь издалека, когда начинаешь копаться в этом говне с точки зрения разработки, очень многое проясняется, и уже не кажется недосягаемым мастерством. Тут не нужен опыт 20 лет в программировании. Даже джун напишет простую вм (второго типа), если основательно сядет за это дело, изучит матчасть. И если потом не забросит, то вполне сможет довести код до хорошего уровня защиты.
Всех пугает слово вм, потому что это реально трудно реверсить, но поверь мне, писать вм гораздо проще, чем потом ее исследовать. Это ошибочное мнение устоялось потому, что очень много людей (реверсеров) встречают на своем пути разные вм, и они доставляют им много проблем, и в то же время мы имеем очень мало людей, которые их разрабатывают, а они не сильно много болтают о том как у них там все устроено. Поэтому все думают, что вм это сумер-мега-гипер недосягаемая технология, невероятно сложная в реализации. Это не так.
Последнее редактирование: