| Вернуться на сайт |
Пример 8 – Процессы и службы
В
данном примере мы рассмотрим что такое процессы, чем
они отличаются от программ, и отдельный класс процессов, именуемый системными
службами. Для этого нам понадобится только среда программирования (в моем
случае это Borland C++ Builder).
Процессом как
правило называют экземпляр выполняемой программы. Хотя на первый взгляд кажется, что программа и процесс понятия практически
одинаковые, они на самом деле друг от друга отличаются. Программа представляет
собой статический набор команд, процесс же - это набор ресурсов и данных,
использующихся при выполнении программы.
Процесс в ОС Windows состоит из следующих компонентов:
Создание Win32 процесса осуществляется вызовом одной из таких функций, как CreateProcess, CreateProcessAsUser (для Windows NT/2000) и CreateProcessWithLogonW (начиная с Windows 2000) и происходит следующим образом:
Процесс завершается если:
Когда процесс завершается, все User- и GDI-объекты, созданные процессом, уничтожаются, объекты ядра закрываются (если их не использует другой процесс), адресное пространство процесса уничтожается. Рассмотрим, как это реализуется на практике.
|
Напишем маленькую функцию, которая завершает процесс с использованием функции TerminateProcess(). В качестве параметра ей передается хэндл завершаемого процесса. В свою очередь хэндл процесса можно получить с помощью функции OpenProcess(). Одним из параметров для этой функции передается PID – process identificator (идентификатор процесса). Идентификатор процесса можно лицезреть в стандартном Диспетчере Задач. |
|
|
Для получения идентификатора в нашей программе напишем небольшую функцию, которая будет определять PID по имени файла. Получим снэпшот (snapshot) системных процессов с помощью функции CreateToolhelp32Snapshot(), а затем функциями Process32First() и Process32Next() переберем все процессы для поиска нужного нам (который задается переменной ExeName). Здесь существенную роль играет структура PROCESSENTRY32, которая как раз содержит информацию как об имени файла (элемент szExeFile), так и об идентификаторе процесса (элемент th32ProcessID). В результате этих нехитрых манипуляций в переменную Pid возвращается текущий идентификатор процесса. Соответственно, не забываем после нахождения идентификатора освобождать хэндл с помощью функции CloseHandle(). Более подробное описание использованных функций можно найти в хелпе по WinAPI, кстати, для их корректной работы необходимо #include <tlhelp32.hpp> |
|
Для использования вынесем на форму кнопку и в ее обработчик вставим вызовы описанных ранее функций. Здесь для примера я открывал браузер Опера и потом программно завершал его процесс. После этого функцией Application->Terminate() завершалось выполнение самой программы. Необходимо отметить, что таким способом можно завершить не каждый процесс, и тут мы вплотную подходим к теме служб… |
Исполняемый файл службы использует во время работы специальный протокол общения с особой подсистемой Windows NT - Service Control Manager (в дальнейшем SCM). API-функции для работы с SCM экспортирует стандартная библиотека Windows advapi32.dll. Подсистема служб загружается в самом начале загрузки операционной системы из исполняемого файла services.exe, одноимённый процесс вы можете наблюдать в списке активных процессов во всё время работы компьютера. Библиотека advapi32.dll общается с services.exe посредством RPC (Remote Procedure Call – удаленный вызов процедур), поэтому всё, что вы можете делать со службами на локальной машине, вы можете делать и на удалённой машине по сети, что очень удобно.
|
Ещё одно отличие службы от
"обычной программы" в том, что служба, будучи запущенной, работает
и после выхода пользователя из системы (даже когда вы видите приглашение
"Для входа в систему нажмите Ctrl+Alt+Delete"). Поэтому службами
часто делают программы, которые должны работать даже тогда, когда нет
вошедших в систему пользователей. Из встроенных служб это, к примеру, Spooler (служба печати), Alerter (служба оповещения, часто используемая системными
администраторами) и т.п. |
Для нашего примера понадобится уровень
доступа SERVICE_STOP, который позволяет
остановить службу с помощи функции ControlService(); |
|
Итак, мы рассмотрели функции, нужные для работы со службами и их конфигурирования, на примере остановки службы (кстати, для работы функций необходимо #include <winsvc.h>). В качестве дополнительной информации можно сказать, что SCM запускает службы исходя из того, какие параметры имеются в базе данных служб. Эта базу данных находится в реестре по ключу HKLM\SYSTEM\CurrentControlSet\Services, где каждый раздел - имя установленной службы. Исходя из этого можно сделать вывод, что существует возможность добавлять службы через реестр. Правда придется перезагружать машину после такой "установки" службы, поскольку база грузится в SCM при старте системы. Кроме того, этот способ подходит только для текущих версий ОС, так как Microsoft не гарантирует, что ключи реестра в следующих версиях Windows будут на том же месте. Более того, никто не гарантирует, что в следующих версиях эта база вообще будет находиться в реестре. У вирусописателей особое мнение на этот счёт - анализ подозрительной программы, в которой импортируется вызов CreateService(), вызывает подозрения, а так будет просто "безобидная" работа с реестром (но у этих "товарищей" вообще на многие вещи особое мнение)
При написании примера использовалась
информация с сайта http://bugtraq.ru/
(с) FM, 2008 |
Отзывы как обычно принимаются на mimicria@mail.ru |