Rust로 간단한 드라이버 작성하기
- Rust 언어 생태계는 매일 성장하고 있으며, 메모리와 동시성 안전성을 컴파일 시점에 제공하는 유일한 주류 언어임. 강력하고 풍부한 빌드 시스템(cargo)과 증가하는 패키지 수(crates)도 장점임.
- Rust는 시스템 프로그래밍 언어로서 C/C++와 같은 영역에서 사용 가능함. C 타입을 Rust로 변환할 때의 장황함은 적절한 래퍼와 매크로로 완화 가능함.
- 이 글에서는 Windows Kernel Programming 책에서 소개한 "Booster" 드라이버의 Rust 버전을 작성하여 스레드 우선순위를 변경하는 방법을 설명함.
시작하기
- 드라이버 빌드를 준비하려면 Windows Drivers-rs를 참고하고, WDK 설치 및 LLVM 설치가 필요함.
- 새로운 Rust 라이브러리 프로젝트를 생성하여 드라이버를 작성할 수 있음:
cargo new --lib booster
-
build.rs
파일을 추가하여 CRT를 정적으로 링크하도록 설정해야 함.
코드 작성
- 커널에서는 표준 라이브러리가 없으므로
#![no_std]
를 사용하여 시작함.
-
wdk_sys
크레이트는 저수준 커널 함수와 상호 운용성을 제공하며, wdk
크레이트는 고수준 래퍼를 제공함.
-
Vec
와 String
은 alloc
모듈에서 정의되어 있으며, 글로벌 할당자를 제공하여 사용할 수 있음.
-
DriverEntry
는 모든 Windows 커널 드라이버의 진입점이며, Rust의 println!
매크로를 사용하여 디버그 출력 가능함.
요청 처리
-
IRP_MJ_CREATE
, IRP_MJ_CLOSE
, IRP_MJ_WRITE
요청을 처리해야 함.
-
boost_write
함수는 스레드 우선순위를 실제로 변경하는 부분임.
-
ThreadData
구조체를 사용하여 드라이버에 요청을 전달함.
드라이버 설치 및 테스트
- 드라이버 파일은
sc.exe
도구를 사용하여 설치 가능하며, sc start
로 시스템에 로드할 수 있음.
- C++ 애플리케이션을 사용하여 드라이버와 통신하고 올바른 구조체를 전달하여 테스트 가능함.
결론
- Rust로 커널 드라이버를 작성하는 것이 가능하며, 지원이 빠르게 개선될 것으로 기대됨.
- Rust의 장점을 최대한 활용하기 위해 안전한 래퍼를 만들어 코드의 장황함을 줄이고
unsafe
블록을 피하는 것이 중요함.
- 이 글의 코드는 GitHub에서 확인 가능함: https://github.com/zodiacon/Booster