Quando si esegue il debug di un processo di Windows, talvolta sarebbe opportuno interromperlo il prima possibile.
Inital Callstack ha questo aspetto: (ottieni questo ad es. Quando imposti un breakpoint in a DllMain
funzione attiva DLL_PROCESS_ATTACH
)
...
ntdll.dll!_LdrpCallInitRoutine@16() + 0x14 bytes
ntdll.dll!_LdrpRunInitializeRoutines@4() + 0x205 bytes
> ntdll.dll!_LdrpInitializeProcess@20() - 0x96d bytes
ntdll.dll!__LdrpInitialize@12() + 0x6269 bytes
ntdll.dll!_KiUserApcDispatcher@20() + 0x7 bytes
quindi impostare un punto di interruzione in una di queste routine ntdll dovrebbe davvero interrompere il processo molto presto.
Tuttavia, non riesco a capire come impostare un breakpoint lì prima di iniziare il processo nel debugger. È possibile in Visual Studio (2005)? Come? Può essere fatto in WinDbg?
risposte:
5 per risposta № 1Vorrei usare qualcosa di simile GFlags per avviare il debugger all'avvio del processo.
Ecco un esempio di impostazioni gflags per test.exe
Ed ecco l'output del debugger. Si noti lo stack di chiamate con ntdll!LdrpInitializeProcess
CommandLine: "C: temptest.exe" Il percorso di ricerca dei simboli è: srv *; srvc: Simbolihttp://msdl.microsoft.com/download/symbols Il percorso di ricerca eseguibile è: ModLoad: 00000000
00d20000 00000000
00d28000
image0000000000d20000 (1b40.464): Break instruction exception - code 80000003 (first chance) ntdll!LdrpDoDebuggerBreak+0x30: 00000000
77c7cb60 cc int 3 0: 000> k Child-SP RetAddr
Chiama il sito 000000000012ed70 00000000
77c32ef5 ntdll! LdrpDoDebuggerBreak + 0x30 000000000012edb0 00000000
77c11a17 ntdll! LdrpInitializeProcess + 0x1b4f 000000000012f2a0 00000000
77bfc32e ntdll! ?? :: :: FNODOBFMstring"+0x29220 00000000
0012f310 00000000`00000000 ntdll! LdrInitializeThunk + 0xe
O potresti aprire il processo all'interno del debugger come Windbg in cui verrebbero introdotte ntdll!LdrpInitializeProcess
per impostazione predefinita.
HTH
1 per risposta № 2
Ho scoperto come farlo in Visual Studio.
Il problema qui è che l'impostazione di un punto di interruzione inqualsiasi funzione di assemblaggio verrà ricordata come "Punto di interruzione dei dati". Questi punti di interruzione sono disabilitati non appena il processo si interrompe, quindi anche se ne ho impostato uno in questa funzione (posso farlo perché ho la funzione sullo stack se imposto un breakpoint in qualsiasi funzione DllMain) questo breakpoint sarà disabilitato per un nuova esecuzione del processo.
però per ntdll.dll (e kernel32.dll) gli indirizzi di caricamento sono praticamente fissi e non cambiano (e almeno non fino al riavvio).
Quindi, prima di iniziare il processo, devo solo riattivare il punto di interruzione dei dati per l'indirizzo che corrisponde a questa funzione NtDll e il debugger si fermerà qui.