서브시스템 관리자 Csrss.exe (Client-Server Runtime Subsystem)

Client-Server Runtime Subsystem의 약자로, Basesrv.dll, winsrv.dll, csrsrv.dll를 로드하여 Console Windows 처리, 프로세스와 스레드 생성과 삭제, 16비트 가상 DOS 머신(VDM) 프로세스를 위한 기능 일부 및 SxS(Side-by-Side) 지원 한다.

Windows Startup Process임과 동시에 서브시스템 관리 프로세스로써 중요한 위치를 차지하는 프로세스이며, 이 역시 네이티브 어플리케이션이다.

레지스트리 (HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems\Windows키)에서 설정값을 확인할 수 있다.

그리고 CSRSS은 윈도우 서브시스템 DLL과 빠른 통신을 위해 LPC(Local Inter-Process Communication)로 처리를 하게 된다. LPC는 서브시스템 간 통신에 사용방식으로 바로 다음에 설명한다.

%SystemRoot%\system32\Csrss.exe ObjectDirectory=\Windows SharedSection=1024,3072,512 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=winsrv:ConServerDllInitialization,2 ProfileControl=Off MaxRequestThreads=16

[내용] 레지스트리에 저장된 Csrss 참조 값

이 프로세스는 추가로 Desktop-Heap에 대해 이해를 하여야 본 프로세스를 이해하는데 도움이 되므로, 이는 메모리관리를 설명 할 때 다시 다루어야 하므로 이정도만 설명하고, Csrss.exe가 제공하는 Export 함수들에 대해 확인해 보도록 하자.

LPC

고속으로 서로 다른 구조에서 데이터를 교환하는데 흔히 사용된다. Win32 응용프로그램이 CSRSS와 통신할 때, SRM(Security Reference Monitor’s)및 Winlogon와 LSASS간 통신등에 사용되며, 비스타에서부터 강제 동기화 방식으로 진행되던 LPC를 비동기화 방식으로 새롭게 추가하였는데, 이를 ALPC(Asynchronous Local Inter-Process Communication) 라고 한다.

서브시스템 관리자 Csrss.exe (Client-Server Runtime Subsystem)

서브시스템 관리자 Csrss.exe (Client-Server Runtime Subsystem)

[그림] LPC에 사용되는 API와 처리 흐름

아래는 LPC에서 제공하는 API로 Native API들이다. 이 API는 NTDLL.dll과 NTOSKRNL.exe를 통해 제공되며, Win32 어플리케이션은 LPC를 직접 사용할 수 없다.

LPC에는 아래와 같은 API를 이용하여, 서로 통신을 진행한다.

API 설명
NtCreatePort 서버가 포트를 생성할 때 사용
NtConnectPort 클라이언트가 포트 연결할 때 사용
NtListenPort 서버에서 연결된 리스트를 요청이 왔을 때 사용
NtAcceptConnectPort 서버에서 연결 허용 요청이 수락 할 때 사용
NtCompleteConnectPort 서버에서 연결 요청에 대한 연결이 완료 되었을 때 사용
NtRequestPort 메시지를 보내고 회신을 기다리지 않는다.
NtRequestWaitReplyPort 메시지를 보내고 회신을 기다린다.
NtReplyPort 회신 메시지를 보낸다.
NtReplyWaitReplyPort 회신 메시지를 보내고, 응답을 기다린다.
NtReplyWaitReceivePort 서버에서 회신 메시지를 보내고, 클라이언트의 응답을 기다린다.
NtImpersonateClientOfPort 서버 스레드에 의해 사용되는데, 클라이언트 스레드의 보안 컨테스트를 임시로 획득한다.

[내용] LPC API 리스트

Windbg에서 LPC를 효과적으로 확인할 수 있는 확장 명령을 제공하는데, 바로 !lpc에 파라메터를 추가하여 사용할 수 있다.

파라메터 설명
message [id] 큐 안의 메시지 내용을 표시해 준다. 메시지ID를 주지 않으면 전체를 보여준다.
port [portaddress] 포트 상태 정보를 보여준다. portaddress를 주지 않은면 전체를 보여 준다.
scan portaddress 지정한 포트어드레스주소에서 오브젝트 타입이 “Port”거나 “WaitablePort”인 포트 정보를 보여준다.
thread [threadaddress] ETHREAD의 LpcReplyChain의 오브젝트가 “Port”거나 “WaitablePort”인 스레드는 회신을 기다리게 되는데, 전체 스레드에서 LpcReceivedMessageId, LpcReplyMessageId가 동일한Port 정보를 보여 준다. 특정 스레드를 주지 않으면 전체를 보여준다.
poolsearch Kernel Pool에서 LPC tag인 (“LpcM”)로 되어 있는 내용을 “lpc message” 방식으로 검색하여 보여준다.

