Как создать виртуальную машину с нуля и из шаблона
Как создать виртуальную машину в виртуальном дата-центре? Ее можно развернуть из шаблона или создать с нуля.
Чтобы создать виртуальную машину любым из этих способов, войдите в панель управления VMware vCloud Director по инструкции.
Создание виртуальной машины из шаблона
Шаблон виртуальной машины содержит уже установленную операционную систему. Его удобно использовать, если нужно создавать однотипные виртуальные машины.
Шаблоны находятся в разделе Libraries, во вкладке vApp Templates. Их можно создавать самому или воспользоваться готовыми. Список доступных шаблонов приведен в статье: Какие шаблоны и ISO-образы доступны в vCloud Director?
Как создать виртуальные машины с разными ОС из готового шаблона:

В разделе Datacenters перейдите на вкладку Virtual Machines. Кликните на New VM.
- Name — имя виртуальной машины.
- Computer name — имя компьютера.
- Description — описание виртуальной машины.
- Type — тип создания виртуальной машины. Для создания из готового шаблона выберите From Template.
- Power on — поставьте галочку, чтобы виртуальная машина включилась после создания.
- В меню Templates выберите шаблон с нужной ОС.
Нажмите ОК.

Виртуальная машина начнет клонироваться из шаблона. При этом появится статус Busy.
Когда установка виртуальной машины будет окончена, она включится. Статус поменяется на Powered on. 
Готово! Вы осуществили создание виртуальной машины из шаблона.
Создание виртуальной машины с нуля
Виртуальную машину можно создать без шаблона — «с нуля». Тогда на неё можно будет загрузить свою операционную систему с ISO-образа.
ISO-образы находятся в разделе Libraries, во вкладке Media & Other. Можно загружать свои образы (оптические диски) или воспользоваться готовыми ISO-образами. Список доступных ISO-образов приведён в статье: Какие шаблоны и ISO-образы доступны в vCloud Director?
Как создать новую виртуальную машину:

В разделе Datacenters откройте вкладку Virtual Machines. Кликните на New VM.
- Name — имя виртуальной машины.
- Computer name — имя компьютера.
- Description — описание виртуальной машины.
- Type — тип создания виртуальной машины. Для создания новой выберите New.
- Power on — поставьте галочку, чтобы виртуальная машина включилась после создания.
- OS Family — выберите семейство ОС.
- Operating System — выберите версию нужной ОС.
- Boot image — выберите из папки Media & Others нужный установочный диск.
- Compute Policy — выберите по умолчанию.
- Select size — выберите размеры выделяемых на виртуальную машину ресурсов. Вы можете выбрать готовые конфигурации Pre-defined Sizing Options: количество процессоров CPU, ядер процессора Cores, оперативной памяти Memory и дискового пространства Storage. Также вы можете выбрать Custom Sizing Options и поставить свои настройки: количество виртуальных ядер Virtual CPUs, количество ядер на виртуальный сокет Cores per socket, количество сокетов на процессор Sockets per CPU и количество оперативной памяти Memory.
- Storage — дисковое пространство. Выберите диски и их размер. Нажав Add, можно добавить дополнительный диск.
- Networking — выберите сеть Network, к которой хотите подключить виртуальную машину. Вы можете выбрать все сети, которые находятся в разделе Datacenters, на вкладке Networks.

Нажмите ОК.

Виртуальная машина должна перейти в статус создания Busy.
Когда виртуальная машина будет создана, она включится. Статус поменяется на Powered on. 
Готово! Вы узнали, как создать виртуальную машину с нуля.
Как создать виртуальную машину с нуля?
1. В разделе Compute, в пункте Virtual Machines нажимаем кнопку new vm.

