p align="left">Блок 3 помещает в виртуальный регистр или переменную (обозначим ее как A3) константу, участвующую в преобразовании. Эта константа, возможно, затем и не будет использована для преобразования данных, все зависит от того, какой код будет сгенерирован. Блок 3 может быть повторен несколько раз. Над данными осуществляется целый набор различных преобразований, и в каждом из них участвуют различные регистры/переменные, инициализированные в блоке 3. Блок 4 можно назвать основным. Именно он, а, точнее сказать, набор этих блоков производит шифрование/расшифрование данных. Количество этих блоков случайно и равно количеству блоков номер 3. При преобразованиях не обязательно будет использовано значение из A3. Например, вместо A3 может использоваться константа или значение из счетчика. На данный момент полиморфный генератор поддерживает 3 вида преобразований: побитовое "исключающее или" (XOR), сложение и вычитание. Набор этих преобразование можно легко расширить, главное, чтобы такое преобразование имело обратную операцию. Блок 5 служит для увеличения A1 на единицу. Как и во всех других блоках эта операция может быть выполнена по-разному, то есть с использованием различных элементарных инструкций виртуальной машины. Блок 6 организует цикл. Он уменьшает значение A2 на единицу, и если результат не равен 0, то виртуальная машина переходит к выполнению четвертого блока. На самом деле управление может быть передано на один из холостых блоков между блоком 3 и 4, но с функциональной точки зрения это значения не имеет. Блок 7 производит проверку ограничения по времени использования алгоритма. Код по проверке на ограничение по времени относится к холостым командам и, на самом деле, может присутствовать и выполнятся в коде большое количество раз. То, что он относится к холостым блокам кода вовсе не значит, что он не будет нести функциональной нагрузки. Он будет действительно проверять ограничение, но он, как и другие холостые блоки, может располагаться произвольным образом в пустых промежутках между функциональными блоками. Поскольку этот блок может теоретически никогда не встретиться среди холостых блоков, то хоть один раз его следует выполнить. Именно поэтому он и вынесен как один из функциональных блоков. Если же при генерации алгоритма от генератора не требуется ограничение по времени, то в качестве аргумента к виртуальной команде проверки времени используется специальное число. Блок 8 завершает работу алгоритма.
3.2.2. Виртуальная машина для выполнения полиморфных алгоритмов Для начала приведем список инструкций, поддерживаемых на данный момент виртуальной машиной. Коды этих инструкций имеют тип E_OPERATION и определены в файле p_enums.h следующим образом: enum E_OPERATION // Инструкции { EO_ERROR = -1, // Недопустимая инструкция EO_EXIT_0, EO_EXIT_1, EO_EXIT_2, // Конец работы EO_NOP_0, EO_NOP_1, EO_NOP_2, EO_NOP_3, // Пустые команды EO_TEST_TIME_0, EO_TEST_TIME_1, // Контроль времени EO_MOV, EO_XCHG, // Пересылка данных EO_PUSH, EO_POP, // Работа со стеком EO_XOR, EO_AND, EO_OR, EO_NOT, // Логические операции EO_ADD, EO_SUB, EO_MUL, EO_DIV, EO_NEG, // Арифметические операции EO_INC, EO_DEC, EO_TEST, EO_CMP, // Операции сравнения // (влияют на флаги) EO_JMP, EO_CALL, EO_RET, // Операторы безусловного перехода EO_JZ, EO_JNZ, EO_JA, EO_JNA, // Условные переходы }; В таблице 1 приведена информация по этим инструкциям и перечислены их аргументы. Таблица 1. Описание инструкций виртуальной машины. |
Название | Действие | | EO_EXIT_0 EO_EXIT_1 EO_EXIT_2 | Команды завершения работы. После ее выполнения виртуальная машина остановится, и управление будет передано выше. Данные инструкции аргументов не имеют. | | EO_TEST_TIME_0 EO_TEST_TIME_1 | Команды контроля времени. Имеют один аргумент - последний доступный день использования. | | EO_MOV | Команда пересылки данных. Имеет два аргумента - источник и получатель. | | EO_XCHG | Данная команда обменивает значения двух регистров или ячеек памяти, переданных в двух аргументах. | | EO_PUSH | Сохраняет переданный аргумент в стеке. | | EO_POP | Снимает значение с вершины стека и помещает в указанную ячейку памяти или регистр. | | EO_XOR | Логическая операция XOR. Имеет два аргумента. Результат помещается в ячейку памяти или регистр, переданный в качестве первого аргумента. | | Название | Действие | | EO_AND | Логическая операция AND. Имеет два аргумента. Результат помещается в ячейку памяти или регистр, переданный в качестве первого аргумента. | | EO_OR | Логическая операция OR. Имеет два аргумента. Результат помещается в ячейку памяти или регистр, переданный в качестве первого аргумента. | | EO_NOT | Логическая операция NOT. Имеет один аргумент. Результат помещается в ячейку памяти или регистр, переданный в качестве аргумента. | | EO_ADD | Арифметическая операция сложения. Имеет два аргумента. Результат помещается в ячейку памяти или регистр, переданный в качестве первого аргумента. | | EO_SUB | Арифметическая операция вычитания. Имеет два аргумента. Результат помещается в ячейку памяти или регистр, переданный в качестве первого аргумента. | | EO_MUL | Арифметическая операция умножения. Имеет два аргумента. Результат помещается в ячейку памяти или регистр, переданный в качестве первого аргумента. | | EO_DIV | Арифметическая операция деления. Имеет два аргумента. Результат помещается в ячейку памяти или регистр, переданный в качестве первого аргумента. | | EO_NEG | Арифметическая операция изменения знака. Имеет один аргумент. Результат помещается в ячейку памяти или регистр, переданный в качестве аргумента. | | EO_INC | Увеличивает значение ячейки памяти или регистра на единицу, передаваемой в единственном аргументе. | | EO_DEC | Уменьшает значение ячейки памяти или регистра на единицу, передаваемой в единственном аргументе. | | EO_TEST | Операция сравнения двух аргументов на равенство. Если аргументы равны, то флаг ZERO выставляется в true, в противном случае в false. | | EO_CMP | Операция сравнения двух аргументов. Если аргументы равны, то флаг ZERO выставляется в true, в противном случае в false. Если первый аргумент меньше второго, то флаг ABOVE выставляется в true, в противном случае в false. | | Название | Действие | | EO_JMP | Данная инструкция осуществляет безусловный переход по адресу, указанному в качестве аргумента. | | EO_CALL | Данная инструкция осуществляет вызов функции по адресу, указанному в качестве аргумента. | | EO_RET | Данная инструкция возвращает управление предыдущей функции. Аргументов нет. | | EO_JZ | Условный переход по адресу, указанному в качестве аргумента. Условием является ZERO == true. | | EO_JNZ | Условный переход по адресу, указанному в качестве аргумента. Условием является ZERO == false. | | EO_JA | Условный переход по адресу, указанному в качестве аргумента. Условием является ABOVE == true. | | EO_JNA | Условием является ABOVE == false. | | |
Отметим, что аргументы могут быть следующих типов: EOP_REG - Регистр EOP_REF_REG - Память по адресу в регистре. EOP_VAR - Переменная. EOP_REF_VAR - Память по адресу в переменной. EOP_CONST - Константное значение. EOP_RAND - Случайное число. Перечисленные типы объявлены в файле p_enums.h. Для примера, приведем как будет выгладить код сложения регистра N 1 с константой 0x12345: DWORD AddRegAndConst[] = { EO_ADD, EOP_REG , 1, EOP_CONST, 0x12345 }; Для наглядной демонстрации, как происходит выполнение кода в виртуальной машине при шифровании/расшифровании данных, приведем отрывок из отладочного отчета. Каждое действие в отладочном режиме протоколируется в файле uniprot.log. Благодаря этому, было легко отлаживать механизм генерации полиморфных алгоритмов и саму работу алгоритмов. Дополнительным результатом создания механизма протоколирования стала возможность показать, как происходит выполнение алгоритма шифрования расшифрования. Ниже приведен отрывок из файла uniprot.log, относящийся к процессу шифрования данных. С целью сокращения объема текста, убраны дублирующийся вывод внутри цикла. Также при генерации этого алгоритма были выставлена вложенность шифрования равная единицы и почти убраны холостые блоки. === Start TranslateOperations === mov RAND ==> REG_2 xchg REG_2 VAR_16 <==> REG_2 VAR_16 mov CONST ==> VAR_11 dec VAR_11 ==> VAR_11 cmp VAR_11 CONST jnz CONST mov RAND ==> REG_6 xchg VAR_14 VAR_12 <==> VAR_14 VAR_12 mov CONST ==> VAR_15 add VAR_15 VAR_18 ==> VAR_15 mov RAND ==> REG_4 mov CONST ==> VAR_19 add VAR_19 VAR_9 ==> VAR_19 add REG_8 REG_7 ==> REG_8 xchg REG_2 VAR_13 <==> REG_2 VAR_13 Эта часть повторяется много раз: mov RAND ==> REG_6 xor REF_VAR_11 VAR_14 ==> REF_VAR_11 mov RAND ==> REG_4 mov RAND ==> REG_9 xor REF_VAR_11 VAR_15 ==> REF_VAR_11 sub VAR_11 CONST ==> VAR_11 mov RAND ==> REG_7 dec VAR_14 ==> VAR_14 cmp VAR_14 CONST jnz CONST ………….. mov RAND ==> REG_1 add REG_9 REG_6 ==> REG_9 test_time1 VAR_10 OK TIME (continue) exit
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
|