О ТОМ, КАК НАЕБНУТЬ ЭВРИСТИК (глюки и бред) Рассмотрим такое действо: антивир проверяет исполняемый файл. Что это значит? Это значит, что антивир берет файл, и, начиная с некоторых мест, эмулирует инструкцию за инструкцией. Во время же эмуляции, при некоторых условиях, происходит проверка предыдущих/текущих/последующих инструкций по базе сигнатур, а также эвристическая проверка. Что это за места, с которых может начинаться эмуляция? Это обязательно точка входа, и, в дополнение к ней, например, некоторое смещение от конца файла, начало кодовой секции, конец кодовой секции, код в заголовке файла, адреса всех импортируемых/экспортируемых процедур и все что угодно. Почему так? Потому что есть такая вещь как UEP, то бишь Unknown Entry Point, которую проклятые антивирусники почему-то обозвали Entry Point Obscuring -- наверное, обскуринг ближе к их продажным сердцам. В кратце -- это не замена точки входа на вирусную, а вставка перехода на вирус в случайное место программы. В результате по точке входа зараженного файла находится то же, что было до заражения. А вирус срабатывает не сразу, а в середине работы программы. Но, поскольку, вирус-то должен быть куда-то записан, а место это зачастую алгоритмически фиксировано -- например это всегда последняя секция файла, то оттуда антивир и начинает эмуляцию, и незачем ему искать на это место переход. Правда, обходится это как два пальца обоссать (неужели кто-то пробовал), например так: перед jmp'ом на вирус вставляется эквивалент , от коих зависит последующая расшифровка. Что значит эмулирует? Значит, антивир имитирует работу процессора и операционной системы, под которыми могла бы быть запущена эта программа. Если в процессе эмуляции возникает вирусная активность, антивир начинает нехорошо вонять, тем самым подзывая юзера. Если тело вируса было зашифровано, в процессе эмуляции оно имеет возможность расшифроваться и подставить под грязные лапы эмулятора самое сокровенное. Но и это не проблема, потому что ни секции, ни страницы, ни фиксапы, ни форматы файлов, ни даже сопроцессор, ни уж тем паче ммх, ни файлы, ни апишки, ни инты ни даже idiv эмуляторами не берутся. А что такое проверка по базе сигнатур? Это просто сравнение некоторых постоянных мест кода с уже известными антивирусу. Обычный антивирус "знает" около 10-20 тысяч разных вирусов. Так что самая обычная проверка выглядит так: для каждой инструкции, которая является меткой (на которую был переход командой jmp/jxx/call), отсчитав X байт до участка длиной Y байт посчитать контролькую сумму и сравнить с известной. Совпало - вирус. Антивирусы достигают б'ольших скоростей проверок тем, что "стандартизируют" указанные X и Y, тем самым уменьшая число операций. В случае, если вирус сложный, участков для проверки контрольных сумм (сигнатур) может быть несколько. Иногда, на проверяемый участок задают битовую маску, кояя говорит, какие байты при подсчете оставить, а какие выкинуть. Надо это тогда, когда в вирусе нет длинных постоянных участков кода. В случае же еще более сложного вируса, антивирус "цепляется" к какому-нибудь значительному признаку, например команде PUSHA, кояя для большинства файлов не характерна, и затем происходит сложная, обстоятельная, занимающая много времени, попытка детектировать вирус. В таких сложных случаях антивирусу приходится работать не на уровне байтов, а на уровне <множеств инструкций>. То происходит проверка на множество инструкций A, из которых вирус может состоять, на множество инструкций B, из которых вирус состоять не может, и на дополнительные признаки. Это сложная, нетривиальная задача, которую решить становится все труднее. И это правильно. Кстати, каспер даже делает два _перекрывающихся_ участка сигнатур (вот гнида), чтобы было сложнее их подъебнуть. К слову, где-то у меня на страничке валялись 6900 файлов - специально сгенеренных ложных срабатываний авп, и около 2000 для веба. Лирическое отступление. Вернемся к нашим антивирусникам. г-н Касперский лижет жопу только Биллу Гейцу. г-ну Касперскому пытается полизать некий г-н Каримов, но каспер ловко уворачивается. Поэтому г-н Каримов подымает хайло на г-на Данилова, а тот-то лижет жопу исключительно сам себе, поэтому и с ним ничего не получается. В создавшейся ситуации г-н Каримов на крови клянется выступить по первому каналу телевидения с обличительной речью (ждем), данилов продолжает лично писать эвристик, а каспер - набирать на работу всяких гандонов, чтобы поддерживали вирусы и пакеры. Исходя из этого, правильно в первую очередь тестировать вирусы эвристиком от веба, а потом - на всякий случай - от авпа. После того, как вы добьетесь от обоих консенсуса (в виде надписи Ok), можете смело выпускать вирус в жизнь, и 273-я ждет вас. ;-) А теперь перейдем к самому главному - к тому, как выебать эвристический анализатор. Самое первое, самое простое, самое общее и самое главное правило гласит: чем меньше вирус похож на все остальные вирусы и чем больше он похож на обычные программы, тем меньше шанс срабатывания эвристики. Здесь критерием сравнения является наличие в зараженном файле характерных особенностей, известных антивирусу. Например: Я, конечно, мог бы вам здесь привести все такие особенности, но ебли будет много, а толку - хуй; да и потом, куда приятней просто попиздить ни о чем. Спать, уткнувшись лицом в клавиатуру - наиотвратительнейшее занятее; и тот не вирмэйкер, кто никогда проснувшись не чувствовал на своей собственной морде вмятых следов от клавиш. Зато просыпаешься под winamp. Кстати, рекомендую исключительно всем слушать музыку группы Scorpions -- например такая вещь, как Alien Nation, да на полной громкости, сделает мозги -- ваши и ваших соседей (на два-три этажа) -- готовыми к употреблению любого количества асма и прочей поебени. Ладно, вернемся к эвристику. Идеальный эвристик - суть нейронная сетка, натренированная на опознавание всех известных вирусов и неопознавание всех известных программ. Пусть сенсорами являются кусочки некого алгоритма, распознающие те или иные свойства объекта - вируса или программы. О каждом из этих свойств мы будем знать тогда некое число. Чем больше свойств - тем лучше. Вполне возможно чтобы свойства задавал человек; однако я считаю идеальным определять их также автоматически, рассматривая объекты как наборы инструкций и параллельно - функциональных вызовов. Ну да хуй с ними. Важно вот что. Пусть есть N критериев, и на каждый по числу. Это суть вектор, коим и будет определяться рассматриваемый объект с точки зрения нейронной сетки. И задачей сетки будет выдать результат - число от 0 до 1 включительно, определяющее вероятнось принадлежности объекта к вирусам либо программам. Ясно, что ровно 0 и 1 будут соответствовать какому-то из известных объектов, на котором сетка обучалась. Можно пойти еще дальше, и выдавать не одно значение, а сразу с многих выходных нейронов снимать компоненты вектора, определяющие отношение распознанного объекта к программам, вирусам, tsr-вирусам, com-вирусам, и прочим сущностям, на коих сетка будет обучена отдельно. В рассмотренном случае все пространство N-мерно, и нечетко поделено на области программ, вирусов и прочих классов. И сетка будет просто определять расстояния между N-мерным вектором, определящим рассматриваемый объект, и ближайшими к нему векторами известных объектов; и на основе разностей этих векторов строить результат. На практике это выглядит так: некой проге на вход подаются 10 тысяч вирусов и 10 тысяч обычных программ, она их все заглатывает, переваривает, и высирает некий файл данных. Затем, при проверке, прога, используя этот же файлик, определяет сходство проверяемого объекта с уже известными и говорит вероятность попадания в класс вирусов. Юзер ставит планку: 70% "похожести" -- пиздец. Но до таких мудрствований данилову с каспером крайне далеко, так что не будем забивать себе голову хуйней. Обходится такая "идеальная" эвристика максимально возможной "подстройкой" под уже известную "хорошую" программу, а также обманом "сенсоров": сокрытием вирусного кода в коде программы. И, напоследок, замечу: написание практически недетектируемого вируса - дело ближайшего года-двух. * * *