[내용] Windbg !lpc 명령어 파라메터

이 같은 정보를 이용해 Windbg를 통해 LPC정보를 확인할 수 있다. 만약 LPC통신을 이용하던 도중 문제가 발생하였다면, 위 쿼리 흐름처럼 어디에서 대기(Wait)상태가 지속되는지를 확인할 수 있다. 아래는 Windbg를 통해 대기 상태인 스레드의 LPC 내용을 확인하는 과정이다.

kd> !lpc thread

Searching message 0 in threads …

Server thread 81d17020 is working on message aea

Client thread 81da4020 waiting a reply from cff

Server thread 81d08478 is working on message 1053

Server thread 81ceb660 is working on message ac4

Server thread 81af2920 is working on message cff

Server thread 81aef020 is working on message b3b

Server thread 81e08da8 is working on message 8a1

Server thread 81cfada8 is working on message cf6

Server thread 81bbb020 is working on message 1042

Server thread 81bdbab8 is working on message 51d

Server thread 81b45b30 is working on message 102f

Server thread 81d1c560 is working on message 906

Server thread 81d15da8 is working on message 1041

Server thread 81d4dda8 is working on message 103d

Server thread 81b45020 is working on message 1043

Done.

.

kd> !thread 81da4020

THREAD 81da4020 Cid 0284.028c Teb: 7ffde000 Win32Thread: e16f1848 WAIT: (WrLpcReply) UserMode Non-Alertable

81da4214 Semaphore Limit 0x1

Waiting for reply to LPC MessageId 00000cff:

Current LPC port e1b92380

Not impersonating

DeviceMap e10087c0

Owning Process 0 Image: <Unknown>

Attached Process 81ce8da0 Image: Csrss.exe

Wait Start TickCount 1909 Ticks: 795 (0:00:00:07.961)

Context Switch Count 7 LargeStack

UserTime 00:00:00.000

KernelTime 00:00:00.000

Start Address 0x764c7d63

Stack Init f4f1a000 Current f4f19c50 Base f4f1a000 Limit f4f17000 Call 0

Priority 15 BasePriority 15 PriorityDecrement 0 DecrementCount 0

ChildEBP RetAddr Args to Child

f4f19c68 804de0f7 81da4090 81da4020 804de143 nt!KiSwapContext+0x2e (FPO: [Uses EBP] [0,0,4])

f4f19c74 804de143 81da4214 81da41e8 81da4020 nt!KiSwapThread+0x46 (FPO: [0,0,0])

f4f19c9c 80578fc6 00000001 00000011 81da4001 nt!KeWaitForSingleObject+0x1c2 (FPO: [Non-Fpo])

f4f19d50 804e07ec 00000084 0050ff00 0050ff00 nt!NtRequestWaitReplyPort+0x63d (FPO: [Non-Fpo])

f4f19d50 7c93e4f4 00000084 0050ff00 0050ff00 nt!KiFastCallEntry+0xf8 (FPO: [0,0] TrapFrame @ f4f19d64)

WARNING: Frame IP not in any known module. Following frames may be wrong.

0050fff4 00000000 00000000 00000000 00000000 0x7c93e4f4

kd> !lpc message 00000cff

Searching message cff in threads …

Client thread 81da4020 waiting a reply from cff

Server thread 81af2920 is working on message cff

Searching thread 81da4020 in port rundown queues …

Server communication port 0xe16ea378

Handles: 1 References: 1

The LpcDataInfoChainHead queue is empty

Connected port: 0xe1b92380 Server connection port: 0xe1721468

Client communication port 0xe1b92380

Handles: 1 References: 2

The LpcDataInfoChainHead queue is empty

Server connection port e1721468 Name: SmSsWinStationApiPort

Handles: 1 References: 11

Server process : 81d402d8 (svchost.exe)

Queue semaphore : 81b7f778

Semaphore state 0 (0x0)

The message queue is empty

The LpcDataInfoChainHead queue is empty

Done.

[내용]Windbg에서 사용중인 LPC 확인

Facebook Comments

Leave A Reply

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.