'Process'에 해당되는 글 2건

  1. 2009.07.11 프로세스 종료 여부 검사하기 _EPROCESS::ProcessExiting
  2. 2008.12.01 [API] Kill Process
Hacking & Security/Kernel2009. 7. 11. 21:03

프로세스가 종료되어도 EPROCESS 포인터는 유효한 경우가 많더군요.
종종 프로세스의 가상 메모리를 읽어야 하는 경우가 있는데 이 경우 문제의 소지가 다분합니다.
그래서 뭐 좋은 방법 없나 고민하던 하다가 실제로 종료되었지만 남아있는 EPROCESS 와 그렇지 않은 녀석을 하나 하나 비교해 봤습니다.
역시나 아는게 없으니 .. 노가다를 할 수 밖에 없네요. ㅜㅜ
혹시 더 좋은 방법을 아시는분은 알려주시면 정말 감사하겠습니다. :-)

EPROCESS 에 믿어도 될만한 필드가 존재하는 것 같네요.
EPROCESS 구조체를 살펴보면 (XP sp2 입니다)


kd> de _EPROCESS
+0x000 Pcb : _KPROCESS
+0x06c ProcessLock : _EX_PUSH_LOCK
..........
+0x248 Flags : Uint4B
+0x248 CreateReported : Pos 0, 1 Bit
+0x248 NoDebugInherit : Pos 1, 1 Bit
+0x248 ProcessExiting : Pos 2, 1 Bit
+0x248 ProcessDelete : Pos 3, 1 Bit
+0x248 Wow64SplitPages : Pos 4, 1 Bit
+0x248 VmDeleted : Pos 5, 1 Bit
+0x248 OutswapEnabled : Pos 6, 1 Bit
+0x248 Outswapped : Pos 7, 1 Bit
+0x248 ForkFailed : Pos 8, 1 Bit
+0x248 HasPhysicalVad : Pos 9, 1 Bit
+0x248 AddressSpaceInitialized : Pos 10, 2 Bits
+0x248 SetTimerResolution : Pos 12, 1 Bit
+0x248 BreakOnTermination : Pos 13, 1 Bit
+0x248 SessionCreationUnderway : Pos 14, 1 Bit
+0x248 WriteWatch : Pos 15, 1 Bit
+0x248 ProcessInSession : Pos 16, 1 Bit
+0x248 OverrideAddressSpace : Pos 17, 1 Bit
+0x248 HasAddressSpace : Pos 18, 1 Bit
+0x248 LaunchPrefetched : Pos 19, 1 Bit
+0x248 InjectInpageErrors : Pos 20, 1 Bit
+0x248 VmTopDown : Pos 21, 1 Bit
+0x248 Unused3 : Pos 22, 1 Bit
+0x248 Unused4 : Pos 23, 1 Bit
+0x248 VdmAllowed : Pos 24, 1 Bit
+0x248 Unused : Pos 25, 5 Bits
+0x248 Unused1 : Pos 30, 1 Bit
+0x248 Unused2 : Pos 31, 1 Bit


0x248 지점에 32비트 비트필드 스트럭쳐(이렇게 부르는거 맞나요.. -_-;)가 있습니다.
여러 플래그들이 있는데 그 중에


+0x248 ProcessExiting : Pos 2, 1 Bit
+0x248 ProcessDelete : Pos 3, 1 Bit


이런 플래그가 있더군요.
살아있는 프로세스는 이 필드 값이 0x0 이고요 죽어있는 프로세스의 경우 0x1 입니다.
ExitTime 필드도 있긴 한데 여러번 테스트 해본 결과 정확하지 않은것 같더군요.

혹시나 해서 인터넷을 뒤적거리다 보니 PsGetProcessExitProcessCalled() 라는 함수가 있더군요.
이 함수를 디스어셈블 해보면...


kd> u nt!PsGetProcessExitProcessCalled
nt!PsGetProcessExitProcessCalled:
8062e1d7 8bff mov edi,edi
8062e1d9 55 push ebp
8062e1da 8bec mov ebp,esp
8062e1dc 8b4508 mov eax,dword ptr [ebp+8]
8062e1df 8b8048020000 mov eax,dword ptr [eax+248h]
8062e1e5 c1e802 shr eax,2
8062e1e8 2401 and al,1
8062e1ea 5d pop ebp
8062e1eb c20400 ret 4


정확히 ProcessExiting 필드를 참조하는 것을 확인 할 수 있습니다.
믿고 사용해도 될 듯 합니다.

출처 : http://somma.egloos.com/3077904
Posted by skensita
Programming/Win32 API2008. 12. 1. 15:42

프로세스를 죽이는 방법은 여러가지가 있지만 남의 프로그램을 Class Name, Windows Name으로

Process Id를 얻어내어 프로세스를 Kill 시키는 방법을 기술한다.


참고로 Process Id와 Process Name 은 Spy++ 로 쉽게 확인 할수 있다.

또한 다이얼로그 기반 프로세스는 Windows Name이 없기 때문에 Null값을 입력하면 된다.


//먼저 핸들값을 얻어낸다.

hwnd = FindWindow(TEXT("Class Name"),TEXT("Windows Name"));

if(hwnd == NULL)
 {
  return false;

 }


//핸들값을 통해 ProecssId를 도출한다.

DWORD dwProcessId = NULL;
 GetWindowThreadProcessId( hwnd,    &dwProcessId);
 if(dwProcessId == NULL)
 {
    return false;
 }


HANDLE  process;
 DWORD  dwError;


//얻어진 ProcessId로 프로세서를 연다.
 process = OpenProcess(PROCESS_TERMINATE, FALSE, dwProcessId );
 dwError = GetLastError();
 if(process == NULL)
 {
    if(dwError == ERROR_INVALID_PARAMETER) // already terminated.
       return true;

 
  return false;
 }


//열려진 Process핸들값으로 해당 프로세서를 종료한다.
 if(!TerminateProcess(process, (UINT)-1))
  printf("KillProcess: TerminateProcess returned false. PID = %u", id);

 CloseHandle(process);
 return true;



꼬리에 꼬리를 무는 식으로 프로그램이 짜여져 있다.

이런것들이 노가다성 작업으로 느껴지기도한다.

Posted by skensita