Внимание! Сайт не обновлялся более 3х лет!
Перейти в портфолио компании

Убийство процесса по имени

13 марта 2012

Сегодня будем грамотно убивать процесс зная его имя. 

Наш киллер справится с любыми процессами, даже с теми, что неподвластны Windows Task Manager

PROCESSENTRY32 structure - Описывает структуру списка процессов, находящихся в адресном пространстве системы в момент снимка.

typedef struct tagPROCESSENTRY32 {
  DWORD     dwSize; // Размер структуры (в байтах)
  DWORD     cntUsage; // Не используется (всегда 0)
  DWORD     th32ProcessID; // Идентификатор процесса
  ULONG_PTR th32DefaultHeapID; // Неиспользуется (0)
  DWORD     th32ModuleID; // Не используется (0)
  DWORD     cntThreads; // Число потоков процесса
  DWORD     th32ParentProcessID; // Идентификатор родительского процесса
  LONG      pcPriClassBase; // Приоритет потоков, порожденных данным
  DWORD     dwFlags; // Не используется (0)
  TCHAR     szExeFile[MAX_PATH]; // Полный путь к exe файлу процесса
} PROCESSENTRY32, *PPROCESSENTRY32;  

MSDN утверждает, что объекты такой структуры необходимо инициализировать размером самой структуры.

Спорить не будем.

CreateToolhelp32Snapshot - Возвращает моментальный снимок данных текущих модулей, процессов, потоков и принадлежащих им куч памяти

lstrcmpi - посимвольно сравнивает 2 строки, пока не будет обнаружено неравенство, либо концевой нулевой символ "\0"

Результат:
меньше нуля: str1 < str2
ноль: str1 = str2
больше нуля: str1 > str2

Process32First - Извлекает информацию о первом процессе снимка, полученного посредством CreateToolhelp32Snapshot

Process32Next - Соответственно извлекает информацию о следующем процессе

OpenProcess - открывает существующий объект процесса, устанавливая указанный уровень доступа.

TerminateProcess - завершает работу заданного процесса и всех его потоков.

Переходим к практике!

Алгоритм убийства следующий:

1) Получить информацию о всех текущих процессах
2) Поочередно сравнивая все имена процессов с нашим, найти его идетификатор
3) Открыть процесс с максимально возможными правами
4) Критическое завершение процесса с флагом 0xDEAD

Приступим!

Пишем фукнцию GetPIDByName:

DWORD GetPIDbyName(LPTSTR szProcessName) {
    HANDLE hSnapshot; // Дескриптор снимка
    PROCESSENTRY32 pe = {sizeof(pe)};  // структура снимка
    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);   // делаем снимок!
    if (hSnapshot == INVALID_HANDLE_VALUE) // Если дескриптор некорректен(отсутствует)
        return 0;                          // Выходим
    if (!Process32First(hSnapshot, &pe))   // Если не удалось извлечь инфу
        return 0;                          // о первом процессе из снимка - выходим
    do {
        if (!lstrcmpi(pe.szExeFile, szProcessName))  // Если строки равны
            return pe.th32ProcessID;                 // Значит нашли идентификатор!
    while (Process32Next(hSnapshot, &pe));  // Пока не обойдем все процессы в снимке
    return 0;                               // Дошли до сюда - fail
}

Получать идентификатор процесса умеем, ну что, учимся убивать?

void KillHim(String sProcessName) { 
    HANDLE hProcess; // Дескриптор процесса
    DWORD pid;       // Идентификатор процесса
    pid = GetPIDbyName(sProcessName.w_str()); // Получили Идентификатор
    // Открываем с макс.возм.правами
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); 
    TerminateProcess(hProcess, 0xDEAD); // Уверены, что желаем убить? убиваем!
    CloseHandle(hProcess); // закрываем дескриптор открытого процесса
}

Ну и сам вызов:

KillHim("firefox.exe");

Ладно, хватит мучать мою систему, я уже все, что можно убил :D

← назад