2. В появившемся окне задаем параметры создаваемой виртуальной машины:
- имя (Virtual Machine Name);
- имя, которое будет показываться внутри гостевой ОС при кастомизации (Computer Name);
- ее описание – при необходимости (Description);
- использовать ли шаблон для разворачивания (From Template);
- семейство и конкретную операционную систему, которую будем потом устанавливать, например, выберем Windows;
- объем оперативной памяти и диска;
- общее количество виртуальных ядер, которое будет выделено ВМ (Virtual CPUs);
- количество ядер на виртуальный сокет.
Последние два параметра важны для лицензирования некоторых ОС. Например, для Windows Server Standard количество сокетов должно быть не более 4. В других вариантах лучше оставить оставить 1 ядро на сокет.

- количество виртуальных сетевых адаптеров (Number of NICs). На данном этапе можно определить параметры сетевого адаптера, нажав кнопку Customize. Рекомендуем выбрать тип адаптера VMXNET 3. В случае если вы планируете использовать устаревшие версии операционных систем, оставьте параметры по умолчанию.

3. Нажимаем кнопку OK. Через некоторое время ВМ будет создана, можно переходить к установке или настройке операционной системы.
Виртуальная машина VirtualBox для начинающих

Виртуальные машины представляют собой эмуляцию устройств на другом устройстве или, в контексте этой статьи и упрощенно, позволяют запускать виртуальный компьютер (как обычную программу) с нужной операционной системой на вашем компьютере с той же или отличающейся ОС. Например, имея на своем компьютере Windows, вы можете запустить Linux или другую версию Windows в виртуальной машине и работать с ними как с обычным компьютером.
Для чего это может потребоваться? Чаще всего, виртуальные машины используют для запуска серверов или для тестирования работы программ в различных ОС. Для начинающего пользователя такая возможность может быть полезна как для того, чтобы попробовать в работе незнакомую систему или, например, для запуска сомнительных программ без опасности получить вирусы на своем компьютере.
Установка VirtualBox
Вы можете бесплатно скачать ПО для работы с виртуальными машинами VirtualBox с официального сайта https://www.virtualbox.org/wiki/Downloads где представлены версии для Windows, Mac OS X и Linux. Несмотря на то, что сайт на английском, сама программа будет на русском языке. Запустите загруженный файл и пройдите простой процесс установки (в большинстве случаев достаточно оставить все параметры по умолчанию).

Во время установки VirtualBox, если вы оставите включенным компонент для доступа к Интернету из виртуальных машин, вы увидите предупреждение «Warning: Network Interfaces», которое сообщает о том, что в процессе настройки ваше Интернет-подключение будет временно разорвано (и восстановится автоматически после установки драйверов и настройки подключений).
По завершении установки можете запустить Oracle VM VirtualBox.
Создание виртуальной машины в VirtualBox
Примечание: для работы виртуальных машин требуется, чтобы на компьютере была включена виртуализация VT-x или AMD-V в БИОС. Обычно она включена по умолчанию, но, если что-то пойдет не так, учитывайте этот момент.
Теперь давайте создадим свою первую виртуальную машину. В примере далее используется VirtualBox, запущенная в Windows, в качестве гостевой ОС (той, которая виртуализируется) будет Windows 10.
- Нажмите «Создать» в окне Oracle VM VirtualBox Менеджер.

- В окне «Укажите имя и тип ОС» задайте произвольное имя виртуальной машины, выберите тип ОС, которая будет на нее установлена и версию ОС. В моем случае — Windows 10 x64. Нажмите «Далее».

- Укажите объем оперативной памяти, выделяемой для вашей виртуальной машины. В идеале — достаточный для её работы, но не слишком большой (так как память будет «отниматься» от вашей основной системы, когда виртуальная машина будет запущена). Рекомендую ориентироваться на значения в «зелёной» зоне.

- В следующем окне выберите «Создать новый виртуальный жесткий диск».

- Выберите тип диска. В нашем случае, если этот виртуальный диск не будет использоваться за пределами VirtualBox — VDI (VirtualBox Disk Image).
- Укажите, динамический или фиксированный размер жесткого диска использовать. Я обычно использую «Фиксированный» и вручную задаю его размер.
- Укажите размер виртуального жесткого диска и место его хранения на компьютере или внешнем накопителе (размер должен быть достаточным для установки и работы гостевой операционной системы). Нажмите «Создать» и дождитесь завершения создания виртуального диска.

