
Una reimplementación de DTrace en Windows
El rastreador de Steve. Una reimplementación del hook de llamadas al sistema de DTrace en Windows. Piense en esto como un hook de SSDT compatible con PatchGuard, pero sin trucos. No admite SSSDT (apis de win32k), ya que las propias API de llamadas al sistema de DTrace no admiten esta tabla adicional. Las apis del kernel Zw* se pueden rastrear además de todas las syscalls de SSDT en modo usuario.
Por favor, lea hasta el final de este readme si está desarrollando nuevos plugins para STrace.
Dtrace en Windows admite múltiples tipos de sondas. Estos incluyen syscall, fbt, etw, profile, y quizás más. Esta reimplementación solo reimplementa los tipos de sonda syscall y etw. Todos los demás tipos de sonda se consideran completamente fuera del alcance de este proyecto y nunca serán compatibles. Siéntase libre de hacer un fork del proyecto si desea agregar tipos de sonda adicionales. El alcance se limitó solo a las sondas syscall y etw debido a la complejidad de los otros tipos de sonda y los sistemas que tocan.
Esta reimplementación descarta por completo el lenguaje de scripting D (nota: NO DLang, el lenguaje moderno más popular). La complejidad de una VM en el kernel como la implementación original de DTrace no es adecuada para este proyecto. En su lugar, esta implementación expone directamente los callbacks de C relevantes necesarios para conectarse a las interfaces del kernel de DTrace de Windows. Para habilitar la 'carga en caliente' de scripts, se utilizó un sistema de plugins basado en DLL como reemplazo de la VM + entorno de scripting del dtrace original. Este sistema de plugins acepta una DLL de modo usuario 'normal' sin ninguna verificación de seguridad habilitada, ni dependencias externas, y la mapea manualmente en el espacio de direcciones del kernel. La plugin dll tiene exportaciones que se invocan cuando ocurren callbacks de syscall del kernel. Las APIs del kernel se resuelven mediante la tabla de importación normal (IAT) de la DLL; los plugins DLL enlazan con ntoskrnl.lib y luego el driver resolverá estas APIs en tiempo de carga, permitiendo que se llame a cualquier api del sistema dentro de los plugins DLL con normalidad. El rendimiento de este sistema de plugins es excelente, ya que el código nativo, en lugar de un intérprete de scripts o un JIT, se ejecuta directamente entre ENTRY y RETURN de la syscall. Este diseño mejora el rendimiento en comparación con la implementación de dtrace proporcionada por Microsoft.
Establecer hooks es muy simple: se obtiene una rutina para registrar/desregistrar un hook por nombre de api, con un callback pre y post syscall. Los callbacks tienen argumentos y valores de retorno accesibles como valores de solo lectura. Los valores de retorno se pueden falsear en las sondas de retorno y los argumentos se pueden modificar en las sondas de entrada, pero la syscall original normalmente no puede reemplazar o 'cancelar' una syscall: esta API actúa como un observador. Sin embargo, existe una supervisión similar a la documentada en (https://github.com/everdox/InfinityHook y https://github.com/everdox/InfinityHook/raw/master/resources/perf.png) que permite reemplazar el puntero de syscall en la pila. Con esta supervisión, es posible reemplazar por completo una syscall con un puntero a una rutina que usted controle. Cuando ocurren eventos y su callback de hook se dispara, puede hacer lo que desee. Los callbacks son síncronos, lo que significa que si retrasa la ejecución en el callback de entrada, por ejemplo sentándose en un bucle while, la llamada a la syscall se retrasará esa cantidad de tiempo. La ejecución de la llamada al sistema ocurre justo después del retorno del callback de entrada y justo antes de la entrada del callback de retorno. Este sistema es totalmente compatible con PatchGuard; sin embargo, DSE debe estar deshabilitado, ya que Microsoft desafortunadamente considera este tipo de extensión del kernel como parte del kernel de NT y, por lo tanto, valida que el firmante raíz sea Windows. Esto no funciona con trucos como habilitar firmantes de kernel personalizados; DSE realmente debe estar desactivado durante el arranque del kernel.
ValidationFlags=IMGP_LATEST_MS_ROOT_REQUIRED | IMGP_WINDOWS_ROOT_REQUIRED | IMGP_MS_SIGNATURE_REQUIRED
Scenario=ImgSigningScenarioWindows
El driver de Rust descarta el sistema de plugins basado en DLL utilizado por el driver de C++ e intenta usar un intérprete de web assembly para alojar scripts wasm en el kernel de Windows en su lugar. Esto es para ser más similar a la implementación original de dtrace que usa una VM, pero con un lenguaje mejor que DLang. Esto proporciona sandboxing y otros beneficios agradables. El POC está completo y funciona, pero desafortunadamente no es utilizable debido a problemas de rendimiento al interpretar WASM con WASMI. Se requeriría un motor wasm basado en JIT compatible con el kernel de NT para que este diseño alternativo sea viable. Se incluye como una novedad divertida, y podría ser útil para otra cosa con algo de trabajo.
Este proyecto está dividido en gran medida entre sus componentes de C++ y Rust. El driver de C++ está completo en funcionalidad y debe preferirse. A alto nivel, el proyecto tiene los siguientes componentes
Configurar Visual Studio con DDK
Compile el driver y la cli, mueva los archivos a la misma carpeta que el script, y luego ejecute el script de powershell en la carpeta de instalación como administrador:
./install_as_admin.ps1
Reinicie, luego seleccione la entrada de arranque STrace, y presione F8 (¡no Enter!) en esta pantalla:

Eso debería mostrar esta pantalla, seleccione arrancar con DSE deshabilitado:

Después de un arranque exitoso, la CLI se puede usar para cargar y descargar plugins DLL para comenzar el rastreo. Se proporcionan dos plugins de ejemplo. Lea los detalles a continuación en detalle si tiene problemas. Es posible que necesite reiniciar nuevamente la primera vez y, potencialmente, configurar manualmente el servicio STrace para que se inicie automáticamente al arrancar usando una herramienta como process hacker.
La instalación original de DTrace está aquí: https://techcommunity.microsoft.com/t5/windows-kernel-internals/dtrace-on-windows-20h1-updates/ba-p/1127929. El DTrace original requiere que se configuren Secure Boot y Virtualized Based Security; este no es el caso con STrace, ya que no implementa los tipos de sonda (FBT) que requieren esas características.