
Un programma simile a strace per l'API 'native' di Windows
Vedi anche http://rogerorr.github.io/NtTrace/
Avrai bisogno della versione a 64 bit e/o a 32 bit di NtTrace, a seconda di quale corrisponde alle tue applicazioni target
scripts\build-vs-x64.bat o scripts\build-vs-x86.bat per compilare rispettivamente la versione a 64 o 32 bit.oppure
nmake /f NtTrace.makoppure
nmake /f NtTrace.makNtTrace è progettato per essere eseguito dalla riga di comando.
Può essere utilizzato per eseguire un programma, con argomenti se necessario.
Ad esempio:
NtTrace -filter File cmd /c echo hello
oppure per collegarsi a un processo esistente tramite PID o, usando l'opzione -a, per nome.
Ad esempio:
NtTrace 1234
oppure
NtTrace -a notepad
Esegui NtTrace -h per un elenco completo delle opzioni.
Per impostazione predefinita, NtTrace ha come target l'API nativa di Windows esposta tramite NtDll.dll
Vengono forniti anche file di configurazione per molti dei punti di ingresso che supportano l'interfaccia grafica di Windows:
Gdi32Trace.cfg per l'interfaccia del dispositivo grafico
User32Trace.cfg per l'interfaccia utente
Puoi selezionare uno di questi, invece del NtTrace.cfg predefinito, usando l'argomento della riga di comando -config.
Windows viene fornito con DbgHelp.dll nella directory system32. Tuttavia, versioni più recenti di questa DLL sono talvolta disponibili da Microsoft nei loro SDK.
La versione della DLL installata con il sistema operativo tende a prevalere su una versione più recente che potrebbe essere scaricata.
Se scopri di aver bisogno di una versione più recente di quella installata nella directory di sistema, puoi semplicemente copiare la versione più recente di DbgHelp.dll nella stessa directory in cui si trova NtTrace.exe.
(Dovrai anche copiare SymSrv.dll e SrcSrv.dll)
NtTrace funziona utilizzando l'interfaccia di debug di Windows per posizionare breakpoint in NtDll attorno alle chiamate native di Windows nel kernel. Ogni volta che un breakpoint viene colpito, NtTrace legge gli argomenti passati alla chiamata associata e i valori restituiti.
Funziona a livello utente e interessa solo il processo specifico (e i suoi figli). Non viene fatto alcun tentativo di entrare nel kernel. Questa è stata una decisione di progettazione deliberata poiché significa che lo strumento può essere utilizzato senza richiedere diritti amministrativi o autorizzazioni per installare driver di dispositivo. Tuttavia, questo significa anche che lo strumento non intercetterà:
NtTrace, per impostazione predefinita, traccia anche i processi figlio del processo iniziale avviato; l'opzione -pid aggiungerà l'ID del processo a ogni riga di output per aiutare a identificare quale processo ha effettuato quali chiamate. L'opzione -only sopprime la traccia dei processi figlio.
Gestisce anche applicazioni multithread (e l'opzione -tid aiuterà a identificare quale thread sta effettuando ogni chiamata).
Tuttavia, nota che, poiché l'interfaccia di debug di Windows è basata su eventi, se più thread effettuano chiamate simultaneamente, la traccia verrà serializzata.
Per impostazione predefinita, vengono tracciate le chiamate in NtDll; i file di configurazione per Gdi32 e User32 selezionano una DLL di destinazione diversa. NtTrace attualmente non supporta la traccia simultanea di diversi tipi di chiamate di sistema.
La configurazione per le chiamate native è contenuta in NtTrace.cfg e questo file viene analizzato all'avvio del programma. Nota che diverse versioni di Windows supportano diversi insiemi di chiamate.
Alcune delle funzioni native sono ufficialmente documentate da Microsoft, ma molte non sono documentate. L'elenco (quasi) completo è stato ottenuto combinando un lavoro investigativo sulle funzioni e da siti web, come ReactOS.
Ad ogni funzione viene assegnata una categoria e il filtraggio può essere effettuato per nome della funzione (corrispondenza parziale) e per categoria della funzione.
Per impostazione predefinita, NtTrace esegue la traccia al ritorno dalla chiamata di sistema, ma l'opzione -pre può essere utilizzata anche per tracciare prima della chiamata.
Ciò può essere utile se, ad esempio, la stessa struttura viene utilizzata per un buffer di richiesta e di risposta.