当一个进程被终止(未关闭)时,除非你开始做一些挂钩,要么通过挂钩TerminateProcess
或NtTerminateProcess
在任务管理器进程中,否则什么都做不了,它是如何工作的示例:
#include <windows.h>
#include <assert.h>
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;
}
这个钩子TerminateProcess
在同一个进程中,你需要把它放在一个DLL中并注入到Task Maneger进程中,没有测试它。但这种方法过于繁琐且不安全,某些 AV 产品可能会将其检测为有害程序。
一个简单的解决方案是按照@Martin James 的建议清理程序启动。在您的程序启动时创建一个文件或使用注册表来存储一些值,例如0
,如果程序已关闭,WM_CLOSE
如果它是 GUI 或CTRL_CLOSE_EVENT
如果您关闭了命令提示符,则进行清理并存储1
。
在下一次启动时,您检查该值是否仍然存在0
,这意味着程序没有正确关闭,请进行清理,如果1
不需要清理,存储0
并继续。
许多程序使用这种方法来检测程序是否正确关闭。