Как реализовать защиту от эвристического анализа
Очевидно, вирус не будет найден в памяти, если разместить обработчик INT 21h в той ее части, в которую загружаются пользовательские программы. С другой стороны, наш вирус помещает свой код в самые старшие адреса основной памяти. Единственным выходом из положения было бы написание обработчика, состоящего из двух частей. При этом "первая" часть должна загружаться в область памяти,выделенную для загрузки прикладных программ,а "вторую" - вместе с остальной частью вируса - следует записать в старшие адреса основной памяти. В случае возникновения прерывания INT 21h управление будет передаваться первой части, которая затем передаст его второй. К сожалению, данный метод себя не оправдывает. DOCTOR WEB в процессе эвристического анализа просто трассирует обработчик INT 21h до входа в его исходный (системный) код, одновременно контролируя адрес обработчика, и при получении любых подозрительных результатов выдает сообщение о наличии неизвестного вируса. Поэтому необходимо сделать так, чтобы при трассировании "первой" части под управлением отладчика вызывался системный обработчик, а при "нормальном" трассировании - вирусный (эксперименты показывают,что DOCTOR WEB,вероятнее всего, содержит встроенный отладчик). Для реализации указанного метода можно использовать особенность микропроцессора, состоящую в наличии очереди команд. Однако этот путь по существу является тупиковым, так как вирус, реализующий такой алгоритм,не будет работать на процессорах PENTIUM из-за наличия в последних так называемой системы прогнозирования переходов. Мы же поступим по другому.Как вы знаете все отладчики интенсивно используют прерывание 01h (One Step),обработчик которого останавливает работу микропроцессора после выполнения каждой команды. Поэтому естественно предположить, что для проведения эвристического анализа DOCTOR WEB устанавливает собственный обработчик Int 01h,а значит, заменяет адрес системного обработчика в таблице векторов прерываний.На факт замены этого адреса мы и будем ориентироваться. Экспериментальным путем было установлено, что системный обработчик Int 01h находится в памяти по такому адресу : 0070:XXXX. Следовательно, достаточно проверить сегментный адрес обработчика Int 01h, чтобы сказать, перехвачено-ли это прерывание какой-нибудь прикладной программой. Следующая проблема,возникающая при построении программы обработки прерывания из двух частей, состоит вот в чем: непонятно, куда именно следует поместить "первую" часть, чтобы она не затиралась при загрузке программ и их работе, и не была бы видна с помощью, например, VC.COM или RELEASE. Многочисленными экспериментами было установлено, что для размещения участка обработчика прерывания, ответственного за " обман " эвристического анализатора, можно использовать байты с 38h по 5Ch, принадлежащие PSP первой загруженной в память программы. Эти байты зарезервированы разработчиками операционной системы, вероятно, для будущих ее версий, и их значения остаются постоянными в течение всего сеанса работы компьютера. Кроме того, зарезервированного пространства в PSP вполне хватит для размещения программы обработки прерывания. Итак, можно предложить следующий алгоритм:
- Отыскивается PSP первой загруженной в память программы.
- В байты 38h - 5Ch записывается код "промежуточного" обработчика прерывания INT 21h. Этот код должен вызывать системный обработчик при работе под управлением отладчика и вирусный в противном случае.
* На самом деле можно использовать и другие области PSP, расположенные после байта со смещением 5Ch (примерно 32 байта - без всяких последствий.).
- В таблице векторов прерываний вектор INT 21h заменяется на точку входа в промежуточный обработчик.
Вот, собственно, и все.