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 で出荷し、タスク マネージャー プロセスに挿入する必要がありますが、テストしていません。しかし、この方法はやり過ぎで安全ではありません。AV 製品によっては、有害なプログラムとして検出される場合があります。
簡単な解決策は、@Martin James が提案したように、プログラムの起動時にクリーンアップすることです。プログラムの起動時にファイルを作成するか、レジストリを使用して のような値を保存します。プログラムが閉じられた場合、GUI の場合0
は受け取った場合、またはコマンド プロンプトを閉じた場合は、クリーンアップを実行して を保存します。WM_CLOSE
CTRL_CLOSE_EVENT
1
次の起動時に、まだ値が変わらない場合はその値を確認します0
。これは、プログラムが適切に閉じられなかったことを意味し、クリーンアップが1
必要ない場合はクリーンアップを行い、保存して次に0
進みます。
多くのプログラムは、このメソッドを使用して、プログラムが適切に閉じられたかどうかを検出します。