- Готово, виртуальная машина создана и отобразится в списке слева в окне VirtualBox. Чтобы увидеть информацию о конфигурации, как на скриншоте, нажмите по стрелке справа от кнопки «Машины» и выберите пункт «Детали».

Виртуальная машина создана, однако, если её запустить, вы не увидите ничего кроме черного экрана со служебной информацией. Т.е. создан пока только «виртуальный компьютер» и никакая операционной система на нём не установлена.
Установка Windows в VirtualBox
- Вставьте образ ISO в виртуальный привод DVD. Для этого выберите виртуальную машину в списке слева, нажмите кнопку «Настроить», перейдите в пункт «Носители», выберите диск, нажмите по кнопке с диском и стрелкой и выберите пункт «Выбрать образ оптического диска». Укажите путь к образу. Затем в пункте настроек «Система» в разделе «Порядок загрузки» установите «Оптический диск» на первое место в списке. Нажмите «Ок».

- В главном окне нажмите «Запустить». Запустится созданная ранее виртуальная машина, при этом загрузка будет выполнена с диска (с образа ISO), можно выполнить установку Windows так, как это делается на обычном физическом компьютере. Все шаги первоначальной установки аналогичны таковым на обычном компьютере, см. Установка Windows 10 с флешки.

- После того, как Windows была установлена и запущена, следует установить некоторые драйверы, которые позволят гостевой системе правильно (и без лишних тормозов) работать в виртуальной машине. Для этого выберите в меню «Устройства» — «Подключить образ диска дополнений VirtualBox», откройте компакт-диск внутри виртуальной машины и запустите файл VBoxWindowsAdditions.exe для установки этих драйверов. При ошибке подключения образа, завершите работу виртуальной машины и подключите образ из C:\ Program Files\ Oracle\ VirtualBox\ VBoxGuestAdditions.iso в настройках носителей (как в первом шаге) и снова запустите виртуальную машину, а затем произведите установку с диска.
По завершении установки и перезагрузки виртуальной машины она полностью будет готова к работе. Однако, возможно, вы захотите выполнить некоторые дополнительные настройки.

Основные настройки виртуальной машины VirtualBox
В настройках виртуальной машины (учтите, что многие настройки недоступны, пока виртуальная машина запущена) вы можете изменить следующие основные параметры:

- В пункте «Общие» на вкладке «Дополнительно» можно включить общий с основной системой буфер обмена и функцию Drag-n-Drop для перетаскивания файлов в гостевую ОС или из неё.
- В пункте «Система» — порядок загрузки, режим EFI (для установки на GPT диск), размер оперативной памяти, количество ядер процессора (не следует указывать число более количества физических ядер процессора вашего компьютера) и допустимый процент их использования (низкие значения часто приводят к тому, что гостевая система «тормозит»).
- На вкладке «дисплей» можно включить 2D и 3D ускорение, задать объем видеопамяти для виртуальной машины.
- На вкладке «Носители» — добавить дополнительные приводы дисков, виртуальные жесткие диски.
- На вкладке USB — добавить USB устройства (которые физически подключены к вашему компьютеру), например, флешку, к виртуальной машине (нажмите по значку USB с «плюсом» справа). Для использования контроллеров USB 2.0 и USB 3.0 установите Oracle VM VirtualBox Extension Pack (доступно для скачивания там же, где вы загружали VirtualBox).
- В разделе «Общие папки» можно добавить папки, которые будут общими для основной ОС и виртуальной машины.
Некоторые из указанных выше вещей можно выполнить и из запущенной виртуальной машины в главном меню: например, в пункт «Устройства» можно подключить флешку, извлечь или вставить диск (ISO), включить общие папки и т.п.
Дополнительная информация
В завершение — некоторая дополнительная информация, которая может оказаться полезной при использовании виртуальных машин VirtualBox.

