Kernel Object
최근 프로그래밍에 관심이 많아 공부를 하고 있는데 오늘은 커널 오브젝트라는 것에 대해서 공부를 해보았다.
Kernel Object(커널 오브젝트)는 Window에서 프로세스, 쓰레드와 같은 리소스들을 쉽게 관리하기 위해 저장해놓은 데이터 메모리 블록을 커널 오브젝트라고 한다. 커널 오브젝트는 Window 커널에서 관리하는 리소스 수 만큼 커널 오브젝트도 생성된다.
커널 오브젝트는 운영체제가 관리하고 프로세스에게 빌려주는 개념으로 생각하면 편리하다. 커널 오브젝트 소멸 시점로 예시를 들면 운영체제에 의해서 결정이 된다고 생각하면 된다. 그리고 여러 프로세스가 하나의 커널 오브젝트에 접근이 가능하다.
커널 오브젝트에 대한 소멸이야기가 나왔으니 이것에 대해서 더 이야기를 해보자.
A라는 프로세스에서 B프로세스를 생성하게 되면 B의 커널 오브젝트도 생성이 된다. 이때 CloseHandle 함수를 이용하여 B의 프로세스 핸들을 반환하여도 B의 커널 오브젝트은 소멸되지 않는다. B 커널 오브젝트는 B 프로세스가 종료되었을 경우에 소멸이 되는거다.
위의 예시에서 자식 프로세스인 B의 종료 코드는 어디에 저장이 될까? 그건 자식 프로세스의 커널 오브젝트에 저장이 된다.
그럼 커널 오브젝트를 언제 소멸시키는게 가장 좋을까?? 해당 커널 오브젝트를 참조하는 대상이 하나도 없을 때 소멸시키는 것이 가장 좋다. 이 방법이 Window가 커널 오브젝트 소멸시기를 결정하는 방식이다.
Window는 커널 오브젝트 참조 대상이 하나도 없을 때 소멸시키는 방법을 사용하기 위하여 Usage Count(참조 횟수)라는 것을 관리하는데 이 Usage Count 가 0이 되는 순간 커널 오브젝트는 소멸된다. 반대로 프로세스를 생성할 시에 커널 오브젝트 Usage Count는 1이 되고 해당 프로세스의 커널 오브젝트를 참조하면 Usage Count가 하나씩 증가가 되는 것이다.
간단한 예를 들면 자식 프로세스가 생성 되었을 경우 이 자식 프로세스의 Usage Count는 2가되어야 한다. 그 이유는 부모 프로세스에서 CreateProcess 를 호출하여 자식 프로세스의 핸들을 얻기 때문이다.
CloseHandle 함수가 나온 예제를 다시 가져와 이야기를 해보자. 이 예제에서도 나온 것처럼 프로세스 핸들을 반환한다고 커널 오브젝트가 소멸되지 않는다. 즉, B 프로세스 Usage Count는 2라는 것이다.
[CloseHandle 전 Usage Count]
[CloseHandle 후 Usage Count]
만약 CloseHandle을 하기 전에 프로세스를 종료해버리면 어떻게 될까??
[CloseHandle을 하지 않고 프로세스를 종료 시켰을 경우]
Usage Count가 1인 상태로 커널 오브젝트가 남아버리는 상태가 되버리는 것이다. 이렇게 되면 문제가 되기 때문에 프로세스 종료전 반드시 프로세스 핸들을 반환해줘야 한다.
마지막으로 커널 오브젝트의 상태에 대해서 이야기를 해보자. 커널 오브젝트는 두가지 상태를 가지는데 signaled 와 non-signaled 다.
먼저 signaled 는 이벤트가 발생하기 전까지 대기하고 있는 상태라 생각하면 되겠다. non-signaled 은 반대로 이벤트가 발생하여 사용 중이여서 기달리라는 상태가 되겠다.
'My Study > System' 카테고리의 다른 글
Critical Section(임계 영역) 개념 (0) | 2016.07.04 |
---|---|
Process Handle (0) | 2016.06.30 |
API Hooking x86 x64 (0) | 2016.05.23 |
DLL Injection (3) - Injector 사용 (0) | 2016.05.23 |
DLL Injection (2) - EAT 를 이용한 DLL Injection (0) | 2016.05.23 |