The Windows kernel provides a set of mechanisms for terminating a process. Termination can be initiated by the process itself, another process, or the operating system in response to critical failures.
Key concepts include:
ExitProcess
TerminateProcess
PsTerminateProcess
PsSetCreateProcessNotifyRoutineEx
)#include <windows.h>
int main()
{
// Perform cleanup tasks
// ...
// Exit with a status code
ExitProcess(0);
return 0; // Unreachable
}
#include <windows.h>
#include <stdio.h>
int main()
{
DWORD pid = 1234; // Target PID
HANDLE h = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
if (h == NULL) {
printf("Unable to open process: %lu\n", GetLastError());
return 1;
}
if (!TerminateProcess(h, 1)) {
printf("TerminateProcess failed: %lu\n", GetLastError());
} else {
printf("Process terminated.\n");
}
CloseHandle(h);
return 0;
}
NTSTATUS
PsTerminateProcess(
_In_ PEPROCESS Process,
_In_ NTSTATUS ExitStatus
);
This routine must be called from within kernel mode and requires proper security considerations.
Windows uses a 32‑bit unsigned integer to represent process exit codes. Common conventions:
0
– Success1
– Generic error0xC0000005
– Access violationThe following snippet spawns a child process and then terminates it after a delay.
#include <windows.h>
#include <stdio.h>
int main()
{
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
if (!CreateProcess(L"C:\\Windows\\System32\\notepad.exe",
NULL, NULL, NULL, FALSE,
0, NULL, NULL, &si, &pi)) {
printf("CreateProcess failed: %lu\n", GetLastError());
return 1;
}
Sleep(3000); // Let Notepad run for 3 seconds
if (!TerminateProcess(pi.hProcess, 0)) {
printf("TerminateProcess failed: %lu\n", GetLastError());
} else {
printf("Notepad terminated.\n");
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return 0;
}
ExitProcess
) over forced termination.TerminateProcess
only when a process cannot be stopped safely.PEPROCESS
pointer before calling PsTerminateProcess
.