Процесс, пославший TerminateProcess.
От: kregheck  
Дата: 08.12.08 08:19
Оценка:
Проблема в следующем. Есть 2 процесса, 1-й убивает 2-й. Как определить имя 1-го процесса, зная имя 2-го?
Re: Процесс, пославший TerminateProcess.
От: Аноним  
Дата: 08.12.08 08:22
Оценка:
без перехвата — никак
Re[2]: Процесс, пославший TerminateProcess.
От: kregheck  
Дата: 08.12.08 08:46
Оценка:
Здравствуйте, Аноним, Вы писали:

А>без перехвата — никак


А можно поподробнее. Есть идеи как это реализовать?
Re[3]: Процесс, пославший TerminateProcess.
От: xmen  
Дата: 08.12.08 20:44
Оценка: +1
Здравствуйте, kregheck, Вы писали:

K>Здравствуйте, Аноним, Вы писали:


А>>без перехвата — никак


K>А можно поподробнее. Есть идеи как это реализовать?


/**************************************************************
 * Project: Hook API function TerminateProcess
 * 
 * Copyright 2008 xmen
 **************************************************************/

#pragma comment(linker, "-entry:DllEntryPoint")
#pragma comment(lib, "kernel32")
#pragma comment(lib, "user32")
#pragma warning(disable: 4508)

#include <windows.h>

extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);

SetHook();
UnHook();

//-----------------
#pragma pack(push)
#pragma pack(1)
typedef struct {
    BYTE    OpPush;
    LPVOID  addr;
    BYTE    OpRet;
} jmp;
#pragma pack(pop)

jmp buf, old;
//-----------------

BOOL
WINAPI
xxxTerminateProcess(
    IN HANDLE hProcess,
    IN UINT uExitCode
    )
{
    DWORD CurrPid =  GetProcessId(GetCurrentProcess());
    
    CHAR strCurrPid[0x20] = {0};
    wsprintf(strCurrPid, "Current PID: %d", CurrPid);
    
    HANDLE hProcess1;
    DuplicateHandle(GetCurrentProcess(),
                    hProcess,
                    GetCurrentProcess(),
                    &hProcess1,
                    PROCESS_QUERY_INFORMATION,
                    TRUE,
                    0);

    DWORD TermPid =  GetProcessId(hProcess1);
    CHAR strTermPid[0x20] = {0};
    wsprintf(strTermPid, "TerminateProcess(PID: %d)", TermPid);
    
    MessageBox(NULL, strTermPid, strCurrPid, 0x40);
    
    UnHook();
    
    BOOL r = TerminateProcess(hProcess, uExitCode);
    
    SetHook();
    
    return r;
}

SetHook()
{
    jmp *pbuf = &buf;
    
    pbuf->OpPush = 0x68;
    pbuf->addr   = &xxxTerminateProcess;
    pbuf->OpRet  = 0xC3;
    
    WriteProcessMemory(INVALID_HANDLE_VALUE,
                       &TerminateProcess,
                       &buf,
                       sizeof(jmp),
                       0);
}

UnHook()
{
    WriteProcessMemory(INVALID_HANDLE_VALUE,
                       &TerminateProcess,
                       &old,
                       sizeof(jmp),
                       0);
}

BOOL WINAPI
DllEntryPoint(HINSTANCE hInstance, ULONG ulReason, LPVOID pv)
{
    switch(ulReason)
    {
        case DLL_PROCESS_ATTACH:
            ReadProcessMemory(INVALID_HANDLE_VALUE,
                              &TerminateProcess,
                              &old,
                              sizeof(jmp),
                              0);
            SetHook();
            break;
        
        case DLL_PROCESS_DETACH:
            UnHook();
            break;
    }
    
    return TRUE;
}


http://files.rsdn.ru/59750/HTP.rar
Re[4]: Процесс, пославший TerminateProcess.
От: xmen  
Дата: 09.12.08 16:11
Оценка: +1
На рисунке показан taskmgr. При попытке завершить процесс выдалось сообщение о том, что процесс PID: 1680 (taskmgr.exe) пытается завершить процесс с PID: 4 (System.exe).



Об устройстве Dll:

* Загружается Dll в адресное пространство процессов с помощью ключа реестра:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs = C:\HookTermProc.dll

* Перехват осуществляется путем замены первых 5 байт (SetHook()) перехватываемой функции своими, для вызова реальной функции нужно установить обратно замененные байты (UnHook()), а после вызова — снова установить перехват (SetHook())

* Нужно получить Pid «убиваемого» процесса зная hProcess, но hProcess открыт с правами PROCESS_TERMINATE. И при попытке получить Pid с помощью функции GetProcessId(hProcess) – получим ошибку ERROR_ACCESS_DENIED. Поэтому используем функцию DuplicateHandle(*, hProcess, *, &hProcess1, PROCESS_QUERY_INFORMATION, *, *) теперь GetProcessId(hProcess1) выполняется успешно

http://files.rsdn.ru/59750/HTP.rar
Re[5]: Процесс, пославший TerminateProcess.
От: kregheck  
Дата: 12.12.08 10:00
Оценка: +1
Спасибо, xmen! Все работает.
Re[4]: Процесс, пославший TerminateProcess.
От: x64 Россия  
Дата: 12.12.08 11:11
Оценка:
На Windows XP SP2 и выше рекомендуется пользоваться Microsoft'овской технологией hot-patching.
Re[5]: Процесс, пославший TerminateProcess.
От: xmen  
Дата: 12.12.08 15:43
Оценка:
Здравствуйте, x64, Вы писали:

x64>На Windows XP SP2 и выше рекомендуется пользоваться Microsoft'овской технологией hot-patching.


Про 5 nop'ов перед API функцией для команды jmp я знаю, но никогда не использовал hot-patching т.к.:
1) вызывается функция из NTDLL.DLL (LdrHotPatchRoutine)
2) работает только с WinXP SP2
3) объемность кода (выходит больше чем 120 строк кода)

Microsoft использует hot-patching для того чтобы ставить security патчи на лету ("обновлять Windows без перезагрузки").
Если есть желание продемонстрировать перехват TerminateProcess() используя технологию hot-patching думаю, многим это будет интересно.
Re[6]: Процесс, пославший TerminateProcess.
От: x64 Россия  
Дата: 12.12.08 16:54
Оценка:
X>1) вызывается функция из NTDLL.DLL (LdrHotPatchRoutine)

Значит так, если кому реально интересно как это происходит, читайте здесь раздел HotPatching. Официальная информация здесь, плюс статья базы знаний под номером 897341.

Но можно и по простому, обойтись без всех этих сложностей. Сначала ставишь far jmp вместо 5 байт перед функцией, затем short jmp назад на начало функции минус 5 байт, т.е. на уже подготовленный far jmp. Short jmp занимает 2 байта, т.е. уже меньше проблем с атомарностью операции. Я так делал, хотя, конечно, надо понимать, что для коммерческого продукта просто так оно не делается.

X>2) работает только с WinXP SP2


Да, начиная с Windows XP SP2 или с Windows Server 2003.

X>3) объемность кода (выходит больше чем 120 строк кода)


Да не сказал бы, всё достаточно просто (см. выше).

X>Microsoft использует hot-patching для того чтобы ставить security патчи на лету ("обновлять Windows без перезагрузки").


Да. Впервые появилось для серверных платформ на Windows Server 2003, чтобы уменьшить кол-во перезагрузок собственно сервера.

X>Если есть желание продемонстрировать перехват TerminateProcess() используя технологию hot-patching думаю, многим это будет интересно.


Может быть, как-нибудь... Сейчас мне не интересно заниматься этим.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.