Поймать TerminateProcess для своего приложения
От: _agg  
Дата: 22.02.19 04:12
Оценка:
привет всем, понадобилось в момент когда из диспетчера задач вызывают снять задачу записать в лог сообщение об этом, пытался вот так:
void __cdecl thr_wait_terminate_process(LPVOID ptr) {
    DWORD dwPID = GetCurrentProcessId();
    HANDLE hProcess = OpenProcess(SYNCHRONIZE | PROCESS_TERMINATE, TRUE, dwPID);
    do {
        if (!hProcess) {
            t2f::T2F(err::GetErrMsg());
            break;
        }
    } while (false);
    DWORD dwErr = WaitForSingleObject(hProcess, INFINITE);
    CString str; str.Format(L"Close process:%lu", dwErr);
    t2f::T2F(str);
}

t2f::T2F — пишет лог
err::GetErrMsg() — вызывает GetLastError и форматирует сообщение из полученной ошибки

Это поточная функция, которая как мне казалось должна поймать TerminateProcess вызываемый для моего процесса диспетчером задач, но увы и поэтому прошу помощи у знающих людей как же правильно это сделать?
Re: Поймать TerminateProcess для своего приложения
От: Sharowarsheg  
Дата: 22.02.19 06:04
Оценка: +2
Здравствуйте, _agg, Вы писали:

_>привет всем, понадобилось в момент когда из диспетчера задач вызывают снять задачу записать в лог сообщение об этом, пытался вот так:



_>Это поточная функция, которая как мне казалось должна поймать TerminateProcess вызываемый для моего процесса диспетчером задач,

но увы и поэтому прошу помощи у знающих людей как же правильно это сделать?

Когда она теоретически могла бы вызваться, твой процесс уже здох. Можно только сделать два процесса и заставить их каждый следить за другим.
Re: Поймать TerminateProcess для своего приложения
От: Слава  
Дата: 22.02.19 06:06
Оценка: -1
Здравствуйте, _agg, Вы писали:

_>Это поточная функция, которая как мне казалось должна поймать TerminateProcess вызываемый для моего процесса диспетчером задач, но увы и поэтому прошу помощи у знающих людей как же правильно это сделать?


Следилочку за людьми пишете? А вот не надо её писать.
Re[2]: Поймать TerminateProcess для своего приложения
От: _agg  
Дата: 22.02.19 08:51
Оценка:
Здравствуйте, Слава, Вы писали:

С>Здравствуйте, _agg, Вы писали:


_>>Это поточная функция, которая как мне казалось должна поймать TerminateProcess вызываемый для моего процесса диспетчером задач, но увы и поэтому прошу помощи у знающих людей как же правильно это сделать?


С>Следилочку за людьми пишете? А вот не надо её писать.


Ерунду говорите уважаемый, в логах обрывы непонятно почему они случаются, что бы отсеить возможность что пользователь просто через диспетчер задач выключает приложение для этого это нужно. Прежде чем что-то сказать нужно подумать.
Re: Поймать TerminateProcess для своего приложения
От: EreTIk EreTIk's Box
Дата: 22.02.19 10:32
Оценка: 2 (1)
Здравствуйте, _agg, Вы писали:

_>привет всем, понадобилось в момент когда из диспетчера задач вызывают снять задачу записать в лог сообщение об этом, пытался вот так:

  Скрытый текст
_>
_>void __cdecl thr_wait_terminate_process(LPVOID ptr) {
_>    DWORD dwPID = GetCurrentProcessId();
_>    HANDLE hProcess = OpenProcess(SYNCHRONIZE | PROCESS_TERMINATE, TRUE, dwPID);
_>    do {
_>        if (!hProcess) {
_>            t2f::T2F(err::GetErrMsg());
_>            break;
_>        }
_>    } while (false);
_>    DWORD dwErr = WaitForSingleObject(hProcess, INFINITE);
_>    CString str; str.Format(L"Close process:%lu", dwErr);
_>    t2f::T2F(str);
_>}
_>

_>t2f::T2F — пишет лог
_>err::GetErrMsg() — вызывает GetLastError и форматирует сообщение из полученной ошибки

_>Это поточная функция, которая как мне казалось должна поймать TerminateProcess вызываемый для моего процесса диспетчером задач, но увы и поэтому прошу помощи у знающих людей как же правильно это сделать?

Как справедливо сказано выше, процесс станет сигнальным объектом, когда уничтожится, то есть перестанет иметь исполняющиеся нити.

