CMD/BAT - Мониторинг и завершение вновь запущенных приложений

Ответить
Аватара пользователя
God_Zilla

CMD/BAT - Мониторинг и завершение вновь запущенных приложений

Сообщение God_Zilla »

Здравствуйте уважаемые форумчане!



Задача: При старте генерируется файл со списком запущенных процессов и приложений, затем с заданным интервалом список сравнивается с текущими запущенными процессами и если обнаруживается новый он завершается.



С генерацией лога запущенных приложений при старте батника проблем нет, не могу сообразить как их сравнивать.



С for и if подружиться никак не получается...



Код:

Код: Выделить всё

@echo off
tasklist >log.txt
goto sleep
:scan
tasklist >templog.txt
for %%i in (templog.txt) do echo %%i>>log.txt
for /f "delims=" %%i in (log.txt) do taskkill /f /im "%%i"
if erorlevel 1 goto scan
:sleep
sleep 10
goto scan
:end
del /q /f log.txt
del /q /f templog.txt
exit

Как сравнить два списка и убить лишний появившийся процесс?



В самой важной части кода конечно полная билибирда:



Код:

Код: Выделить всё

for %%i in (templog.txt) do echo %%i>>log.txt
for /f "delims=" %%i in (log.txt) do taskkill /f /im "%%i"
if erorlevel 1 goto scan



По идее при обнаружении первой добавившейся строчки в templog.txt (запущен новый процесс/приложение) скрипт должен убить процесс и секция scan должна быть перезапущена минуя sleep на случай если были еще изменения, если их нет пауза.



Помогите!
Аватара пользователя
DmitriiV

Re: CMD/BAT - Мониторинг и завершение вновь запущенных приложений

Сообщение DmitriiV »

God_Zilla, Вы выбрали очень неудобный способ решения этой задачи. Советую обратить внимание на возможности WMI: создание подписки на событие запуска процесса.
Аватара пользователя
Guest

Re: CMD/BAT - Мониторинг и завершение вновь запущенных приложений

Сообщение Guest »

God_Zilla, у меня давно и успешно работает вот такой скрипт:




Код "cleanup.bat"






Код:

Код: Выделить всё

@Echo Off
:: Завершает не указанные в "белом списке" процессы
:: Anonymous, 2011
SetLocal ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS
Call :CheckOS
If %ErrorLevel%==1 Exit /B
:: Файл со списком разрешённых процессов
Set #WhitelistFile=%~sdp0whitelist.txt
:: Получение PID своего процесса
:GetPID
Set WinTitle=%Random%%Random%
Title %WinTitle%
For /F "tokens=2 skip=2 delims=," %%P In ('tasklist /FI "WINDOWTITLE eq %WinTitle%" /FO CSV') Do (
Set MyPID=%%~P
)
:: Чтение файла со списком разрешённых процессов
:ReadList
Set /A i=0
For /F "tokens=*" %%l in (%#WhitelistFile%) Do (
	Set /A i+=1
	Set _Whitelist!i!=%%l
)
Set Whitelist_strings=!i!
:: Получение списка процессов
:GetProcList
Set ProcList_Strings=0
For /F "tokens=1,2* skip=5 delims=," %%P In ('tasklist /FO CSV') Do (
	Call :Add Proclist %%~P
)
Call :Purge whitelist
Call :Purge proclist
Call :Compare
EndLocal
Exit /B
:: Вывод содержимого списка
:: (не используется, для отладки)
:Dump
Set $ListName=%*
Set /A #StrCount=!%$ListName%_strings!
Echo.
Echo ==[%$ListName%]=======:
For /L %%S In (1,1,%#StrCount%) Do (
	Echo [%%S] !_%$ListName%%%S!
)
Echo.
Exit /B 0
:: Сравнение списков, завершение не разрешенных процессов
:Compare
For /L %%S In (1,1,%Proclist_strings%) Do (
	Set $TmpStringData=!_Proclist%%S!
	Set isUnknown=True
	For /L %%S In (1,1,%Whitelist_strings%) Do (
		Set $WhitelistString=!_Whitelist%%S!
		If /I !$TmpStringData!==!$WhitelistString! Set isUnknown=False
	)
	If !isUnknown!==True (
		If "!$TmpStringData!"=="cmd.exe" (
		taskkill /F /FI "PID ne %MyPID%" /FI "IMAGENAME eq cmd.exe"
		) Else (
		taskkill /F /IM "!$TmpStringData!"
		)
	)
)
Exit /B 0
:: Добавка строки
:Add
Set $ListName=
Set $ListString=
For /F "tokens=1,* delims= " %%n In ("%*") Do (
	Set $ListName=%%n
	Set $ListString=%%~o
)
Set /A $StrCount=!%$ListName%_strings!
Set /A $StrCount+=1
Set _%$ListName%%$StrCount%=%$ListString%
Set %$ListName%_strings=%$StrCount%
Exit /B 0
:: Очистка от одинаковых строк
:Purge
Set $ListName=%*
Set /A #StrCount=!%$ListName%_strings!
:PurgeLoop
Set /A $TmpStringNum=0
For /L %%S In (1,1,%#StrCount%) Do (
	Set $TmpStringNum=%%S
	Set $TmpStringData=!_%$ListName%%%S!
	For /L %%D In (1,1,%#StrCount%) Do (
		If Not %%D==!$TmpStringNum! (
			If "!_%$ListName%%%D!"=="!$TmpStringData!" Call :Delete %$ListName% %%D&&GoTo PurgeLoop
			)
	)
)
Exit /B 0
:: Удаление строки, сдвиг номеров следующих за ней
:Delete
Set $ListName=
Set $ListStringNum=
For /F "tokens=1,* delims= " %%n In ("%*") Do (
	Set $ListName=%%n
	Set $ListStringNum=%%o
)
Set /A #StrCount=!%$ListName%_strings!
Set /A i=0
For /L %%S In (1,1,%#StrCount%) Do (
	If Not %%S==%$ListStringNum% Set /A i+=1
	If Not %%S==%$ListStringNum% Set _%$ListName%!i!=!_%$ListName%%%S!
)
Set _%$ListName%%#StrCount%=
Set %$ListName%_strings=%i%
Exit /B 0
:: Проверка на версию ОС (На Win7 и Vista скрипт не проверялся,
:: поэтому и запускаться он там не будет)
:CheckOS
For /F "tokens=1,2* delims=[" %%A In ('ver') Do (
	Set $TmpString=%%B
	For /F "tokens=1,2* delims= " %%A In ("!$TmpString!") Do (
		Set $TmpString=%%B
		For /F "tokens=1,2* delims=]" %%A In ("!$TmpString!") Do (
			Set $TmpString=%%A
			For /F "tokens=1,2,3 delims=." %%A In ("!$TmpString!") Do (
			Set VerMajor=%%A
			Set VerMinor=%%B
			Set VerBuild=%%C
			)
		)
	)
)
Set bCompatibleOS=false
Echo 5.0 5.1|findstr /R "\">nul&&Set bCompatibleOS=true
If %bCompatibleOS%==false (
ChCp 866>nul
Echo.
Echo Ваша операционная система не поддерживается
Echo Для выхода нажмите любую кнопку...
Echo.
Pause>nul
Exit /B 1
)
Exit /B 0






