Windows에서 프로세스를 강제 종료하려면 TerminateProcess() API를 사용하면 된다.
그런데 Windows NT 계열에서 TerminateProcess()를 사용하려면 PROCESS_TERMINATE 접근 권한을 가지는 프로세스 핸들이 필요하다.
OpenProcess()로 PROCESS_TERMINATE 접근 권한의 프로세스 핸들을 얻을 수 있는데 그 전에 먼저 SeDebugPrivilege 권한을 획득해야 한다.
따라서 프로세스를 종료하기 위한 절차는 다음과 같다.
1. 현재 프로세스의 권한을 변경하기 위한 액세스 토큰의 핸들을 가져온다.
OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken)
2. 액세스 토큰에 SeDebugPrivilege 권한을 추가한다.
SetPrivilege(hToken, SE_DEBUG_NAME, TRUE);
SetPrivilege() - 액세스 토근의 권한을 변경하기 위한 함수
SetPrivilege 소스 보기..
BOOL SetPrivilege(
HANDLE hToken, // 토큰 핸들
LPCTSTR Privilege, // 활성/비활성화할 권한
BOOL bEnablePrivilege // 권한 활성화 여부?
)
{
TOKEN_PRIVILEGES tp;
LUID luid;
TOKEN_PRIVILEGES tpPrevious;
DWORD cbPrevious=sizeof(TOKEN_PRIVILEGES);
if (!LookupPrivilegeValue( NULL, Privilege, &luid ))
return FALSE;
// 현재의 권한 설정 얻기
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = 0;
AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
&tpPrevious,
&cbPrevious
);
if (GetLastError() != ERROR_SUCCESS)
return FALSE;
// 이전의 권한 설정에 따라 권한 설정하기
tpPrevious.PrivilegeCount = 1;
tpPrevious.Privileges[0].Luid = luid;
if (bEnablePrivilege) {
tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
}
else {
tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED &
tpPrevious.Privileges[0].Attributes);
}
AdjustTokenPrivileges(
hToken,
FALSE,
&tpPrevious,
cbPrevious,
NULL,
NULL
);
if (GetLastError() != ERROR_SUCCESS)
return FALSE;
return TRUE;
}
3. 원하는 윈도우를 찾아서 프로세스 ID를 가져온다.
HWND hWnd = FindWindow(_T("종료시킬 윈도우"), NULL);
if (!hWnd)
return 1;
DWORD nProcessId;
GetWindowThreadProcessId(hWnd, &nProcessId);
4. 프로세스 ID로 PROCESS_TERMINATE의 접근 권한을 가지는 프로세스 핸들을 얻고 종료시킨다.
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, nProcessId);
if (hProcess)
{
TerminateProcess(hProcess, -1);
CloseHandle(hProcess);
}
5. 액세스 토큰에서 SeDebugPrivilege 권한을 제거하고 액세스 토큰 핸들을 닫는다.
SetPrivilege(hToken, SE_DEBUG_NAME, FALSE);
CloseHandle(hToken);