작업 관리자 세부 정보 탭에 "사용자 이름" 열을 켜 두면 대부분 내 계정이나 SYSTEM, LOCAL SERVICE 가 보이는데, 유독 UMFD-0, UMFD-1 처럼 처음 보는 이름이 붙은 줄이 있다. 그 줄의 프로세스가 fontdrvhost.exe 다. 바로 근처에 있는 WUDFHost.exe 도 설명이 "사용자 모드 드라이버 프레임워크 호스트 프로세스"라 무엇을 하는지 감이 잘 오지 않는다. 둘 다 "커널에서 하던 일을 밖으로 꺼냈다"는 공통점이 있어서 한 편에 묶었다.
fontdrvhost 는 세션마다 하나
Get-CimInstance Win32_Process -Filter "Name='fontdrvhost.exe' or Name='WUDFHost.exe'" |
Select-Object Name, ProcessId, ParentProcessId, SessionId, CreationDate
확인한 시점에 fontdrvhost.exe 는 두 개였다. 하나는 세션 0 에서 부모가 wininit.exe, 다른 하나는 세션 1(내가 로그온한 콘솔 세션)에서 부모가 winlogon.exe 였다. 둘 다 PC 를 켠 지 6초 만에 같은 초에 떴다. 부팅 순서 편에서 본 대로 wininit 은 세션 0 을, winlogon 은 사용자 세션을 여는 프로세스다. 세션을 열 때 그 세션의 글꼴 담당도 같이 하나 띄운다고 보면 된다.
UMFD 는 User-Mode Font Driver 의 줄임이고, 뒤의 숫자가 세션 번호다. 세션 0 의 것이 UMFD-0, 세션 1 의 것이 UMFD-1 이다. 원격 데스크톱으로 다른 사용자가 들어오거나 사용자 전환으로 세션이 하나 더 생기면 UMFD-2 가 붙은 fontdrvhost 가 하나 더 생기는 것으로 알려져 있다. 내 PC 에서 일반 권한으로 tasklist /v 를 돌리면 사용자 이름이 N/A 로 나왔다. 이 계정은 사람이 쓰는 계정이 아니라 이 프로세스에 권한을 최소로 주려고 만든 가상 계정으로 알려져 있다.
파일은 C:\Windows\System32\fontdrvhost.exe, 866,080바이트, 설명 "Usermode Font Driver Host", 버전 10.0.26100.9711 이고 Microsoft Windows 서명이 유효했다. 개인 메모리는 세션 0 쪽 3.0MB, 세션 1 쪽 6.0MB, 작업 집합은 둘 다 1MB 도 안 됐다. 성능 카운터로 잰 CPU 는 0% 였다.
왜 글꼴을 커널 밖에서 읽나
예전 Windows 에서는 TrueType·OpenType 글꼴 파일을 해석하는 코드가 커널(win32k) 안에 있었다. 글꼴 파일은 생각보다 복잡한 구조라 해석 코드에 결함이 나기 쉬운데, 그 결함이 커널 안에 있으면 조작한 글꼴 하나로 시스템 권한까지 넘어갈 수 있다. 실제로 그런 공격이 여러 번 있었던 것으로 알려져 있다. Windows 10 부터 이 해석 작업을 권한이 거의 없는 별도 프로세스로 옮겼고, 그것이 fontdrvhost 다. 글꼴 해석이 잘못되어도 무너지는 것은 이 작은 프로세스 하나에 그친다.
이 PC 의 C:\Windows\Fonts 에는 파일이 836개(약 890MB) 있었다. TTF 603개, 옛 비트맵 글꼴인 FON 192개, OTF 와 TTC 가 18개씩이었다. 그래도 fontdrvhost 의 메모리는 몇 MB 였다. 글꼴 목록과 캐시는 Windows Font Cache Service(FontCache)가 따로 맡는다.
fontdrvhost 의 CPU 가 계속 높다면 대개 글꼴을 대량으로 그리는 프로그램이 있거나, 손상된 글꼴 파일을 해석하다 막히는 경우로 보인다. 최근에 글꼴을 설치했다면 그것부터 의심해 볼 만하다. 설정 → 개인 설정 → 글꼴에서 최근 설치한 것을 확인하고 지울 수 있다.
WUDFHost 는 장치 드라이버의 그릇
WUDFHost.exe 는 UMDF(User-Mode Driver Framework)로 만든 드라이버를 담는 프로세스다. 블루투스 기기, 센서, 휴대폰 파일 전송, 스마트카드 리더처럼 속도보다 안정성이 중요한 장치는 드라이버를 사용자 모드로 만들 수 있다. 드라이버가 죽어도 블루스크린이 아니라 그 WUDFHost 하나가 다시 뜨는 것으로 끝난다.
확인한 시점에 WUDFHost.exe 는 두 개였다. 둘 다 세션 0 에서 부모가 services.exe 였고, 개인 메모리는 2.7MB, 2.2MB 였다. 하나는 부팅 직후, 다른 하나는 그로부터 약 1시간 11분 뒤에 떴다. 파일은 C:\Windows\System32\WUDFHost.exe, 380,256바이트, 버전 10.0.26100.9949, 서명 유효였다. 일반 권한에서는 명령줄이 비어 보이지만, 관리자 권한으로 보면 어느 장치를 맡았는지 가리키는 인수가 붙어 있는 것으로 알려져 있다.
어떤 장치를 맡고 있는지 찾기
명령줄 없이 찾는 방법은 장치 쪽에서 거꾸로 보는 것이다. UMDF 드라이버를 쓰는 장치는 드라이버 스택에 커널 쪽 중계 드라이버인 WUDFRd(UMDF Reflector)가 들어 있다.
Get-PnpDevice -PresentOnly -Class HIDClass, Bluetooth, WPD, Sensor, SmartCardReader -ErrorAction SilentlyContinue |
Where-Object { (Get-PnpDeviceProperty -InstanceId $_.InstanceId -KeyName DEVPKEY_Device_Stack).Data -match 'WUDFRd' } |
Select-Object Class, FriendlyName
이 PC 에서 연결된 장치 257개를 -Class 없이 전부 검사했더니 3분이 넘게 걸렸다. 위처럼 UMDF 를 자주 쓰는 장치 종류로 먼저 좁혀도 1분 반쯤 걸렸으니 결과가 나올 때까지 기다려야 한다. 장치 관리자에서 보려면 장치 속성 → 드라이버 탭 → "드라이버 세부 정보"에 WUDFRd.sys 가 있는지 보면 된다.
257개 가운데 걸린 것은 세 장치였다.
| 장치 종류 | 이름 | UMDF 드라이버 |
|---|---|---|
| HIDClass | Bluetooth 저에너지 GATT 준수 HID 장치 (마우스 1) | mshidumdf |
| HIDClass | Bluetooth 저에너지 GATT 준수 HID 장치 (마우스 2) | mshidumdf |
| WPD | USB 로 연결된 휴대폰 | WUDFWpdMtp (MTP) |
앞의 둘은 드라이버 스택이 mshidumdf > WUDFRd > BthLEEnum 순이었고, 부모 장치를 따라가 보니 각각 블루투스 저전력(BLE) 마우스였다. BLE 기기의 입력은 HID over GATT 라는 UMDF 드라이버가 처리하는 것으로 알려져 있다. 세 번째는 USB 로 연결되어 있던 휴대폰이었고, 탐색기에서 휴대폰 파일을 보여 주는 MTP 전송을 사용자 모드 드라이버가 맡는다.
장치는 셋인데 WUDFHost 는 둘이었다. UMDF 는 장치마다 꼭 그릇을 하나씩 만들지 않고, 같은 드라이버를 쓰는 장치들은 한 WUDFHost 에 묶을 수 있는 것으로 알려져 있다. 이 PC 라면 마우스 둘이 한 그릇, 휴대폰이 다른 그릇으로 보인다. 다만 일반 권한으로는 어느 WUDFHost 에 어느 장치가 올라왔는지까지는 확인하지 못했다. 레지스트리의 UMDF 드라이버 등록 목록(HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WUDF\Services)에는 이 둘을 포함해 22개가 있었지만, 실제로 장치가 연결되어 돌고 있는 것은 이것뿐이었다.
WUDFHost 하나가 CPU 를 계속 쓰거나 자꾸 다시 뜬다면 그 장치의 드라이버 문제일 가능성이 높다. 위 방법으로 장치를 찾고, 잠시 연결을 끊어 보거나 제조사 드라이버를 업데이트한다.
가짜 구별과 끄면 안 되는 이유
두 프로세스 모두 C:\Windows\System32 에 있고 Microsoft Windows 서명이어야 한다. fontdrvhost 의 부모는 wininit 이나 winlogon, WUDFHost 의 부모는 services.exe 다.
Get-AuthenticodeSignature C:\Windows\System32\fontdrvhost.exe, C:\Windows\System32\WUDFHost.exe |
Select-Object Path, Status
fontdrvhost 를 끝내면 그 세션에서 글자를 그리지 못하게 되어 화면이 망가지거나 로그아웃되는 것으로 알려져 있다. WUDFHost 를 끝내면 그 장치가 잠깐 끊긴다. 둘 다 메모리가 몇 MB 수준이라 끄는 것으로 얻을 것도 없다. 개수가 마음에 걸린다면 fontdrvhost 는 세션 수와, WUDFHost 는 UMDF 장치 수와 견줘 보면 된다. 이 PC 에서는 세션 둘에 fontdrvhost 둘, UMDF 장치 셋에 WUDFHost 둘이었다.
다음 편은 프린터가 없어도 늘 떠 있는 spoolsv.exe, 인쇄 스풀러다. 인쇄가 멈출 때 볼 곳과 보안 업데이트 이야기를 함께 정리한다.