How to handle “End Task” from Windows Task Manager on a background process?

前端 未结 2 1458
盖世英雄少女心
盖世英雄少女心 2020-12-21 13:35

I wrote a simple test program (TestProgram.exe) to learn how to handle the CTRL_CLOSE_EVENT and here are my observations and my question:

1) When I double click Test

2条回答
  •  有刺的猬
    2020-12-21 14:06

    When a process is terminated (not closed) nothing realy can be done unless you start do some hooking, either by hooking TerminateProcess or NtTerminateProcess in the Task Manger process, example of how it works:

    #include 
    #include 
    
    BOOL WINAPI MyTerminateProcess(HANDLE hProcess, UINT uExitCode ) {
        MessageBox(NULL, TEXT("Do some cleanup"), NULL, MB_OK);
        ExitProcess(0);
        return TRUE;
    }
    
    #pragma pack(1)
    typedef struct __PATCHDATA {
        BYTE push;
        DWORD address;
        BYTE ret;
    } PATCHDATA;
    #pragma pack()
    
    int main(int argc, char **argv) {
        HMODULE hModule;
        DWORD written;
        // This struct contains assembly instruction that do:
        //  push address ; 0x68 MyTerminateProcess
        //  ret          ; 0xc3
        // so the execution will return to our hook
        PATCHDATA patch = {0x68, (DWORD) MyTerminateProcess, 0xc3};
    
        // remove this code, the program will terminate itself.
        // TODO: check the memory protection and modify it.
        WriteProcessMemory(GetCurrentProcess(),
                           TerminateProcess,
                           &patch,
                           sizeof(PATCHDATA),
                           &written);
    
        TerminateProcess(NULL, 0);
    
        return 0;
    }
    

    This hooks TerminateProcess in the same process, you need to ship it in a DLL and inject it in the Task Maneger process, didn't test it. But this method is overwork and not safe, some AV products may detect it as harmful program.

    A simple solution is to clean up on the program start-up as @Martin James suggested. On your program start-up create a file or use the registry to store some value like 0, if the program was closed, received WM_CLOSE if it's GUI or CTRL_CLOSE_EVENT if you closed the command prompt, you do the clean-up and store 1.

    On the next start-up you you check back that value if it stills 0, this mean do the program was not closed properly, do do the clean up, if it's 1 no need to the clean-up, store 0 and move on.

    Many programs use this method to detect if the program was closed properly.

提交回复
热议问题