3 điểm bởi GN⁺ 2023-09-25 | 3 bình luận | Chia sẻ qua WhatsApp
  • 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-sys cho các binding FFI trực tiếp tới WDK API, wdk cho các binding WDK API an toàn và đúng phong cách Rust, wdk-panic cho panic handler, wdk-alloc để hỗ trợ alloc, và wdk-macros là bộ macro giúp sử dụng các binding trực tiếp của wdk-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.io hiệ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 clone windows-drivers-rs rồi chỉnh cấu hình build.rs của wdk-sys
  • Quy trình sử dụng gồm tạo gói Cargo lib, thêm các dependency wdk-build, wdk, wdk-sys, wdk-alloc, wdk-panic, cấu hình cdylib, thiết lập metadata WDK, gọi wdk_build::configure_wdk_binary_build() trong build.rs, thêm DriverEntry, rồi chạy cargo 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 alloc của thư viện chuẩn Rust, cần cấu hình global allocator wdk_alloc::WdkAllocator
  • Yêu cầu build gồm libclang cho bindgen, cargo-make cho 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 make mặc định sẽ build và đóng gói driver; kết quả là gói driver đã được ký và tệp WDRLocalTestCert.cer được tạo trong target/<Cargo profile>/package hoặ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 .sys.cat được tạo bằng cách đặt WDK_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-make là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

 
GN⁺ 2023-09-25
Ý 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ỉ?

    • Có vẻ Apple cũng từng làm chuyện tương tự. Tài liệu nội bộ của Apple chẳng là gì so với sách của Jonathan Levin, nên nghe nói Apple thường mua các cuốn đó cho kỹ sư OS của họ.
      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
    • Nhắc đến ông ấy thì không thể bỏ qua Sysinternals. Tôi phụ thuộc vào bộ công cụ đó trong công việc hằng ngày.
      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ác công cụ Sysinternals nên được cài sẵn trong mọi bản cài Windows. Trong môi trường của tôi chúng là thiết yếu, và khi sửa hoặc debug máy tính của bạn bè mà không có chúng thì thật sự rất thiếu.
      Có lẽ đó cũng là lý do MSFT acquihire Mark Russinovich và đội ngũ của ông ấy.
    • Ông ấy là một lập trình viên giỏi, nhưng đọc sách của ông ấy thì tôi không nghĩ ông ấy sẽ là một CEO giỏi.
      Ấ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...

  • 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,
    }

    • Phần lớn những thứ đó rốt cuộc chỉ là kiểu số nguyên FFI. Vì API driver Windows được dùng như vậy.
      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ể.
    • Muốn loại bỏ cái đó thì có lẽ phải viết lại toàn bộ.
  • 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#.

    • Microsoft đang đẩy ngày càng nhiều mã sang user space. Một thay đổi gần đây là yêu cầu các hãng máy in dùng ứng dụng máy in UWP, thay vì driver, khi họ muốn thêm chức năng tùy chỉnh cho máy in. Những ứng dụng như vậy thường được viết bằng các ngôn ngữ 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.
    • Tôi không biết liệu nó có thật sự tốt hơn không. Tôi không có kinh nghiệm phát triển driver, nhưng device driver là thành phần lõi cấp thấp của một hệ điều hành đang chạy, nên có vẻ không hợp với cách garbage collection ngắt việc thực thi theo lịch của riêng nó.
    • Tôi không muốn con trỏ chuột bị giật vì driver dừng lại để chạy garbage collector.
    • Microsoft đã từng thử rồi nhưng thất bại thảm hại. Tôi không nghĩ họ từng nói rõ lý do, nhưng với phần cứng đầu những năm 2000 thì có lẽ garbage collection gây ra quá nhiều lần khựng.
    • Ngay cả với C++, viết device driver mà vẫn giữ được khả năng tạo driver kernel có thể phân trang cũng rất khó.
      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.
 
bungker 2023-11-30

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.

 
botplaysdice 2023-12-01

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.