Войти

Показать полную графическую версию : Мониторинг и завершение вновь запущенных приложений


God_Zilla
11-11-2011, 13:12
Здравствуйте уважаемые форумчане!

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

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

С 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
11-11-2011, 14:27
God_Zilla, Вы выбрали очень неудобный способ решения этой задачи. Советую обратить внимание на возможности WMI: создание подписки на событие запуска процесса.

Anonymоus
11-11-2011, 19:11
God_Zilla, у меня давно и успешно работает вот такой скрипт:



@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 "\<!VerMajor!.!VerMinor!\>">nul&&Set bCompatibleOS=true
If %bCompatibleOS%==false (
ChCp 866>nul
Echo.
Echo Ваша операционная система не поддерживается
Echo Для выхода нажмите любую кнопку...
Echo.
Pause>nul
Exit /B 1
)
Exit /B 0


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


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 "\<!VerMajor!.!VerMinor!\>">nul&&Set bCompatibleOS=true
Или (так будет даже проще) закомментируйте\удалите эти две строки в начале:

Call :CheckOS
If %ErrorLevel%==1 Exit /B

God_Zilla
13-11-2011, 07:20
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

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




© OSzone.net 2001-2012