- Одна из полезных возможностей при использовании виртуальных машин — создание «снимка» (snapshot) системы в её текущем состоянии (со всеми файлами, установленными программами и прочим) с возможностью отката к этому состоянию в любой момент (и возможностью хранить несколько снимков). Сделать снимок в VirtualBox можно на запущенной виртуальной машине в меню «Машина» — «Сделать снимок состояния». А восстановить в менеджере виртуальных машин, нажав «Машины» — «Снимки» и выбрав вкладку «Снимки».
- Некоторые комбинации клавиш по умолчанию перехватываются основной операционной системой (например, Ctrl+Alt+Del). Если вам требуется отправить подобное сочетание клавиш в виртуальную машину, используйте пункт меню «Ввод».
- Виртуальная машина может «захватывать» ввод клавиатуры и мышь (так, что нельзя перевести ввод на основную систему). Чтобы «освободить» клавиатуру и мышь, если потребуется, используйте нажатие хост-клавиши (по умолчанию это правый Ctrl).
- На сайте Майкрософт есть готовые бесплатные виртуальные машины Windows для VirtualBox, которые достаточно импортировать и запустить. Подробно о том, как это сделать: Как скачать бесплатные виртуальные машины Windows с сайта Майкрософт.
- При необходимости вы можете включить загрузку виртуальной машины VirtualBox с физической флешки или другого накопителя
А вдруг и это будет интересно:
- Лучшие бесплатные программы для Windows
- GlideX — смартфон или планшет в качестве второго монитора и другие возможности
- Как открыть Управление компьютером в Windows 11 и 10
- Appcopier — утилита резервного копирования настроек Windows 11 и 10
- Как определить тип файла без расширения или с неправильным расширением
- Панель эмодзи Windows 11 и 10 — как открыть и решение возможных проблем
- Windows 11
- Windows 10
- Android
- Загрузочная флешка
- Лечение вирусов
- Восстановление данных
- Установка с флешки
- Настройка роутера
- Всё про Windows
- В контакте
- Одноклассники
-
Александр 17.09.2021 в 18:46
- Dmitry 17.09.2021 в 19:17
Виртуалка своими руками. Как обфусцировать код при помощи виртуализации и что делать с такой защитой

