Электронная библиотека

Xakep

Xakep

Первый вирь - COMом

Xakep, номер #014, стр. 014-058-3


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

В общем, пора закончить с теорией и приступить к практике. Можно даже считать, что вирус уже написан - осталось его накодить :).

Что, уже пора?

Когда вирус получит управление, его тело - код и данные - будут находиться не в самом начале, а на некотором расстоянии (которое есть ни что иное, как размер жертвы). Это необходимо учитывать, когда вирь обращается к данным и процедурам, вызывая их по JMP/CALL NEAR. Как это сделать? (наложенным платежом перечисляй мне - помогу, расчетный счет в конце телепередачи. :)) Два варианта навскидку - вычислять требуемое смещение к данным еще в процессе заражения и вычислять его на ходу, прямо при запуске виря. Я выбрал второе - оно показалось мне лучше, универсальнее что ли. А что выберешь ты, зависит от твоей фантазии и ловкости рук, конечно:

call $+3 ; команда CALL NEAR занимает три байта,

; поэтому CALL $+3, есть просто вызов следующей

; команды. В стеке появится слово со значением IP

; следующей команды.

pop ax ; осталось только взять его и

sub ax,offset entry virus+3 ; попpавить то, что получилось на IP

; команды CALL, а не POP AX

mov bp,ax ; после этого его можно положить куда-нибудь для

; дальнейшего использования

Обращения к данным и процедурам виря теперь нужно делать только с добавлением BP к их адресам. Тогда все они будут корректно считаны/записаны/вызваны. Т.е. вместо

mov [data],something

пишется

mov [bp+data],something

и все адреса рассчитывать соответственно. Есть один момент, о котором я хотел бы пробулькать пивом, бродящим со вчерашнего дня в моем желудке. Чтобы выяснить адрес, не нужно постоянно добавлять BP к нормальному смещению вот так:

mov dx,offset data

add dx,bp

На это уходит уйма байт, которые пригодятся для другого. Гораздо лучше воспользоваться старым добрым LEA (load effective address), который советовал использовать в своей книжке добрый дядька Питер Нортон:

lea dx,[bp+data]

Раз, два, три, четыре, пять - я иду искать

Вирус должен сохранить состояние среды, в которую его запихали не без помощи INT 21H. Для поиска я воспользуюсь FindFirst и FindNext из INT 21H. Они используют DTA, которая дефолтом располагается с 128 байта в PSP. Там же, кстати, лежат параметры, которые были переданы программе в командной строке. И как только я вызову FindFirst или FindNext c явным намерением похулиганить, все эти параметры просто исчезнут во мраке небытия. Именно поэтому DTA сохраняется. Все-таки не надо лишний раз высовывать голову из окопа, обнаруживая свое (вируса) присутствие в файле. Могут ведь и заметить. Итак, DTA нужно сохранить. Для этого нужно иметь где-то буфер в 128 байт. Но не стоит делать так:

Назад на стр. 014-058-2  Содержание  Вперед на стр. 014-058-4