앞에서 커널 오브젝트의 UsageCount는 공유하는 프로세스의 수만큼 증가한다고 설명했다.
그렇다면 커널 오브젝트를 참조하는 프로세스가 되기 위한 조건은 무엇일까?
핸들 테이블의 관점에서 봤을 때

"프로세스가 핸들을 얻게 되었다"

위의 말의 의미는, 핸들 테이블에 해당 핸들에 대한 정보가 갱신(추가) 되었음을 의미하는 것이다."

예를 들어 createMailslot 함수의 호출을 통해 메일슬롯을 생성햇다고 가정하면,
1) 메일 슬롯 리소스 생성
2) 커널 오브젝트 생성
3) 핸들 정보가 핸들 테이블에 갱신
4) CreateMailslot 함수를 빠져나오며 핸들값 반환

대부분의 경우 프로세스가 핸들을 얻게 되었다고 하면,
보통 4번째 단계에 초점을 맞춰서 생각을 한다. 그러나 이는 잘못된 것이다.
프로세스가 핸들을 얻었다고 말할 수 있는 부분은 3번째 단계 이후부터다.
즉 핸들 테이블에 A 핸들에 대한 정보가 등록되면, A 핸들을 얻은 것이다.

다음은 CreateMailslot 함수와 CreateProcess 함수에서 생성되는 자식 프로세스의
핸들을 상속하기 위한 샘플 코드들이다.

SECURITY_ATTRIBUTES sa;
sa.nLength=sizeof(sa);
sa.lpSecurityDescriptor=NULL;
sa.bInheritHandle=TRUE;

CreateMailslot(~,~,~,&sa);

-----------------

SECURITY_ATTRIBUTES sa;
sa.nLength=sizeof(sa);
sa.lpSecurityDescriptor=NULL;
sa.bInheritHandle=TRUE;

CreateProcess(~,~,&sa,~~~~);

이렇게 자식 프로세스의 핸들이 상속될 수 있도록 설정하면,
이후에 생성되는 자식 프로세스에게 상속될 것이다.

 

Pseudo 핸들과 핸들의 중복(Duplicate)

현재 실행 중에 있는 프로세스 자신의 해늘을 얻는 방법으로써
GetCurrentProcess 함수를 통해 프로세스 자신의 커널 오브젝트에 접근이 가능하다.
하지만 이 함수 호출을 통해 얻은 핸들을 가리켜 가짜 핸들(Pseudo Handle) 이라 한다.
왜냐면 이렇게 얻어진 핸들은 핸들 테이블에 등록되어 있지도 않으며,
단지 현재 실행 중인 프로세스를 참조하기 위한 용도로 정의해 놓은, 약속된 상수가 반환되는 것이기 때문이다.
(현재 -1이 반환되도록 정의되어 잇다) 따라서 자식 프로세스로 상속되지 않으며,
CloseHandle 함수의 인자로 전달할 필요도 없다.
현재 실행중인 프로세스가 GetCurrentProcess 함수 호출을 통해 얻은 가짜 핸들 이외에 핸들
테이블에 등록되어 있는 진짜 핸들을 얻어야 할 필요성이 있는가?
우선 진자 핸들을 얻는 방법에 대해 알아보자.
다음은 DuplicateHandle 이라는 함수이며, 핸들을 복사하는 기능을 지닌다.
만약 현재 실행중인 프로세스의 진짜 핸들을 얻고자 한다면 이 함수를 사용하자

BOOL WINAPI DuplicateHandle(
  __in          HANDLE hSourceProcessHandle,
  __in          HANDLE hSourceHandle,
  __in          HANDLE hTargetProcessHandle,
  __out         LPHANDLE lpTargetHandle,
  __in          DWORD dwDesiredAccess,
  __in          BOOL bInheritHandle,
  __in          DWORD dwOptions
);

1) 복제할 핸들을 소유하는 프로세스를 지정한다
2) 복제할 핸들을 지정한다
3) 복제된 핸들을 소유할 프로세스를 지정한다
4) 복제된 핸들값을 저장할 변수의 주소를 지정한다
5) 복제된 핸들의 접근권한을 지정한다. 방대한 내용이 잇으므로 msdn 참고할 것
6) 복제된 핸들의 상속 여부를 지정한다. TRUE 전달 시 새로운 자식 프로세스로 상속되며, FALSE 전달 시 상속되지 않는다
7) DUPLICATE_SAME_ACCESS 를 전달하면 원본 핸들과 동일한 접근권한을 가지게 된다.
그 외에 DUPLICATE_CLOSE_SOURCE 가 올 수 있는데 이 인자는 원본 핸들을 종료시킨다( CloseHandle과 같다).
이 둘은 비트 단위 OR 연산자를 통해 동시 전달이 가능하다.
이 함수는 4번째 까지의 전달인자가 가장 중요하다.

+ Recent posts