3 ポイント 投稿者 GN⁺ 2023-09-25 | 3件のコメント | WhatsAppで共有
  • Windows DriversをRustで開発できるようにするRust crate群で、WDMおよびWDFドライバー開発モデルのサポートを目標としている
  • 主な構成は、WDKビルド設定用のwdk-build、WDK APIの直接FFIバインディングであるwdk-sys、安全で慣用的なWDK APIバインディングのwdk、panic handler用のwdk-panicallocサポート用のwdk-allocwdk-sysの直接バインディング利用を支援するマクロ群wdk-macrosで構成される
  • WDM、KMDF、UMDFドライバーとWin32 Servicesのサポートを念頭に作られており、WDK 22H2以降に含まれるすべてのWDFバージョンのサポートを含む
  • crates.ioで公開されているcrateは現在KMDF v1.33のみをサポートしており、ほかの構成のバインディングはwindows-drivers-rsをcloneした後、wdk-sysbuild.rs設定を修正して生成できる
  • 利用の流れは、Cargo libパッケージの作成、wdk-buildwdkwdk-syswdk-allocwdk-panic依存関係の追加、cdylib設定、WDK metadata設定、build.rswdk_build::configure_wdk_binary_build()を呼び出し、DriverEntryを追加し、cargo makeを実行するという構成
    • Kernel Mode crateであるKMDFおよびWDMドライバーでは、panic戦略abort#![no_std]、panic handlerの設定が必要
    • Rust標準ライブラリのallocモジュールを使うには、wdk_alloc::WdkAllocatorのグローバルallocator設定が必要
  • ビルド要件は、bindgen用のlibclang、post-build作業用のcargo-make、有効なWDK環境であり、推奨される方法はeWDK developer promptに入ること
  • cargo makeはデフォルト動作でドライバーのビルドとパッケージングを行い、結果として署名済みドライバーパッケージとWDRLocalTestCert.cerファイルがtarget/<Cargo profile>/packageまたはtarget architectureパス配下に生成される
  • cargo make default --target <TARGET TRIPLE>--release--features <FEATURES>+<TOOLCHAIN>のような引数の受け渡しをサポートし、WDK_BUILD_ENABLE_SIGNTOOL_VERIFY=true設定で生成された.sysおよび.catファイルの署名検証処理を有効化できる
  • 新しいCargo拡張cargo-wdkは、Rustドライバービルドの推奨ツールとしてcargo-makeを置き換えるために開発中のPreview段階にある
  • WDM、KMDF、UMDFの最小サンプルはexamples directoryにあり、ドライバー作成の例はWindows-rust-driver-samplesで確認できる
  • まだ開発初期段階であり、production useにはまだ推奨されない

