커널모드 시스템 디스패칭과 서비스 디스크립터 테이블
- Windows Server 2008
[커널모드 시스템 디스패칭]
커널은 시스템 서비스 디스패치 테이블에서 시스템 서비스 정보를 찾기 위해 시스템 호출 번호를 사용한다. 이 테이블은 각 엔트리가 인터럽트 처리 루틴이 아닌 시스템 서비스에 대한 포인터를 갖고 있다는 점만 제외하면 인터럽트 디스패치 테이블과 유사하다.
시스템 서비스 디스패처인 KiSystemService는 스레드의 유저모드 스택에 있는 호출자의 인자를 스레드의 커널 스택에 복사하고 시스템 서비스를 실행 한다. 이전 모드는 커널이 트랩 핸들러를 실행할 때마다 스레드에 저장하는 값이며 발생할 예외나 트랩 시스템 호출에 대한 특권 레벨을 식별한다.
커널모드 코드는 시스템 호출이 가능하고 CPU는 이미 적당한 특권 레벨 상태이며 커널과 더불어 드라이버도 필요한 함수를 직접 호출 할 수 있다. 익스큐티브 계층의 경우 커널은 자신의 모든 루틴을 접근할 수 있으며 표준 루틴처럼 이들을 호출 할 수 있다. 하지만 외부적으로 드라이버는 이들 시스템 호출이 그 밖의 다른 표준 커널모드 API처럼 익스포트되어 있다면 이들에 접근만 할 수 있다. (실제로 소수의 시스템 호출만이 익스포트되어 있다.)
커널은 NtCreateFile 같은 함수를 직접 호출한다면 커널은 유저모드임을 나타내는 이전 모드 값을 보관하고 전달된 주소가 커널모드 주소임을 탐지해 호출을 실패시키고 유저모드 애플리케이션은 커널모드 포인터를 전달하지 말아야 함을 정화하게 어서트(assert)한다. 하지만 실제로 이렇게 동작하지는 않는다.
익스포트된 API는 실제로 간단한 별칭이거나 Nt버전을 감싸는 래퍼(wrapper)의 기능을 하며 지원되지 않을 수도 있는 인터럽트를 발생하거나 syssenter 대신 이들 API는 가짜 인터럽트 스택을 생성하고 직접 KiSystemService 루틴을 호출 하여 CPU 인터럽트를 그대로 에뮬레이션 한다. 핸들러는 이 호출이 이루어진 실제 특권 레벨을 탐지해 이전 모드를 커널로 설정한다는 점을 제외하면 이 호출이 마치 유저모드로 온 것 같은 동일한 동작을 실행 한다. 이는 호출이 커널로부터 왔음을 알고서 더 이상 실패 시키지 않는다.
각 스레드는 자신의 시스템 서비스 테이블(32비트와 IA64 버전만 해당, 그외 버전은 주소가 하드코딩되어 있음)에 대한 포인터를 가진다. 윈도우는 내장된 두 개의 시스템 서비스 테이블을 가진다. 서드파티 드라이버는 자신의 서비스 호출을 추가하기 위해 이 테이블을 확장할 수 없다.
시스템 서비스 디스패처는 32비트 시스템 서비스 번호에서 2비트 크기의 필드를 테이블 인덱스로 해석해 요청된 서비스가 어느 테이블에 있는 지를 결정한다. 시스템 서비스 번호의 하위 12비트는 테이블 인덱스가 나타내는 테이블에 대한 인덱스 역할을 한다.
[서비스 디스크립터 테이블]
서비스 디스크립터 테이블은 주 디폴트 배열 테이블인 KeServiceDescriptorTable은 Ntosrknl.exe에 구현된 익스큐티브의 핵심 시스템 서비스를 정의한다. 또 하나의 배열 테이블인 KeServiceDescriptorTableShadow는 윈도우 서브시스템의 커널모드 부분에 구현된 윈도우 USER와 GDI 서비스(Win32k.sys)를 포함 한다.
윈도우 익스큐티브 서비스용 시스템 서비스 디스패치 명령은 시스템 라이브러리인 Ntdll.dll에 있다, 서브시스템 DLL은 문서화된 자신의 함수를 구현하기 위해 Ntdll 내의 함수를 호출 한다.
아래 그림에서 보면 윈도우 Kernel32.dll 내의 WriteFile 함수는 Ntdll.dll의 NtWritefile 함수를 호출하고 NtWriteFilie 함수는 NtwriteFile임을 나타내는 시스템 서비스 번호를 전달하면서 시스템 서비스 트랩을 유발하기 위한 적절한 명령을 실행 한다. 이제 시스템 서비스 디스패처는 I/O 요청을 처리하기 위해 실제 NtWriteFile을 호출 한다. 윈도우 USER와 GDI 함수의 경우 시스템 서비스 디스패치는 윈도우 서비스시스템의 커널모드 중 일부로서 로드 가능한 Win32k.sys 내의 함수를 호출 한다.
[참고자료]
Windows Internals
'Windows , IIS' 카테고리의 다른 글
객체구조 – 객체 헤더와 본체 (0) | 2015.07.16 |
---|---|
익스큐티브 객체 (0) | 2015.07.16 |
32비트, 64비트 시스템 서비스 디스패칭 (0) | 2015.07.16 |
윈도우 오류 보고 (0) | 2015.07.16 |
처리되지 않은 예외 (0) | 2015.07.16 |