3 pontos por GN⁺ 2023-09-25 | 3 comentários | Compartilhar no WhatsApp
  • Conjunto de crates Rust que permite desenvolver Windows Drivers em Rust, com foco em dar suporte aos modelos de desenvolvimento de drivers WDM e WDF
  • Os principais componentes são wdk-build, para configuração de build do WDK; wdk-sys, com bindings FFI diretos para a API do WDK; wdk, com bindings seguros e idiomáticos para a API do WDK; wdk-panic, para panic handler; wdk-alloc, para suporte a alloc; e wdk-macros, um conjunto de macros que ajuda no uso direto dos bindings de wdk-sys
  • Foi criado tendo em mente suporte a drivers WDM, KMDF, UMDF e serviços Win32, incluindo suporte a todas as versões de WDF incluídas no WDK 22H2 ou superior
  • Os crates publicados no crates.io atualmente suportam apenas KMDF v1.33; bindings para outras configurações podem ser gerados clonando windows-drivers-rs e depois modificando a configuração de build.rs em wdk-sys
  • O fluxo de uso consiste em criar um pacote Cargo lib, adicionar as dependências wdk-build, wdk, wdk-sys, wdk-alloc e wdk-panic, configurar cdylib, definir os metadados do WDK, chamar wdk_build::configure_wdk_binary_build() em build.rs, adicionar DriverEntry e executar cargo make
    • Crates de Kernel Mode como drivers KMDF e WDM exigem estratégia de panic abort, #![no_std] e configuração de panic handler
    • Para usar o módulo alloc da biblioteca padrão do Rust, é necessário configurar o allocator global wdk_alloc::WdkAllocator
  • Os requisitos de build incluem libclang para bindgen, cargo-make para tarefas pós-build e um ambiente WDK válido; a forma recomendada é entrar no prompt de desenvolvedor do eWDK
  • Por padrão, cargo make faz o build e empacota o driver, gerando como resultado um pacote de driver assinado e o arquivo WDRLocalTestCert.cer em target/<Cargo profile>/package ou sob o caminho da arquitetura alvo
  • Há suporte para passar argumentos como cargo make default --target <TARGET TRIPLE>, --release, --features <FEATURES> e +<TOOLCHAIN>; também é possível ativar a verificação de assinatura dos arquivos .sys e .cat gerados com WDK_BUILD_ENABLE_SIGNTOOL_VERIFY=true
  • A nova extensão do Cargo cargo-wdk está em desenvolvimento, em estado Preview, para substituir o cargo-make como ferramenta recomendada para build de drivers Rust
  • Exemplos mínimos de WDM, KMDF e UMDF estão no diretório examples, e exemplos de criação de drivers podem ser vistos em Windows-rust-driver-samples
  • Ainda está em estágio inicial de desenvolvimento e não é recomendado para uso em produção