А вот список "разрешенных процессов" для него:


Код "whitelist.txt"






Код:

Код: Выделить всё

explorer.exe
console.exe
csrss.exe
ctfmon.exe
firefox.exe
lsass.exe
psi-plus.exe
services.exe
smss.exe
svchost.exe
tasklist.exe
taskmgr.exe
VistaDrv.exe
winlogon.exe
wmiprvse.exe








Всё, что вам нужно сделать - это генерировать whitelist.txt при старте, и периодически запускать основной скрипт, который будет сравнивать процессы и подчищать недавно запущенные. Ну и еще, там защита от запуска на vista/win7 стоит, потому что у меня их нету, следовательно, работу скрипта я не проверял на них. Чтобы всё-таки запустить, внесите номер версии в строку



Код:

Код: Выделить всё

Echo 5.0 5.1|findstr /R "\">nul&&Set bCompatibleOS=true

Или (так будет даже проще) закомментируйте\удалите эти две строки в начале:



Код:

Код: Выделить всё

Call :CheckOS
If %ErrorLevel%==1 Exit /B
Аватара пользователя
God_Zilla

Re: CMD/BAT - Мониторинг и завершение вновь запущенных приложений

Сообщение God_Zilla »

Anonymоus благодарю, очень полезно!



В порядке обенм опытом, решение предложенное на соседнем форуме:





Код:

Код: Выделить всё

@echo off
if exist log.txt del /q /f log.txt
for /f "delims=," %%i in ('tasklist /FO CSV 2^>nul') do echo %%i>>log.txt
echo "ntvdm.exe">>log.txt
goto sleep
:scan
tasklist /FI "Imagename eq grand.exe" 2>nul | findstr "grand.exe" >nul
if errorlevel 1 goto end
for /f "delims=," %%i in ('tasklist /FO CSV 2^>nul') do (
findstr %%i log.txt >nul || taskkill /f /im %%i
)
:sleep
sleep 10
goto scan
:end
del /q /f log.txt
exit

После запуска генерируется список запущенных процессов "log.txt", затем пауза 10 секунд (утилита sleep), текущие процессы сравниваются с "Log.txt" если обнаруживается лишний - он завершается, затем пауза 10 сек. и далее опять по кругу.



В скрипте предусмотрен контроль работы одного приложения "grand.exe" если он не обнаруживается в списке активных процессов скрипт останавливается "goto end".



Разрешенные приложения (не запушенные в момент старта скрипта), в данном примере "ntvdm.exe", дописываются в log.txt командой "echo "ntvdm.exe">>log.txt"



В основном батнике проверка OS реализованна так:



Код:

Код: Выделить всё

@echo off
:whois
ver | find " 5."
if not errorlevel 1 goto winxp
ver | find " 6."
if not errorlevel 1 goto win7
:winxp
echo you os is Windows XP
:win7
echo you os is Windows Seven
pause
exit

Задача решена, всем большое спасибо!
Ответить

Вернуться в «Скриптовые языки администрирования Windows»