Почему этот код должен срабатывать только при уничтожении процесса из диспетчером задач? Как это будет отличаться от других случаев:

Если интересует именно вызов TerminateProcess, то в Windows 10 (а скорее всего и и на более старых версиях) в отдельном процессе можно следить за ETW-событиями, которые логируют вызов TerminateProcess одного процесса для другого:
  PspLogAuditTerminateRemoteProcessEvent
PAGE:007BC54A ; __stdcall PspLogAuditTerminateRemoteProcessEvent(x, x)
PAGE:007BC54A _PspLogAuditTerminateRemoteProcessEvent@8 proc near
PAGE:007BC54A                                         ; CODE XREF: NtTerminateProcess(x,x)+172p
PAGE:007BC54A
PAGE:007BC54A var_2C          = dword ptr -2Ch
PAGE:007BC54A var_28          = dword ptr -28h
PAGE:007BC54A var_24          = dword ptr -24h
PAGE:007BC54A var_20          = dword ptr -20h
PAGE:007BC54A var_1C          = dword ptr -1Ch
PAGE:007BC54A var_18          = dword ptr -18h
PAGE:007BC54A var_14          = dword ptr -14h
PAGE:007BC54A var_10          = dword ptr -10h
PAGE:007BC54A var_C           = dword ptr -0Ch
PAGE:007BC54A var_8           = dword ptr -8
PAGE:007BC54A var_4           = dword ptr -4
PAGE:007BC54A
PAGE:007BC54A                 mov     edi, edi
PAGE:007BC54C                 push    ebp
PAGE:007BC54D                 mov     ebp, esp
PAGE:007BC54F                 sub     esp, 2Ch
PAGE:007BC552                 mov     eax, ___security_cookie
PAGE:007BC557                 xor     eax, ebp
PAGE:007BC559                 mov     [ebp+var_4], eax
PAGE:007BC55C                 push    4
PAGE:007BC55E                 lea     eax, [ebp+var_28]
PAGE:007BC561                 mov     [ebp+var_28], ecx
PAGE:007BC564                 pop     ecx
PAGE:007BC565                 mov     [ebp+var_24], eax
PAGE:007BC568                 lea     eax, [ebp+var_2C]
PAGE:007BC56B                 mov     [ebp+var_14], eax
PAGE:007BC56E                 lea     eax, [ebp+var_24]
PAGE:007BC571                 push    eax
PAGE:007BC572                 push    2
PAGE:007BC574                 mov     [ebp+var_2C], edx
PAGE:007BC577                 xor     edx, edx
PAGE:007BC579                 push    edx
PAGE:007BC57A                 push    offset _KERNEL_AUDIT_API_TERMINATEPROCESS
PAGE:007BC57F                 push    dword_67AC8C
PAGE:007BC585                 mov     [ebp+var_20], edx
PAGE:007BC588                 push    _EtwApiCallsProvRegHandle
PAGE:007BC58E                 mov     [ebp+var_1C], ecx
PAGE:007BC591                 mov     [ebp+var_18], edx
PAGE:007BC594                 mov     [ebp+var_10], edx
PAGE:007BC597                 mov     [ebp+var_C], ecx
PAGE:007BC59A                 mov     [ebp+var_8], edx
PAGE:007BC59D                 call    _EtwWrite@24    ; EtwWrite(x,x,x,x,x,x)
PAGE:007BC5A2                 mov     ecx, [ebp+var_4]
PAGE:007BC5A5                 xor     ecx, ebp
PAGE:007BC5A7                 call    @__security_check_cookie@4 ; __security_check_cookie(x)
PAGE:007BC5AC                 mov     esp, ebp
PAGE:007BC5AE                 pop     ebp
PAGE:007BC5AF                 retn
PAGE:007BC5AF _PspLogAuditTerminateRemoteProcessEvent@8 endp


Но сразу надо учесть, что:

P.S. Зачем вокруг логирования ошибки открытия процесса городить while (false)? В боевом коде после if (!hProcess) есть еще код, который не попал в приведенный пример?
Отредактировано 22.02.2019 12:13 EreTIk . Предыдущая версия . Еще …
Отредактировано 22.02.2019 12:11 EreTIk . Предыдущая версия .
Re[2]: Поймать TerminateProcess для своего приложения
От: _agg  
Дата: 27.02.19 04:12
Оценка:
Здравствуйте, EreTIk, Вы писали:

ETI>P.S. Зачем вокруг логирования ошибки открытия процесса городить while (false)? В боевом коде после if (!hProcess) есть еще код, который не попал в приведенный пример?