Есть множество решений для защиты программ, которые определяют работу внутри изолированных сред, работают с антиотладочными приемами, контролируют целостность своего кода и динамически шифруют свои данные в памяти, защищаясь от дампа. Еще одна мощная техника защиты — это виртуализация кода. В этой статье я покажу, как она работает.
![]()
INFO
Читай другие статьи автора по теме дебага и защиты от него.
- Тайный WinAPI. Как обфусцировать вызовы WinAPI в своем приложении
- Детект песочницы. Учимся определять, работает ли приложение в sandbox-изоляции
- Антиотладка. Теория и практика защиты приложений от дебага
- Набор программ для взлома программ. Выбираем инструменты для реверса
Здесь я имею в виду не виртуальные машины вроде VirtualBox или VMware, а те, при помощи которых запутывают исполняемый код, чтобы затруднить анализ программной логики. В этой статье мы коснемся принципов работы виртуальных машин, компиляторов, трансляции кода, а также напишем свою виртуальную машину, которая будет понимать наш собственный язык программирования.
Итак, виртуальные машины, предназначенные для запутывания кода, основаны на идее замены «обычного» байт-кода, который, например, используется в архитектуре x86-64, на тот байт-код, который мы изобретем сами. Чтобы реконструировать поток управления в программе, подвергшейся виртуализации, необходимо проанализировать каждый опкод и разобраться, что он делает. Чтобы понимать, что происходит, нужно немного коснуться работы процессора — ведь, по сути, перед нами стоит задача «написать процессор».
Нам предстоит написать некое подобие транслятора-интерпретатора кода — чтобы исходный код, который мы будем писать, начал обрабатываться внутри нашей виртуальной машины. Можно провести аналогию с процессорами: современные процессоры представляют собой сложные устройства, которые управляются микрокодом. Многие наборы инструкций, особенно современные, типа Advanced Vector Extensions (AVX), — это, по сути, подпрограммы на микрокоде процессора, который, в свою очередь, напрямую взаимодействует с железом процессора.
Получается, что современные процессоры похожи больше на софт, а не на железо: сложные инструкции типа VBROADCASTSS , VINSERTF128 , VMASKMOVPS реализованы исключительно «софтверно» при помощи программ, состоящих из микрокодов. А таких наборов инструкций, как ты, возможно, знаешь, много — достаточно открыть техническое описание какого-нибудь Skylake и посмотреть на поддерживаемые наборы инструкций.
![]()
INFO
Микропрограммы процессора состоят из микроинструкций, а они, в свою очередь, реализуют элементарные операции процессора — операции, которые уже нельзя разделить на более мелкие, например работа с арифметико-логическим устройством (АЛУ) процессора: подсоединение регистров к входам АЛУ, обновление кодов состояния АЛУ, настройка АЛУ на выполнение математических операций.
Стековая виртуальная машина
Нам необходимо будет эмулировать, помимо работы процессора, работу памяти (RAM). Для этого мы воспользуемся реализацией собственного стека, который будет работать по принципу LIFO.
![]()
INFO
LIFO (last in, first out) — способ организации хранения данных, который похож на стопку журналов на столе: если нужный журнал лежит в середине стопки, нельзя его просто вытащить, можно только поочередно убирать журналы сверху и так до него добраться. Получается, мы всегда работаем только с верхушкой этой стопки.
В этом нет ничего сложного — по сути, это просто массив данных с указателем на них. Для наглядности код:
// Размер памяти VM const int MAXMEM = 5; // Массив памяти, который состоит из элементов типа int int stack[MAXMEM]; // Указатель на положение данных в стеке, сейчас стек не инициализирован int sp = -1;
Этот стек станет оперативной памятью нашей виртуальной машины. Чтобы путешествовать по нему, достаточно обычных операций с массивами:
stack[++sp] = data1; // Положим данные int data2 = stack[--sp]; // Возьмем данные
Далее, чтобы наша память не «сломалась», нам необходимо позаботиться о проверках, чтобы не срабатывали попытки взять данные, когда память пуста, либо положить больше данных, чем она может вместить.
// Проверка стека на пустоту // Функция вернет TRUE (1), если стек пуст, // и FALSE (0), если данные есть int empty_sp() < return sp == -1 ? 1 : 0; >// Проверка стека на заполненность // Функция вернет TRUE (1), если стек полон, // и FALSE (0), если место еще есть int full_sp()
Как видишь, никакой магии нет! Мы успешно запрограммировали память для нашей будущей VM. Далее переходим к командам. Создадим перечисление под названием mnemonics и заполним его инструкциями для нашей VM (читай комментарии):
// Поддерживаемые мнемоники VM typedef enum < // Положить значение на стек. Этот параметр имеет один аргумент PUSH = 0x00d00201, // Получить значение со стека. Берется верхушка стека POP = 0x00d00205, // Сложить два верхних значения стека ADD = 0x00d00202, // Вычесть два верхних значения стека SUB = 0x00d00206, // Поделить два значения DIV = 0x00d00203, // Перемножить два значения. Во всех четырех операциях результат кладется на стек MUL = 0x00d00204, // Ввести данные ENTER = 0x00d00211, // Сверка данных с шаблоном TEST = 0x00d00209, // Вывести верхушку стека PRINT = 0x00d00210, // Вывести все данные, которые находятся в нашей памяти RAM = 0x00d00208, // Завершить работу виртуальной машины EXIT = 0x00d00207 >mnemonics;
У каждой мнемоники есть значение в шестнадцатеричном формате, которое мы присвоили самостоятельно. Если бы мы не сделали этого, в перечислении все элементы были бы пронумерованы начиная с нуля с шагом в единицу. Зачем мы так поступили, я объясню позже, а мы теперь готовы написать программу, которая состоит из наших инструкций, я также ее прокомментирую.
// Исполняемый код const int code[] = < PUSH, 22, // Кладем на стек 22 PUSH, 45, // Кладем на стек 45 RAM, // Выводим содержимое памяти SUB, // Вычитание POP, // Вытащить результат из стека PUSH, 23, // Кладем на стек 23 PUSH, 9, // Кладем на стек 9 PUSH, 5, // Проверка на ошибку RAM, // Выводим содержимое памяти PRINT, // Выводим верхушку стека ADD, // Сложение POP, // Вытащить результат PUSH, 7, // Кладем на стек 7 PUSH, 7, // Кладем на стек 7 RAM, // Выводим содержимое памяти ADD, // Сложение POP, // Вытащить результат POP, // Проверка на ошибку ENTER, // Ввод данных PRINT, // Выводим верхушку стека TEST, // Проверяем данные EXIT // Остановка VM >;
Как видишь, это такой же простой массив. Единственное, что может немного смутить, — манера записи, но это лишь для наглядности.
Кроме того, нам понадобится еще одна переменная, чтобы перемещаться по коду в случае необходимости.
int ip = 0; // Указатель на инструкцию (мнемонику)
Теперь мы подошли к самому интересному — основному циклу виртуальной машины. Именно этот цикл оживит наши инструкции и придаст им смысл. Я приведу полный листинг с комментариями.
// Трансляция кода VM void decoder(int instr) < switch (instr) < case PUSH: < // Проверяем, есть ли место в памяти if (full_sp()) < printf("Memory is full\n"); break; >// Перемещаемся в свободную ячейку памяти sp++; // В массиве кода берем следующее за мнемоникой PUSH значение // и кладем его в ячейку памяти stack[sp] = code[++ip]; break; > case POP: < // Проверка памяти на пустоту if (empty_sp()) < printf("Memory is empty\n"); break; >// Берем значение с верхушки стека int pop_value = stack[sp--]; // и выводим его printf("Result: %d \n", pop_value); break; > case ADD: < // Берем два верхних значения стека int a = stack[sp--]; int b = stack[sp--]; sp++; // Складываем их и кладем результат на стек stack[sp] = b + a; // Выводим сообщение printf("ADD->"); break; > case SUB: < // Берем два верхних значения стека int a = stack[sp--]; int b = stack[sp--]; sp++; // Вычитаем их и кладем результат на стек stack[sp] = a - b; // Выводим сообщение printf("SUB->"); break; > case DIV: < // Берем два верхних значения стека int a = stack[sp--]; int b = stack[sp--]; sp++; // Делим их и кладем результат на стек stack[sp] = a / b; // Выводим сообщение printf("DIV->"); break; > case MUL: < // Берем два верхних значения стека int a = stack[sp--]; int b = stack[sp--]; sp++; // Перемножаем их и кладем результат на стек stack[sp] = a * b; // Выводим сообщение printf("DIV->"); break; > case RAM: < // Это простой цикл вывода всех значений массива int x = sp; for (; x >= 0; --x) < printf("RAM[%u]: %u\n", x, stack[x]); >break; > case TEST: < // Сверка верхнего значения стека с числом 0x31337 // Если числа совпадают, выводится сообщение «Good Pass!», // иначе «Bad Pass!» stack[sp--] == 0x31337 ? printf("Good Pass!\n") : printf("Bad Pass!\n"); break; >case PRINT: < printf("PRINT Stack[%u]: %u\n", sp, stack[sp]); break; >case ENTER: < printf("ENTER Password: "); // Перемещаемся вверх по памяти // и при помощи scanf_s записываем данные в наш массив // Введенные данные окажутся на верхушке массива sp++; scanf_s("%i", &stack[sp]); break; >case EXIT: < // Установка глобальной переменной в FALSE, // чтобы прервать работу VM VM = false; printf("Exit VM\n"); break; >> >
Разумеется, это не самый стабильный код в мире, и можно добавить еще разные проверки для повышения стабильности, но я попытался найти золотую середину между сложностью кода и легкостью его восприятия.
Итак, мы реализовали команды виртуальной машины. Давай теперь ее запустим!
int main() < while (VM) < // Переменная, которая контролирует работу VM decoder(code[ip]); ip++; >system("pause"); >
Надо сказать, что я установил значение переменной MAXMEM равным единице, чтобы память VM вмещала только два значения. Нам все равно больше не нужно, но это полезно для демонстрации работы функций, которые контролируют переполнение или опустошение памяти. Вот скриншот работы виртуальной машины.


