# Подготовка проекта

Для примера рассмотрим простейшее приложение, состоящее из одной формы (Form1), элемента ввода текста (Edit1) и кнопки (Button1). Работа приложения заключается в следующем: при нажатии на кнопку Button1 проверяется корректность введенного пароля и при этом выдается соответствующее сообщение.

Пароль проверяется по простейшему алгоритму: сначала он преобразуется в число, после чего определяется остаток от деления данного числа на 17. Пароль считается правильным, если остаток от деления числового представления пароля на 17 равен 13. Процедура проверки пароля на языке программирования Delphi реализуется следующим образом:

    function TForm1.CheckPassword: Boolean;
    begin
      Result:=(StrToIntDef(Edit1.Text, 0) mod 17=13);
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    begin
      if CheckPassword then
       MessageDlg('Correct password', mtInformation, [mbOK], 0)
      else
       begin
        MessageDlg('Incorrect password', mtError, [mbOK], 0);
        Edit1.SetFocus;
       end;
    end;

Выбор защищаемых процедур и функций может осуществляться тремя способами:

- С использованием MAP-файла, который формируется компилятором при создании исполняемого модуля программы. В MAP-файле содержится вся необходимая информация об именах и адресах всех процедур и функций приложения. В случае использования MAP-файла при работе с VMProtect выбор защищаемых процедур и функций может осуществляться по имени. Используя МАР-файл, после перекомпиляции проекта VMProtect автоматически определит новые адреса процедур и функций.
- С использованием маркеров, которые вставляются в исходный код приложения. Маркеры представляют собой специальные метки, по которым VMProtect определяет границы защищаемого блока. Также VMProtect поддерживает маркеры с предустановленным типом компиляции. Использование маркеров целесообразно, если следует защитить только часть процедуры или функции. При использовании маркеров можно указать части кода, в которых в дальнейшем можно будет защитить строковые константы.
- По адресам защищаемых процедур в исполняемом файле. По сравнению с предыдущими данный способ менее удобен в использовании, так как при любой доработке программы и, соответственно, ее перекомпиляции будет необходимо определять все адреса повторно. Данный способ рекомендуется лишь для защиты программных продуктов, для которых отсутствуют исходные тексты.

Использование MAP-файла для определения границ защищаемого кода имеет еще один важный плюс, который требует отдельного рассмотрения. Почти любая процедура или функция, обладающая локальными переменными или использующая стек для хранения регистров и/или промежуточных результатов вычислений, имеет так называемые пролог и эпилог, находящиеся соответственно в начале и в конце скомпилированной процедуры или функции:

    push ebp      \
    mov ebp, esp   \ пролог
    push 00        /
    push ebx      /

    ...

    pop ebx       \
    pop ecx        \ эпилог
    pop ebp        /
    ret           /

Из-за особенностей реализации современных компиляторов маркеры кода никогда не охватывают пролог и эпилог (даже если маркерами будет охвачен весь текст функции CheckPassword, находящийся между begin и end). Для взлома будет достаточно откорректировать пролог функции таким образом, чтобы виртуалированный код не был выполнен. Для функции CheckPassword это можно сделать следующим образом:

    mov eax, 1
    ret

Важно:
Если для выбора виртуализированных участков кода используется MAP-файл, то пролог и эпилог будут тоже завиртуализированы, что повысит защищенность программы. Более того, если одна виртуализированная функция вызывается из другой виртуализированной функции, то передача управления между ними будет осуществлена без перехода на адрес вызываемой функции (вызов будет представлять собой простой переход на другой адрес байт-кода внутри исполнителя виртуальной машины), что также повысит степень защищенности программы, так как внесенные взломщиком в точку входа корректировки окажутся бесполезными. При работе с виртуализированными функциями передача управления точке входа в завиртуализированную функцию будет осуществлена лишь в случае вызова защищенной функции из незащищенного или промутированного участка кода.

© 2006-2015 Copyright VMProtect Software