sh711 님의 블로그

Windows Kernel Driver Load 본문

Study/Windows

Windows Kernel Driver Load

sh711 2025. 3. 14. 01:56

윈도우 부팅 과정

 

드라이버 로드 과정 확인을 위해 nt!IopInitializeBootDrivers 함수에 bp를 설정했다

 

이어서, nt!IopLoadDriver 함수에 브레이크 설정 후 Go 하면 브레이크가 잡힌다

 

IopLoadDriver 함수는 로드할 드라이버의 경로, 각 드라이버에 존재하는 DRIVER_OBJECT를 인자로 받는다

// IopLoadDriver 함수 원형
NTSTATUS IopLoadDriver(
    IN PUNICODE_STRING DriverName,
    IN PDRIVER_OBJECT *DriverObject
);

 

인자인 rcx, rdx 의 값 확인 시 현재 확인이 불가하다

 

이어서, nt!MmLoadSystemImageEx 함수에 브레이크를 걸고 진행시킨다

 

이제 드라이버 내 DriverEntry로 점프하는 곳을 찾아가보자

nt!MiDriverLoadSucceeded 함수에 브레이크 후 진입한다

 

해당 함수 MiCacheImageSymbols는 rcx 인자로 로드할 드라이버의 베이스 주소를 입력 받는다

0xfffff80179400000

rcx 값 확인시 PE 파일(커널드라이버) 식별

이어서 _wcsnicmp 함수를 호출한다

_wcsnicmp 함수는 문자열을 대소문자 구분없이 비교하는 함수이고 원형은 다음과 같다.

int _wcsnicmp(
  const wchar_t *str1,
  const wchar_t *str2,
  size_t count
);

 

rcx 값

현재 로드할 드라이버 경로 ==> \SystemRoot\System32\drivers\pacer.sys

따라서 아직 모듈이 로드되지 않아 심볼을 확인할 수 없다

rdx 값

cc 값은 값 경계를 위한 더미코드

r8 값 (size)

 

결과적으로 일치하므로 반환값은 0이 나왔다

결과 검증

 

이후, DbgLoadImageSymbolsUnicode 함수 호출 후 모듈이 등록되는 것을 확인할 수 있다

 

DbgLoadImageSymbolsUnicode 내부 진입 시 ntkrnlmp!RtlImageNtHeaderEx 함수를 호출한다

해당 함수는 PE파일(로드할 커널드라이브)의 헤더를 찾는 함수이고 커널 내에서 PE구조를 파싱할 때 사용된

// 함수 원형
NTSYSAPI PIMAGE_NT_HEADERS NTAPI RtlImageNtHeaderEx(
    ULONG Flags,
    PVOID Base,
    ULONG64 Size,
    PIMAGE_NT_HEADERS *OutHeaders
);

return : PIMAGE_NT_HEADERS (NT 헤더 구조체의 주소)

각각의 값 확인이 가능하다

해당 함수 내에서 파일에서 추출한 "PE" 파일 문자열과 0x4550("PE")를 비교하여 같지 않을 경우 rax에 0xc000007b 값을 넣고 ret를 한다.

지금은 올바르게 되어서 rax 값을 r9 값 주소에 넣은 후 r10(0) 반환값 설정 후 ret 한다

 

이후 DebugService2 함수가 호출되는데 아마 지금 디버깅 중이어서 호출되는것 같다

내부 명령은 0x2D 시그널 인터럽트를 발생시킨다

x86 및 x86-64 아키텍처에서는 4개의 권한 레벨(Ring)이 존재한다

Ring 0 (CPL = 0): 커널 모드 (Kernel Mode)
Ring 3 (CPL = 3): 유저 모드 (User Mode)

유저 모드(Ring 3)에서 syscall 또는 int 명령을 사용하면 커널 모드(Ring 0)로 전환됨
커널 모드에서 실행 중이라면 그대로 Ring 0을 유지함

인터럽트 신호 값은 IDT(Interrupt Descriptor Table) 테이블을 참조하여 인터럽트 핸들러가 실행됨

 

r 명령을 통한 cs(code segment) 값 확인
cs = 0033일땐 유저 모드
cs = 0010일땐 커널 모드

 

 

이어서 확인 시 KiDebugServiceTrap 함수를 호출하였다

현재 디버깅 여부를 알 수 있다.

KdDebuggerEnabled L1 = 1 // 디버거 활성화
KdDebuggerNotPresent L1 = 1 // 디버거 존재하지 않음

인터럽트 이후 모듈이 로드되었다 (pacer.sys 이후라 netbios 모듈 로드)

'Study > Windows' 카테고리의 다른 글

windows API 프로그래밍  (0) 2025.03.13
Windbg 윈도우 커널 분석 - 1  (0) 2025.03.10
Windbg 프로그램 분석  (0) 2025.03.08