Другие статьи в выпуске:
Xakep #239. Вскрыть и изучить
- Содержание выпуска
- Подписка на «Хакер» -60%
Вроде бы все работает как надо. Теперь давай посмотрим, как распутывать код, который спрятан внутри подобной виртуалки.
На самом деле все очень просто: нужно загрузить этот файл в дизассемблер, найти наш цикл switch/case и посмотреть на места, где происходит сравнение с нашими константами-инструкциями. Заглянув в каждое ветвление после сравнения с константой, можно определить, за что отвечает эта константа-инструкция.
В итоге можно написать автоматический скрипт, прогон которого будет раскладывать весь наш байт-код и давать верные имена подпрограммам, которые представляют инструкции виртуальной машины. Получается, потратив некоторое время на анализ виртуальной машины, можно потом написать универсальный скрипт, который будет «снимать» эту VM с любой программы. Мы ведь будем знать все значения констант-инструкций! Но это не совсем так.
Помнишь перечисление mnemonics , в котором мы присваивали значения нашим командам? Я обещал еще вернуться к нему. Его можно записать немного по-другому:
static unsigned long time = (unsigned int)__TIMESTAMP__; #define time x typedef enum < // Положить значение на стек. Этот параметр имеет один аргумент PUSH = 0x00d00201 ^ x, // Получить значение со стека. Берется верхушка стека POP = 0x00d00205 ^ x, // Сложить два верхних значения стека ADD = 0x00d00202 ^ x, // Вычесть два верхних значения стека SUB = 0x00d00206 ^ x, // Поделить два значения DIV = 0x00d00203 ^ x, // Перемножить два значения. Во всех четырех операциях результат кладется на стек MUL = 0x00d00204 ^ x, // Ввести данные ENTER = 0x00d00211 ^ x, // Сверка данных с шаблоном TEST = 0x00d00209 ^ x, // Вывести верхушку стека PRINT = 0x00d00210 ^ x, // Вывести все данные, которые находятся в нашей памяти RAM = 0x00d00208 ^ x, // Завершить работу виртуальной машины EXIT = 0x00d00207 ^ x, >mnemonics;
Ничего необычного, просто операция xor (побитовое исключающее ИЛИ) применяется к каждому значению кодов наших мнемоник. Но обрати внимание на то, как инициализируется эта переменная.
static unsigned long time = (unsigned int)__TIMESTAMP__;
Мы используем предопределенную константу __TIMESTAMP__ , приводим ее в число и берем его для xor. Эта константа берет время компиляции, поэтому для каждой скомпилированной программы значения операций будут отличаться. При таком раскладе становится сложнее написать универсальный скрипт, разбирающий VM в автоматическом режиме.
Заключение
В этой статье мы рассмотрели, как можно сделать собственную виртуалку, которая будет исполнять наш исходный код. Конечно, в серьезных коммерческих виртуальных машинах, которые используются в протекторах, все намного сложнее, но это первое приближение — демонстрация того, с чем придется сталкиваться, когда нужно будет дизассемблировать подобные защитные механизмы.