본문 바로가기
개발, IT

TerminateProcess()

by Nabi™ 2009. 7. 17.


TerminateProcess 를 사용해도 되는건지...

Win32 API 에 보면 TerminateProcess 라는 함수가 있습니다. 함수명 그대로 Process 를 강제로 Kill 시키는 함수입니다. 하지만 Jeffery Richter 의 Programming Application for Win2k 나 기타 이와 관련된 설명을 하는 책이면 되도록 쓰기를 권고하지 않는 함수로서 설명하고 있습니다. 이유는 여러가지 있습니다만 그 중에 한 이유를 소개하면 여러 리소스 정리가 되지 않고 바로 죽기 때문입니다.


그럼 어떻게 하나?

쓰지 말라고 하였으니 안 쓰면 되지 하겠지만, 그런데 꼭 쓸 경우가 생깁니다.

만약 위의 권고를 이미 알고 있는 사용자라면 더욱 고민하겠지요. 결국 권고를 무시하고 쓰는 경우가 많은데, 이를 위해 더 안전한 방법을 소개 합니다. 이 방법은 이미 DDJ 에 소개된 방법입니다만 모르는 분이 많은 것 같아 소개합니다.

사용법은 아래와 같이 함수를 작성하고 TerminateProcess 와 똑같이 호출해주시면 됩니다.

BOOL SafeTerminateProcess(HANDLE hProcess, UINT uExitCode)
{
  DWORD dwTID, dwCode, dwErr = 0;
  HANDLE hProcessDup = INVALID_HANDLE_VALUE;
  HANDLE hRT = NULL;
  HINSTANCE hKernel = GetModuleHandle("Kernel32");
 
  BOOL bSuccess = FALSE;
  BOOL bDup = DuplicateHandle(GetCurrentProcess(),
                                  hProcess,
                                  GetCurrentProcess(),
                                  &hProcessDup,
                                  PROCESS_ALL_ACCESS,
                                  FALSE,
                                  0);
  if ( GetExitCodeProcess((bDup) ? hProcessDup : hProcess, &dwCode)
       && (dwCode == STILL_ACTIVE) )
  {
    FARPROC pfnExitProc;
    pfnExitProc = GetProcAddress(hKernel, "ExitProcess");
    hRT = CreateRemoteThread((bDup) ? hProcessDup : hProcess,
                            NULL,
                            0,
                            (LPTHREAD_START_ROUTINE)pfnExitProc,
                            (PVOID)uExitCode, 0, &dwTID);
    if ( hRT == NULL ) dwErr = GetLastError();
  }
  else
  {
       dwErr = ERROR_PROCESS_ABORTED;
   }
   if ( hRT )
  {
      WaitForSingleObject((bDup) ? hProcessDup : hProcess, INFINITE);
      CloseHandle(hRT);
      bSuccess = TRUE;
  }
  if ( bDup )
  CloseHandle(hProcessDup);
  if ( !bSuccess )
  SetLastError(dwErr);
 
return bSuccess;
}

  위의 소스 코드를 분석해보면 원리는 간단합니다. Kernel32.dll 에 있는 ExitProcess라는 함수에 대한 포인터를 얻고 그것을 CreateRemoteThread를 이용하여 호출하여 그 프로세스가 스스로 죽는 효과를 만들어 내는 것입니다.

물론 DuplicateHandle 등 부수적인 체크 등을 위해 넣은 코드들은 있지만 기본 원리는 이와 같이 간단합니다.

이를 사용할 때의 주의점은 Win9X 계열은 이 방법을 사용할 수 없다는 점입니다. CreateRemoteThread 라는 API 를 사용하는데 이것은 Win9X 에서는 지원하지 않는 함수이므로 사용할 수 없는 것입니다. 따라서 이 점 주의해주십시오.

좋은정보가 되셨다면 아래 한번 클릭해주세요^^


댓글