windows-drivers-rs - Nền tảng cho phép phát triển driver Windows bằng Rust
(github.com/microsoft)- Bộ crate Rust cho phép phát triển Windows Drivers bằng Rust, với mục tiêu hỗ trợ các mô hình phát triển driver WDM và WDF
- Các thành phần chính gồm
wdk-buildđể cấu hình build WDK,wdk-syscho các binding FFI trực tiếp tới WDK API,wdkcho các binding WDK API an toàn và đúng phong cách Rust,wdk-paniccho panic handler,wdk-allocđể hỗ trợalloc, vàwdk-macroslà bộ macro giúp sử dụng các binding trực tiếp củawdk-sys - Được xây dựng với định hướng hỗ trợ driver WDM, KMDF, UMDF và Win32 Services, đồng thời bao gồm hỗ trợ mọi phiên bản WDF có trong WDK 22H2 trở lên
- Các crate được công bố trên
crates.iohiện chỉ hỗ trợ KMDF v1.33; các binding cho cấu hình khác có thể được tạo bằng cách clonewindows-drivers-rsrồi chỉnh cấu hìnhbuild.rscủawdk-sys - Quy trình sử dụng gồm tạo gói Cargo
lib, thêm các dependencywdk-build,wdk,wdk-sys,wdk-alloc,wdk-panic, cấu hìnhcdylib, thiết lập metadata WDK, gọiwdk_build::configure_wdk_binary_build()trongbuild.rs, thêmDriverEntry, rồi chạycargo make- Với các crate Kernel Mode như driver KMDF và WDM, cần dùng chiến lược panic
abort,#![no_std], và cấu hình panic handler - Để dùng mô-đun
alloccủa thư viện chuẩn Rust, cần cấu hình global allocatorwdk_alloc::WdkAllocator
- Với các crate Kernel Mode như driver KMDF và WDM, cần dùng chiến lược panic
- Yêu cầu build gồm
libclangchobindgen,cargo-makecho các tác vụ hậu build, và môi trường WDK hợp lệ; cách được khuyến nghị là vào eWDK developer prompt cargo makemặc định sẽ build và đóng gói driver; kết quả là gói driver đã được ký và tệpWDRLocalTestCert.cerđược tạo trongtarget/<Cargo profile>/packagehoặc dưới đường dẫn kiến trúc đích- Hỗ trợ truyền các tham số như
cargo make default --target <TARGET TRIPLE>,--release,--features <FEATURES>,+<TOOLCHAIN>; cũng có thể bật bước xác minh chữ ký cho các tệp.sysvà.catđược tạo bằng cách đặtWDK_BUILD_ENABLE_SIGNTOOL_VERIFY=true - Extension Cargo mới
cargo-wdkđang ở trạng thái Preview và được phát triển để thay thếcargo-makelàm công cụ được khuyến nghị cho việc build driver Rust - Có các ví dụ tối thiểu cho WDM, KMDF, UMDF trong thư mục examples, và có thể xem các ví dụ tạo driver tại Windows-rust-driver-samples
- Dự án vẫn đang ở giai đoạn phát triển ban đầu và chưa được khuyến nghị cho production use
3 bình luận
Ý kiến trên Hacker News
Dành cho những ai không nhớ: trước khi Mark Russinovich kế nhiệm vị trí của sếp mình và được nhắc đến như một ứng viên CEO tiếp theo của MSFT, ông từng điều hành một công ty công cụ phần mềm và tư vấn về nhân NT, nơi các kỹ sư Redmond đến học phát triển nhân NT.
Ông cũng đã phát hiện các cơ chế bảo vệ tệp kiểu rootkit như rootkit DRM của Sony, rootkit của Symantec, và còn bắt được Best Buy sao chép lậu ERD Commander.
Giờ nghĩ lại thì hơi tiếc vì tôi đã xóa LinkedIn vào năm 2014. Đó là tài khoản mà cả Thung lũng và Mark đều là kết nối bậc 1, nhưng dù sao thì sự tương đối vô danh cũng có tự do và sự lanh lợi của nó. Bài reggae nào của Desmond Dekker nói rằng khoe khoang mình đã làm được bao nhiêu, kiếm được bao nhiêu và quen biết ai là vô nghĩa ấy nhỉ?
Khá thú vị là các công ty ở quy mô đó, dù có lợi thế lớn hơn nhiều nhờ mã nguồn thật và quyền tiếp cận kỹ sư, lại không tự làm tốt được những việc như vậy. Những bên thứ ba này, ít nhất là Levin, đã phải dựa khá nhiều vào dịch ngược.
https://newosxbook.com
Khi nghĩ rằng gần như mọi công ty trên thế giới dùng Windows đều sử dụng ít nhất một công cụ Sysinternals, ảnh hưởng của Sysinternals có lẽ còn lớn hơn cả bản thân Azure.
Có lẽ đó cũng là lý do MSFT acquihire Mark Russinovich và đội ngũ của ông ấy.
Ấn tượng tôi nhận được từ cuốn đầu tiên là ông nhìn thế giới theo kiểu cực kỳ đen-trắng.
Tweet gốc: https://twitter.com/markrussinovich/status/17057307039574058...
http://farside.link/twitter.com/markrussinovich/status/17057...
Hay đấy /s, nhưng cái này không giống Rust:
pub struct QueueContext {
buffer: PVOID,
length: usize,
timer: wdf::Timer,
current_request: WDFREQUEST,
current_status: NTSTATUS,
spin_lock: wdf::SpinLock,
}
Khi viết driver Rust cho nhân Linux cũng có vấn đề tương tự, và các dự án khác tương tác với C cũng vậy.
Những kiểu như NTSTATUS có khá nhiều tài liệu đi kèm. Khác với C hay C++, trong Rust bạn không thể cứ gán một giá trị số nguyên vào một giá trị enum. Có thể tạo các lớp wrapper để lần nào cũng phải ép kiểu, nhưng khi đó một nửa mã sẽ thành .into(), và còn có khả năng tạo thêm overhead cho driver.
Nhìn thì, ngoài void* cho buffer, các giá trị enum này hầu như chỉ được đọc chứ không phải được thiết lập hay thay đổi. Với NTSTATUS, một khối match {} có vẻ là đủ. WDFREQUEST là handle nên ngoài việc đổi sang một handle khác cùng kiểu thì cũng không có nhiều thứ có thể làm.
Timer và SpinLock đã được chuyển thành đối tượng theo phong cách Rust bọc các lời gọi thư viện unsafe bên trong. Ngoài ra tôi không thấy có cách nào rõ ràng để làm đoạn mã này “Rust” hơn mà không chịu chi phí hiệu năng đáng kể.
Biết cái gì tốt hơn không? Viết device driver bằng một ngôn ngữ quản lý bộ nhớ như C#.
Tôi đồng ý với nhận định của Microsoft rằng cách tốt nhất là chạy ít mã của nhà sản xuất hơn trong kernel, thay vì làm cho kernel dễ tiếp cận hơn. C# không phù hợp với các tình huống như “tôi muốn truy cập một buffer nào đó nhưng nó chưa được page in, và tôi đang ở trong interrupt handler”, nên việc chạy garbage collector trong kernel mà không có bug có vẻ gần như bất khả thi.
Driver phải kiểm soát tính sẵn có của bộ nhớ cực kỳ chặt chẽ, vì nó có thể truy cập bộ nhớ vào những thời điểm không thể xảy ra page fault, chẳng hạn trong interrupt handler. Ngôn ngữ và runtime C# tối thiểu sẽ phải bổ sung khả năng xử lý điều này một cách tường minh.
Có vẻ như điều này đang bị đánh giá hơi thấp nên tôi xin bổ sung. Russinovich là người đã tạo ra vô số tài liệu và công cụ liên quan đến nhân Windows. Trong số các nhà phát triển liên quan đến nhân Windows (bao gồm cả những người tạo ra rootkit), có lẽ không ai là chưa từng học qua bằng cách xem các tài liệu hay văn bản của Russinovich.
Nghe nói họ đang viết lại kernel Windows bằng Rust, giờ cuối cùng SDK cho driver cũng bắt đầu xuất hiện rồi nhỉ. Có lẽ chẳng bao lâu nữa sẽ có thông báo từ năm 20XX trở đi hãy làm driver bằng Rust.