
Um DTrace Reimplementado no Windows
O rastreador do Steve. Uma reimplementação do hook de syscall do DTrace no Windows. Pense nisto como um hook SSDT compatível com PatchGuard, mas sem truques. Isto não suporta SSSDT (APIs win32k), pois as próprias APIs de chamada de sistema do DTrace não suportam esta tabela adicional. As APIs de kernel Zw* podem ser rastreadas além de todas as syscalls SSDT do modo usuário.
Leia até o final deste readme se você estiver desenvolvendo novos plugins para o STrace!
O DTrace no Windows suporta vários tipos de sonda. Estes incluem syscall, fbt, etw, profile, e talvez mais. Esta reimplementação apenas reimplementa os tipos de sonda syscall e etw. Todos os outros tipos de sonda são considerados totalmente fora do escopo deste projeto e nunca serão suportados. Sinta-se à vontade para fazer um fork do projeto se quiser adicionar tipos de sonda adicionais. O escopo foi limitado apenas às sondas syscall e etw devido à complexidade dos outros tipos de sonda e dos sistemas que eles tocam.
Esta reimplementação descarta completamente a linguagem de script D (nota: NÃO é DLang, a linguagem moderna mais popular). A complexidade de uma VM no kernel, como na implementação original do DTrace, é inadequada para este projeto. Em vez disso, esta implementação expõe diretamente os callbacks C relevantes necessários para se conectar às interfaces do kernel do DTrace no Windows. Para permitir o 'hot-loading' de scripts, um sistema de plugins baseado em DLL foi usado como substituto para o ambiente de VM + script do dtrace original. Este sistema de plugins aceita uma DLL 'normal' de modo usuário, sem verificações de segurança habilitadas, ou dependências externas, e a mapeia manualmente no espaço de endereço do kernel. A plugin dll tem exports que são invocados quando callbacks de syscall do kernel ocorrem. As APIs do kernel são resolvidas através da tabela de importação normal (IAT) da DLL; as DLLs de plugin são vinculadas a ntoskrnl.lib e então o driver resolve essas APIs no momento do carregamento, permitindo que quaisquer APIs do sistema sejam chamadas dentro das DLLs de plugin normalmente. O desempenho deste sistema de plugins é excelente, pois código nativo, em vez de um interpretador de scripts ou um JIT, executa diretamente entre ENTRY e RETURN da syscall. Este design melhora o desempenho em comparação com a implementação do dtrace fornecida pela Microsoft.
Configurar hooks é muito simples: você obtém uma rotina para registrar/desregistrar um hook pelo nome da API, com um callback pré e pós syscall. Os callbacks têm argumentos e valores de retorno acessíveis somente como leitura. Os valores de retorno podem ser falsificados em sondas de retorno e os argumentos podem ser modificados nas sondas de entrada, mas a syscall original não pode normalmente substituir ou 'cancelar' uma syscall - esta API atua como um observador. No entanto, existe uma brecha semelhante à documentada em (https://github.com/everdox/InfinityHook e https://github.com/everdox/InfinityHook/raw/master/resources/perf.png) que permite que o ponteiro da syscall seja substituído na pilha. Com essa brecha, é possível substituir completamente uma syscall por um ponteiro para uma rotina que você controla. Quando eventos ocorrem e seu callback de hook dispara, você pode fazer o que quiser. Os callbacks são síncronos, ou seja, se você atrasar a execução no callback de entrada, por exemplo, ficando em um loop while, a chamada de syscall será atrasada por esse período. A execução da chamada de sistema ocorre logo após o retorno do callback de entrada e imediatamente antes da entrada do callback de retorno. Este sistema é totalmente compatível com PatchGuard, no entanto o DSE deve estar desabilitado, pois a Microsoft infelizmente considera esse tipo de extensão de kernel parte do kernel NT e, portanto, valida que o signatário raiz seja o Windows. Isso não funciona com truques como habilitar signatários de kernel personalizados; o DSE realmente precisa estar desabilitado durante a inicialização do kernel.
ValidationFlags=IMGP_LATEST_MS_ROOT_REQUIRED | IMGP_WINDOWS_ROOT_REQUIRED | IMGP_MS_SIGNATURE_REQUIRED
Scenario=ImgSigningScenarioWindows
O driver Rust descarta o sistema de plugins baseado em DLL usado pelo driver C++ e tenta usar um interpretador de web assembly para hospedar scripts wasm no kernel do Windows. Isso é para ser mais semelhante à implementação original do dtrace, que usa uma VM, mas com uma linguagem melhor que DLang. Isso fornece sandboxing e outros benefícios interessantes. O POC está completo e funciona, mas infelizmente não é utilizável devido a problemas de desempenho com a interpretação de WASM com WASMI. Um mecanismo wasm baseado em JIT compatível com o kernel NT seria necessário para que esse design alternativo funcionasse. Está incluído como uma novidade divertida e pode ser utilizável para outra coisa com algum trabalho.
Este projeto é amplamente dividido entre seus componentes C++ e Rust. O driver C está completo em termos de recursos e deve ser preferido. Em um nível alto, o projeto tem os seguintes componentes
Configuração do Visual Studio com o DDK
Compile o driver e a CLI, mova os arquivos para a mesma pasta do script e execute o script powershell na pasta de instalação como administrador:
./install_as_admin.ps1
Reinicie, depois selecione a entrada de inicialização do STrace e pressione F8 (não Enter!) nesta tela:

Isso deve abrir esta tela; selecione inicializar com o DSE desabilitado:

Após a inicialização bem-sucedida, a CLI pode ser usada para carregar e descarregar DLLs de plugin para começar o rastreamento. Dois plugins de exemplo são fornecidos. Leia os detalhes abaixo atentamente se você encontrar problemas. Talvez seja necessário reiniciar novamente na primeira vez e, potencialmente, definir manualmente o serviço STrace para iniciar automaticamente na inicialização usando uma ferramenta como o process hacker.
A instalação original do DTrace está aqui: https://techcommunity.microsoft.com/t5/windows-kernel-internals/dtrace-on-windows-20h1-updates/ba-p/1127929. O DTrace original exige que o Secure Boot e o Virtualized Based Security sejam configurados; este não é o caso do STrace, pois ele não implementa os tipos de sonda (FBT) que exigem esses recursos.