НЕКОТОРЫЕ МЫСЛИ О МЕТАМОРФИЗМЕ Недавно возникла маразматическая мысль о вирусе, состоящем из одних 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. Также, вместо того, чтобы искать возможные элементы в файлах, можно пытаться подобрать их случайным образом. Написать вирус, полностью состоящий из таких элементов, сегодня достаточно сложно. Однако, не будем забывать о том, что метаморфный вирус -- это просто большой полиморфик, в котором декриптор, со временем, вырос до размеров всего вируса и генерит сам себя. Другими словами, завтра это будет сделано; а сегодня мы запросто можем применить идею о элементах к генерации если не всего вируса, то хотя бы простого полиморфного декриптора. Поскольку наилучшей антиэвристической техникой является интеграция кода, к ней и следует применить то, что описано в этом тексте. Таким образом в середине зараженного файла будет находится декриптор, состоящий из элементов, нахождение которых потребует много времени. * * *