
                       НЕКОТОРЫЕ МЫСЛИ О МЕТАМОРФИЗМЕ

     Недавно  возникла  маразматическая  мысль о вирусе, состоящем из одних
 NOP'ов.  Идея  тут  вот  в  чем.  Пусть  существует  обычная  компьютерная
 программа,  такая,  что  ее  код  содержит в себе последовательно, одну за
 другой,  те  же  самые  инструкции  и группы инструкций (или их варианты),
 которые могут быть использованы в некотором вирусе. Тогда достаточно будет
 забить  NOP'ами  все  оставшиеся  инструкции,  чтобы  эта  программа стала
 вирусом.  Таким  образом,  с точки зрения внесенных изменений, в программу
 были  записаны исключительно NOPы, и ничего более. Сам же вирус скрывается
 в том, _как_, то есть в какие места программы были записаны эти NOP'ы. При
 этом,  это может быть не одна программа, а программа со всеми ее DLL'ками;
 и  кроме  того,  в программу можно записывать не только NOP'ы, но и прочий
 мусор.  Другими  словами,  стандартное  заражение  путем  добавления новых
 инструкций  здесь  изменено  на  удаление ненужных. Конечно, тут возникнут
 некоторые  трудности  с  константами.  Но я ведь не доктор -- если вас это
 прикалывает, сами что-нибудь и придумайте.
     Куда  более интересны следствия из анализа той техники, которую мог бы
 использовать такой вирус.
     И  действительно, вирусы ведь состоят из небольших кусочков кода -- по
 одной-две инструкции, и каждый из таких элементов дублируется по многу раз
 не  только  в вирусах, но и в обычных программах; причем, и это главное, в
 разных вариантах.
     Предположим теперь, что в вирусе хранится по несколько хешей на каждый
 вариант  такого элемента. И вирус постоянно ищет свои возможные элементы в
 коде  тех  программ, которые найдет; и подключает к себе эти элементы, при
 этом затирая подключенные ранее варианты этих элементов.
     То  есть,  говоря  проще,  вирус  весь  состоит из небольших элементов
 (блоков  кода),  и  пусть,  например,  варианты  одного  из этих элементов
 выглядят так:

   вариант 1       вариант 2       вариант 3       вариант 4     вариант N

 mov eax, [ecx]  mov edx, [ecx]  mov eax, ecx    push [ecx]       ...
 mov edx, eax    mov eax, edx    mov edx, [eax]  mov edx, [esp]   ...
                                 mov eax, edx    pop eax

     Таким образом, касательно одного блока кода, в вирусе будет хранится N
 хешей  для  каждого  из  его вариантов, и, естественно, последний из таких
 найденных вариантов, в настоящий момент и работающий.
     В результате возникает неопределенность в модификациях вируса, так как
 заранее  неизвестно,  из каких в точности инструкций эти модификации будут
 состоять.
     Чем  больше  вариантов  каждого элемента (и, соответственно, их хешей)
 будет  предусмотрено,  и чем больше будет длина и время вычисления каждого
 хеша,  тем  сложнее  будет  получить  исчерпывающую  информацию  обо  всех
 возможных модификациях такого вируса.
     Самая  суть этого метода заключается в том, что "определение", то есть
 получение   полной   информации   обо   всех  состояниях   такого   вируса
 распределяется во времени.
     И  даже больше. Вовсе необязательно, чтобы вирус изначально содержал в
 себе  _все_  элементы. Некоторае часть особо интересных подпрограмм такого
 вируса может отсутствовать, и срабатывать только при нахождении хешей всех
 элементов  этих  подпрограмм.  Таким  образом  станет  неизвестно, когда и
 какая  подпрограмма  вируса  сработает, а также - что это за подпрограмма.
 Похожую  мысль  высказывали  уже давно, когда предлагали зашифровать часть
 вируса куском некоторого определенного биоса. Однако, как мне кажется, то,
 что предлагается здесь - чуть более актуально.
     Здесь  есть одна интересная фича: некоторые из элементов "нормальные",
 а некоторые - "мусорные". И в плане добавления именно мусорных, не имеющих
 влияния   на   выполнение   вируса   элементов,  есть  огромное  поле  для
 экспериментов.
     Где  будут  хранится  хеши? Хеши могут хранится в зашифрованном виде в
 самом   вирусе;   достаточно   большая   база   хешей   может   хранится в
 распределенном  виде,  когда  носителями являются интернетовские машины; и
 эти  хеши,  что  более интересно, могут подключаться так же, как и обычные
 вирусные  плугины.  Но  что  значит  -  подключить  десяток хешей к такому
 вирусу?   А   это   значит,   что  у  антивирусов  появится  потенциальная
 возможность  пропустить  уже  хотя  бы один зараженный файл -- из которого
 потом вновь разовьется эпидемия.
     Как  разбить  вирус на элементы? Если вирус пишется на ассемблере, это
 придется  делать  руками.  Если вирус пишется на hll, то это проще сделать
 автоматически: например компилять из c++ в ассемблер.
     Какими должны быть элементы? Понятно, что они должны состоять из целых
 инструкций,  поскольку множество комбинаций этих инструкций крайне велико:
 очень  много  программ,  и  как  минимум половина их "объема" - это код. В
 принципе,  длины  элементов  не  ограничены  ни  чем.  Однако,  есть  одна
 трудность.  Для  хорошей  "морфности" такого вируса, в нем должно быть два
 типа  вариантов  элементов. Несколько вариантов -- те, которые встречаются
 очень   часто;  для  того,  чтобы  у  вируса  была  возможность  постоянно
 изменяться;  см.выше  - номера 1,2,3. Оставшаяся же часть вариантов -- это
 те  куски  кода,  которые встречаются достаточно редко. Для того, чтобы их
 было  сложно  найти,  но вместе с тем и существовала вероятность того, что
 они будут найдены. Например - что-нибудь вроде варианта 4.
     Также,  вместо  того,  чтобы искать возможные элементы в файлах, можно
 пытаться подобрать их случайным образом.

     Написать  вирус,  полностью  состоящий  из  таких  элементов,  сегодня
 достаточно  сложно. Однако, не будем забывать о том, что метаморфный вирус
 --  это просто большой полиморфик, в котором декриптор, со временем, вырос
 до  размеров  всего вируса и генерит сам себя. Другими словами, завтра это
 будет  сделано;  а  сегодня мы запросто можем применить идею о элементах к
 генерации   если  не  всего  вируса,  то  хотя  бы  простого  полиморфного
 декриптора.   Поскольку   наилучшей  антиэвристической  техникой  является
 интеграция  кода, к ней и следует применить то, что описано в этом тексте.
 Таким  образом  в  середине  зараженного  файла будет находится декриптор,
 состоящий из элементов, нахождение которых потребует много времени.

                                   * * *