Этот пример я писал для теста, не судите строго действительно с do while фигня написана, там после if был еще код раньше потом убрал, а do while остался. По сути к такому выводу и пришел что я отловил WM_CLOSE, WM_QUERYENDSESSION, WTS_EVENT_LOGOFF, WTS_EVENT_LOGON, WTS_EVENT_CONNECT, WTS_EVENT_DISCONNECT если оборвалось и не было не одного из событий, то считаю что приложение не штатно завершилось. Хотя с другой стороны должен быть крэш дамп а его нет. Вообщем разбираюсь приложение досталось в поддержку недавно пытаюсь его оживить.
Спасибо за участие )
Re[3]: Поймать TerminateProcess для своего приложения
От: m2l  
Дата: 27.02.19 05:04
Оценка:
Здравствуйте, _agg, Вы писали:

_>Этот пример я писал для теста, не судите строго действительно с do while фигня написана, там после if был еще код раньше потом убрал, а do while остался. По сути к такому выводу и пришел что я отловил WM_CLOSE, WM_QUERYENDSESSION, WTS_EVENT_LOGOFF, WTS_EVENT_LOGON, WTS_EVENT_CONNECT, WTS_EVENT_DISCONNECT если оборвалось и не было не одного из событий, то считаю что приложение не штатно завершилось. Хотя с другой стороны должен быть крэш дамп а его нет. Вообщем разбираюсь приложение досталось в поддержку недавно пытаюсь его оживить.


Если тебя интересуют не действия пользователя, а креши, то есть MiniDumpWriteDump и библиотеки-обертки вокруг неё для простого использования.
Re: Поймать TerminateProcess для своего приложения
От: morgot  
Дата: 05.05.19 14:48
Оценка:
Здравствуйте, _agg, Вы писали:

_>поймать TerminateProcess вызываемый для моего процесса диспетчером задач


А разве это реально вообще? Как я помню, Terminate убивает процесс без предупреждения. Вот немного инфы https://devblogs.microsoft.com/oldnewthing/20040722-00/?p=38373

Наверное, если интересует именно диспетчер задач, то проще как-то отслеживать его появление, инжектиться туда и там уже перехватывать.
Re: Поймать TerminateProcess для своего приложения
От: wildwind Россия  
Дата: 06.05.19 07:48
Оценка:
Здравствуйте, _agg, Вы писали:

_>привет всем, понадобилось в момент когда из диспетчера задач вызывают снять задачу записать в лог сообщение об этом, пытался вот так:


Могу ошибаться, но по-моему Диспетчер задач сначала шлет WM_CLOSE, и если приложение не реагирует, тогда уже TerminateProcess.
Отредактировано 06.05.2019 7:48 wildwind . Предыдущая версия .
Re[2]: Поймать TerminateProcess для своего приложения
От: VladCore  
Дата: 22.05.19 21:43
Оценка:
Здравствуйте, wildwind, Вы писали:

W>Здравствуйте, _agg, Вы писали:


_>>привет всем, понадобилось в момент когда из диспетчера задач вызывают снять задачу записать в лог сообщение об этом, пытался вот так:


W>Могу ошибаться, но по-моему Диспетчер задач сначала шлет WM_CLOSE, и если приложение не реагирует, тогда уже TerminateProcess.


Типа того.
А что шлют консольному процессу, например .net core веб приложению в nano server в докере?

Там нет окон, но есть поддержка логики остановки/завершения и оно наверно работает. сам не проверял. но стало интересно.

Ctrl-C шлют?
Re[3]: Поймать TerminateProcess для своего приложения
От: ononim  
Дата: 29.05.19 07:53
Оценка: 9 (1)
VC>А что шлют консольному процессу, например .net core веб приложению в nano server в докере?
VC>Там нет окон, но есть поддержка логики остановки/завершения и оно наверно работает. сам не проверял. но стало интересно.
https://docs.microsoft.com/en-us/windows/console/handlerroutine
Как много веселых ребят, и все делают велосипед...
Re[2]: Поймать TerminateProcess для своего приложения
От: Ops Россия  
Дата: 04.06.19 07:28
Оценка:
Здравствуйте, morgot, Вы писали:

M>Наверное, если интересует именно диспетчер задач, то проще как-то отслеживать его появление, инжектиться туда и там уже перехватывать.


А еще есть PE и хрен знает что еще с аналогичным функционалом, подменяющие собой диспетчер задач.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.