3 comentários

 
GN⁺ 2023-09-25
Opiniões do Hacker News
  • Para quem não se lembra, Mark Russinovich, antes de suceder seu chefe e passar a ser citado como candidato a próximo CEO da MSFT, comandava uma empresa de ferramentas de software e consultoria em kernel NT à qual os engenheiros de Redmond recorriam para aprender desenvolvimento do kernel NT.
    Ele também descobriu recursos de proteção de arquivos como o rootkit de DRM da Sony e o rootkit da Symantec, e ainda pegou a Best Buy pirateando o ERD Commander.
    Hoje me arrependo um pouco de ter apagado o LinkedIn em 2014. Era uma conta em que todo o Valley e o Mark eram conexões de primeiro grau, mas o relativo anonimato também traz liberdade e agilidade. Qual era mesmo aquela música de reggae do Desmond Dekker sobre ser inútil ficar falando do quanto você fez, ganhou e quem conhece?

    • Acho que a Apple também fez algo parecido. Dizem que a documentação interna da Apple não era grande coisa perto dos livros de Jonathan Levin, então a Apple comprava esses livros com frequência para seus engenheiros de OS.
      É bem interessante que empresas desse porte, mesmo tendo uma posição muito mais vantajosa, com acesso ao código-fonte real e aos engenheiros, não consigam fazer bem esse tipo de coisa por conta própria. Esses terceiros — pelo menos Levin — tiveram de depender em boa parte de engenharia reversa.
      https://newosxbook.com
    • Não dá para falar dele sem mencionar a Sysinternals. Dependo desse conjunto de ferramentas no trabalho todos os dias.
      Considerando que praticamente toda empresa no mundo que usa Windows utiliza pelo menos uma ferramenta da Sysinternals, talvez a influência da Sysinternals tenha sido maior até do que a do próprio Azure.
    • As ferramentas da Sysinternals deveriam vir incluídas por padrão em toda instalação do Windows. No meu ambiente elas são indispensáveis, e fazem muita falta quando vou consertar ou depurar o computador de um amigo.
      Provavelmente foi por isso que a MSFT fez o acquihire de Mark Russinovich e sua equipe.
    • Ele é um bom programador, mas, lendo os livros dele, não parece que seria um bom CEO.
      A impressão que tive do primeiro livro foi a de alguém que vê o mundo de forma extremamente preto no branco.
  • Tweet original: https://twitter.com/markrussinovich/status/17057307039574058...

  • Legal /s, mas isso não parece Rust idiomático:
    pub struct QueueContext {
    buffer: PVOID,
    length: usize,
    timer: wdf::Timer,
    current_request: WDFREQUEST,
    current_status: NTSTATUS,
    spin_lock: wdf::SpinLock,
    }

    • A maioria dessas coisas acaba apontando para tipos inteiros de FFI. É assim que a API de drivers do Windows é usada.
      Ao escrever drivers Rust no kernel Linux há um problema parecido, e o mesmo vale para outros projetos que interoperam com C.
      Tipos como NTSTATUS têm bastante documentação associada. Diferentemente de C ou C++, em Rust não dá para simplesmente atribuir um valor inteiro a um valor de enum. Você poderia criar uma classe wrapper para obrigar casts toda vez, mas aí metade do código viraria .into() e isso provavelmente também adicionaria overhead ao driver.
      Pelo que parece, exceto talvez pelo void* do buffer, esses valores de enum não estão sendo definidos nem alterados, apenas lidos. Para NTSTATUS, um bloco match {} parece suficiente. WDFREQUEST é um handle, então não há muito que se possa fazer além de trocá-lo por outro handle do mesmo tipo.
      Timer e SpinLock foram transformados em objetos mais idiomáticos em Rust, que encapsulam internamente chamadas de biblioteca unsafe. Fora isso, não vejo bem como tornar esse código mais idiomático em Rust sem impor um custo de desempenho considerável.
    • Para se livrar disso, acho que seria preciso reescrever tudo.
  • Sabe o que seria melhor? Escrever drivers de dispositivo em uma linguagem com memória gerenciada, como C#.

    • A Microsoft está empurrando cada vez mais código para o espaço de usuário. Uma mudança recente é exigir que fabricantes de impressoras usem apps de impressora UWP, e não drivers, para adicionar funções customizadas às impressoras. Esses apps geralmente são escritos em linguagens como C#.
      Concordo com a avaliação da Microsoft de que, em vez de tornar o kernel mais acessível, o melhor é executar menos código de fabricantes dentro do kernel. C# não é adequado para situações como “quero acessar um certo buffer, mas ele ainda não foi paginado para a memória, e estou dentro de um tratador de interrupção”, então parece quase impossível rodar um coletor de lixo no kernel sem bugs.
    • Não sei se isso seria realmente melhor. Não tenho experiência em desenvolvimento de drivers, mas drivers de dispositivo são componentes centrais de baixo nível de um sistema operacional em funcionamento, então não parecem combinar bem com coleta de lixo interrompendo a execução conforme sua própria agenda.
    • Não quero que o mouse dê engasgadas porque o driver parou para rodar o coletor de lixo.
    • A Microsoft já tentou isso e fracassou miseravelmente. Acho que nunca explicaram o motivo, mas em hardware do início dos anos 2000 imagino que haveria pausas demais por causa da coleta de lixo.
    • Mesmo em C++, é muito difícil escrever drivers de dispositivo mantendo a capacidade de criar drivers de kernel pagináveis.
      Drivers podem acessar memória em momentos em que uma falta de página é impossível, por exemplo durante um tratador de interrupção, então é preciso controlar a disponibilidade de memória de forma muito rígida. A linguagem e o runtime de C# teriam, no mínimo, de adicionar recursos para lidar explicitamente com isso.
 
bungker 2023-11-30

Acho que isso está sendo um pouco subestimado, então vou acrescentar algo. Russinovich é alguém que criou inúmeros materiais e ferramentas relacionados ao kernel do Windows. Entre os desenvolvedores ligados ao kernel do Windows (incluindo os que criaram rootkits), provavelmente não há ninguém que não tenha estudado vendo os materiais ou a documentação do Russinovich.

 
botplaysdice 2023-12-01

Ouvi dizer que estão reescrevendo o kernel do Windows em Rust e, finalmente, o SDK para drivers está saindo. Pelo visto, em breve deve aparecer um aviso dizendo para criar drivers em Rust a partir de 20XX.