3件のコメント

 
GN⁺ 2023-09-25
Hacker News のコメント
  • 覚えていない人のために言うと、Mark Russinovichは上司の後任となり、次期 MSFT CEO 候補として名前が挙がる前、Redmond のエンジニアたちが NT カーネル開発を学びに行くようなソフトウェアツールおよび NT カーネルのコンサルティング会社を運営していた。
    また、Sony の DRM ルートキットや Symantec のルートキットのようなファイル保護機能を発見し、Best Buy が ERD Commander を違法コピーしていたことも突き止めた。
    2014年に LinkedIn を消してしまったのは、今となっては少し惜しい。Valley 全体と Mark が 1次つながりだったアカウントだったのだが、それでも相対的な無名さには自由と機敏さがある。自分がどれだけやったか、稼いだか、誰を知っているかを語るのは無意味だ、という Desmond Dekker のレゲエ曲は何だったかな。

    • Apple も似たようなことをしていたように思う。社内の Apple 文書は Jonathan Levin の本に比べれば大したものではなく、Apple は OS エンジニア向けにそれらの本をよく購入していたという。
      あの規模の企業が、実際のソースコードとエンジニアへのアクセスというはるかに有利な立場にありながら、こうしたことを自力でうまくできないというのはかなり興味深い。こうした第三者、少なくとも Levin はかなりの部分をリバースエンジニアリングに頼らざるを得なかった。
      https://newosxbook.com
    • 彼の話をするなら Sysinternalsを外すわけにはいかない。毎日の業務であのツール群に頼っている。
      世界中の Windows を使うほぼすべての会社が、少なくとも1つは Sysinternals のツールを使っていることを考えると、Sysinternals の影響力はもしかすると Azure そのものよりも大きかったかもしれない。
    • Sysinternals ツールは、すべての Windows インストールに標準で含まれているべきだ。自分の環境では必須だし、友人の PC を直したりデバッグしたりするときにないと本当に困る。
      MSFT が Mark Russinovich とそのチームを acquihire した理由も、そこにあるのではないか。
    • 彼は優れたプログラマーだが、彼の本を読む限り、優れた CEO になるとは思えない。
      最初の本から受けた印象は、世界を極端に白黒で見ているというものだった。
  • 元のツイート: https://twitter.com/markrussinovich/status/17057307039574058...

  • すばらしい /s だが、これは Rust らしくない:
    pub struct QueueContext {
    buffer: PVOID,
    length: usize,
    timer: wdf::Timer,
    current_request: WDFREQUEST,
    current_status: NTSTATUS,
    spin_lock: wdf::SpinLock,
    }

    • それらの大半は結局 FFI の整数型を指している。Windows ドライバー API がそういう使い方だからだ。
      Linux カーネルで Rust ドライバーを書く場合にも似た問題があり、C と相互運用する他のプロジェクトでも同じだ。
      NTSTATUS のような型には、かなり多くのドキュメントが付いている。C や C++ と違い、Rust では整数値を enum 値にそのまま代入することはできない。ラッパークラスを作って毎回キャストさせることもできるが、そうするとコードの半分が .into() になり、ドライバーにオーバーヘッドも生じる可能性が高い。
      見たところ、buffer 用の void* 程度を除けば、こうした enum 値を設定したり変更したりしているのではなく、読むだけだ。NTSTATUS には match {} ブロックで十分そうだ。WDFREQUEST はハンドルなので、同じ型の別のハンドルに差し替える以外にできることもあまりない。
      Timer と SpinLock は、unsafe なライブラリ呼び出しを内部に包んだRust らしいオブジェクトになっている。それ以外については、かなりの性能負担なしにこのコードをもっと Rust らしくする方法はあまり見当たらない。
    • あれをなくすには、全部書き直す必要がありそうだ。
  • 何がもっと良いか分かるか? C# のようなメモリ管理言語でデバイスドライバーを書くことだ。

    • Microsoft は、ますます多くのコードをユーザー空間へ押し出している。最近の変更としては、プリンターメーカーがプリンターにカスタム機能を追加する際、ドライバーではなく UWP プリンターアプリを使うよう求めている。こうしたアプリは通常 C# などの言語で書かれる。
      カーネルをより簡単に扱えるようにするより、カーネル内でメーカーのコードを実行する量を減らす方が最善だという Microsoft の判断には同意する。C# は「あるバッファにアクセスしたいが、まだページインされておらず、自分は割り込みハンドラーの中にいる」といった状況には向いていないので、カーネルでガベージコレクターをバグなく動かすのはほぼ不可能に見える。
    • 本当により良いかは分からない。ドライバー開発の経験はないが、デバイスドライバーは動作中の OS の低レベルな中核構成要素なので、ガベージコレクションが自分の都合で実行を中断する方式とは相性が悪そうに思える。
    • ドライバーがガベージコレクターを動かすために止まって、マウスがカクつくのは望まない。
    • Microsoft はすでに試したが、悲惨に失敗した。理由は明らかにしていなかったと思うが、2000年代初頭のハードウェアではガベージコレクションによる停止が多すぎたのだろうと思う。
    • C++ でも、ページ可能なカーネルドライバーを書ける状態を保ちながらデバイスドライバーを書くのは非常に難しい。
      ドライバーはページフォールトが許されないタイミング、たとえば割り込みハンドラー中にもメモリへアクセスする可能性があるため、メモリの可用性を非常に厳密に制御しなければならない。C# 言語とランタイムは、少なくともそれを明示的に扱う機能を追加する必要がある。
 
bungker 2023-11-30

少し過小評価されているように思うので補足します。Russinovich は Windows カーネルに関して数多くの資料やツールを作ってきた人物です。Windows カーネル関連の開発者の中で(ルートキットを作った開発者たちを含めて)、Russinovich の資料や文書を見て学ばなかった人はいないのではないかと思います。

 
botplaysdice 2023-12-01

WindowsカーネルをRustで書き直しているという話は聞いていましたが、ついにドライバーSDKが出てきたのですね。近いうちに20XX年からはRustでドライバーを作れという告知が出そうです。