Prise en main de WinDbg (mode utilisateur)
WinDbg est un débogueur en mode noyau et en mode utilisateur inclus dans les Outils de débogage pour Windows. Les exercices pratiques suivants peuvent vous aider vous lancer dans l’utilisation de WinDbg comme un débogueur en mode utilisateur.
Pour des informations sur la manière d’obtenir les Outils de débogage pour Windows, veuillez consulter la section Télécharger et installer le débogueur Windows WinDbg.
Après avoir installé les outils de débogage, recherchez les répertoires d’installation pour les versions 64 bits (x64) et 32 bits (x86) des outils. Par exemple :
- C:\Program Files (x86)\Windows Kits\10\Debuggers\x64
- C:\Program Files (x86)\Windows Kits\10\Debuggers\x86
Ouvrez le Bloc-notes et attachez WinDbg
Allez dans votre répertoire d’installation, et ouvrez WinDbg.exe.
Dans le menu Fichier, sélectionnez Lancer un exécutable. Dans la boîte de dialogue de « Lancer en exécutable », rendez-vous dans le dossier qui contient notepad.exe. (Le fichier notepad.exe est généralement dans C:\Windows\System32.) Pour Nom de fichier, saisissez notepad.exe. Sélectionnez Ouvrir.
Dans la ligne de commande en bas de la fenêtre WinDbg, saisissez la commande suivante :
La sortie est similaire à cet exemple :
Symbol search path is: srv* Expanded Symbol search path is: cache*;SRV
Le chemin de recherche des symboles indique à WinDbg où chercher les fichiers de symboles (PDB). Le débogueur a besoin de fichiers de symboles pour obtenir des informations sur les modules de code, comme les noms de fonctions et les noms de variables.
Saisissez ensuite la commande suivante :
La commande
.reload
indique à WinDbg de faire sa recherche initiale pour trouver et charger les fichiers de symboles.Pour voir les symboles pour le module notepad.exe, saisissez la commande suivante :
Remarque
Si aucun résultat n’apparaît, saisissez
.reload /f
pour tenter de forcer le chargement des symboles. Utilisez !sym noisy pour afficher des informations supplémentaires sur le chargement des symboles.Pour voir les symboles dans le module notepad.exe qui contiennent
main
, utilisez la commande examine symbols pour lister les modules qui correspondent au masque :x notepad!wWin*
La sortie est similaire à cet exemple :
00007ff6`6e76b0a0 notepad!wWinMain (wWinMain) 00007ff6`6e783db0 notepad!wWinMainCRTStartup (wWinMainCRTStartup)
Pour mettre un point d’arrêt à
notepad!wWinMain
, saisissez la commande suivante :Pour vérifier que votre point d’arrêt a été défini, saisissez la commande suivante :
La sortie est similaire à cet exemple :
0 e Disable Clear 00007ff6`6e76b0a0 0001 (0001) 0:**** notepad!wWinMain
Pour démarrer le processus Bloc-notes, saisissez la commande suivante :
Le Bloc-notes s’exécute jusqu’à ce qu’il arrive à la fonction
WinMain
, puis il s’arrête dans le débogueur.Breakpoint 0 hit notepad!wWinMain: 00007ff6`6e76b0a0 488bc4 mov rax,rsp
Pour voir une liste des modules de code actuellement chargés dans le processus Bloc-notes, saisissez la commande suivante :
La sortie est similaire à cet exemple :
0:000> lm start end module name 00007ff6`6e760000 00007ff6`6e798000 notepad (pdb symbols) C:\ProgramData\Dbg\sym\notepad.pdb\BC04D9A431EDE299D4625AD6201C8A4A1\notepad.pdb 00007ff8`066a0000 00007ff8`067ab000 gdi32full (deferred) 00007ff8`067b0000 00007ff8`068b0000 ucrtbase (deferred) 00007ff8`06a10000 00007ff8`06aad000 msvcp_win (deferred) 00007ff8`06ab0000 00007ff8`06ad2000 win32u (deferred) 00007ff8`06b40000 00007ff8`06e08000 KERNELBASE (deferred) 00007ff8`07220000 00007ff8`072dd000 KERNEL32 (deferred) 00007ff8`07420000 00007ff8`07775000 combase (deferred) 00007ff8`07820000 00007ff8`079c0000 USER32 (deferred) 00007ff8`079c0000 00007ff8`079f0000 IMM32 (deferred) 00007ff8`07c00000 00007ff8`07c2a000 GDI32 (deferred) 00007ff8`08480000 00007ff8`085ab000 RPCRT4 (deferred) 00007ff8`085b0000 00007ff8`0864e000 msvcrt (deferred) 00007ff8`08c40000 00007ff8`08cee000 shcore (deferred) 00007ff8`08db0000 00007ff8`08fa5000 ntdll (pdb symbols) C:\ProgramData\Dbg\sym\ntdll.pdb\53F12BFE149A2F50205C8D5D66290B481\ntdll.pdb 00007fff`f8580000 00007fff`f881a000 COMCTL32 (deferred)
Pour voir une arborescence des appels de procédure, saisissez la commande suivante :
La sortie est similaire à cet exemple :
0:000> k 00 000000c8`2647f708 00007ff6`6e783d36 notepad!wWinMain 01 000000c8`2647f710 00007ff8`07237034 notepad!__scrt_common_main_seh+0x106 02 000000c8`2647f750 00007ff8`08e02651 KERNEL32!BaseThreadInitThunk+0x14 03 000000c8`2647f780 00000000`00000000 ntdll!RtlUserThreadStart+0x21
Pour démarrer à nouveau le Bloc-notes, saisissez la commande suivante :
Pour interrompre le Bloc-notes, dans le menu Fichier, sélectionnez Interrompre.
Pour définir et vérifier un point d’arrêt à
ZwWriteFile
, saisissez les commandes suivantes :Pour démarrer à nouveau le Bloc-notes, saisissez g. Dans la fenêtre du Bloc-notes, saisissez du texte.. Dans le menu File (Fichier), sélectionnez Save (Enregistrer). Le code en cours s’interrompt lorsqu’il arrive à
ZwCreateFile
. Saisissez la commande k pour voir l’arborescence des appels de procédure.Dans la fenêtre WinDbg, à gauche de la ligne de commande, les numéros de processeur et de thread sont affichés. Dans cet exemple, le numéro de processeur actuel est 0, et le numéro de thread actuel est 11 (
0:011>
). La fenêtre affiche la trace de pile pour le thread 11 s’exécutant sur le processeur 0.Pour voir une liste de tous les threads dans le processus Bloc-notes, entrez cette commande (le tilde) :
La sortie est similaire à cet exemple :
0:011> ~ 0 Id: 5500.34d8 Suspend: 1 Teb: 000000c8`262c4000 Unfrozen 1 Id: 5500.3960 Suspend: 1 Teb: 000000c8`262c6000 Unfrozen 2 Id: 5500.5d68 Suspend: 1 Teb: 000000c8`262c8000 Unfrozen 3 Id: 5500.4c90 Suspend: 1 Teb: 000000c8`262ca000 Unfrozen 4 Id: 5500.4ac4 Suspend: 1 Teb: 000000c8`262cc000 Unfrozen 5 Id: 5500.293c Suspend: 1 Teb: 000000c8`262ce000 Unfrozen 6 Id: 5500.53a0 Suspend: 1 Teb: 000000c8`262d0000 Unfrozen 7 Id: 5500.3ca4 Suspend: 1 Teb: 000000c8`262d4000 Unfrozen 8 Id: 5500.808 Suspend: 1 Teb: 000000c8`262da000 Unfrozen 10 Id: 5500.3940 Suspend: 1 Teb: 000000c8`262dc000 Unfrozen . 11 Id: 5500.28b0 Suspend: 1 Teb: 000000c8`262de000 Unfrozen 12 Id: 5500.12bc Suspend: 1 Teb: 000000c8`262e0000 Unfrozen 13 Id: 5500.4c34 Suspend: 1 Teb: 000000c8`262e2000 Unfrozen
Dans cet exemple, 14 threads ont des indices de 0 à 13.
Pour consulter l’arborescence des appels de procédure pour le thread 0, saisissez les commandes suivantes :
La sortie est similaire à cet exemple :
0:011> ~0s 0:011> ~0s win32u!NtUserGetProp+0x14: 00007ff8`06ab1204 c3 ret 0:000> k # Child-SP RetAddr Call Site 00 000000c8`2647bd08 00007ff8`07829fe1 win32u!NtUserGetProp+0x14 01 000000c8`2647bd10 00007fff`f86099be USER32!GetPropW+0xd1 02 000000c8`2647bd40 00007ff8`07d12f4d COMCTL32!DefSubclassProc+0x4e 03 000000c8`2647bd90 00007fff`f8609aba SHELL32!CAutoComplete::_EditWndProc+0xb1 04 000000c8`2647bde0 00007fff`f86098b7 COMCTL32!CallNextSubclassProc+0x9a 05 000000c8`2647be60 00007ff8`0782e858 COMCTL32!MasterSubclassProc+0xa7 06 000000c8`2647bf00 00007ff8`0782de1b USER32!UserCallWinProcCheckWow+0x2f8 07 000000c8`2647c090 00007ff8`0782d68a USER32!SendMessageWorker+0x70b 08 000000c8`2647c130 00007ff8`07afa4db USER32!SendMessageW+0xda
Pour quitter le débogage et se détacher du processus de Bloc-notes Windows, veuillez saisir la commande suivante :
Ouvrez votre propre application et attachez WinDbg
Par exemple, supposons que vous avez écrit et construit cette petite application de console :
...
void MyFunction(long p1, long p2, long p3)
{
long x = p1 + p2 + p3;
long y = 0;
y = x / p2;
}
void main ()
{
long a = 2;
long b = 0;
MyFunction(a, b, 5);
}
Pour cet exercice, supposons que l’application construite (MyApp.exe) et le fichier de symboles (MyApp.pdb) se trouvent dans C:\MyApp\x64\Debug. Supposons également que le code source de l’application se trouve dans C:\MyApp\MyApp et que la machine cible a compilé MyApp.exe.
Ouvrez WinDbg.
Dans le menu Fichier, sélectionnez Lancer un exécutable. Dans la boîte de dialogue « Lancer un exécutable », rendez-vous dans C:\MyApp\x64\Debug. Pour Nom de fichier, saisissez MyApp.exe. Sélectionnez Ouvrir.
Saisissez la commande :
.sympath+ C:\MyApp\x64\Debug
Les commandes indiquent à WinDbg où trouver les symboles et le code source de votre application. Dans ce cas, l’emplacement du code source n’a pas besoin d’être défini en utilisant .srcpath car les symboles ont des chemins complets vers les fichiers source.
Saisissez la commande :
Votre application s’interrompt dans le débogueur lorsqu’elle arrive à sa fonction
main
.WinDbg affiche votre code source et la fenêtre de commande.
Dans le menu Déboguer, sélectionnez Pas à pas (ou tapez F11). Continuez à avancer pas à pas jusqu’à ce que vous entriez dans
MyFunction
Lorsque vous entrez dans la ligney = x / p2
, votre application se plante et s’interrompt dans le débogueur.La sortie est similaire à cet exemple :
(1450.1424): Integer divide-by-zero - code c0000094 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. MyApp!MyFunction+0x44: 00007ff6`3be11064 f77c2428 idiv eax,dword ptr [rsp+28h] ss:00000063`2036f808=00000000
Entrez cette commande :
WinDbg affiche une analyse du problème (dans ce cas, division par 0).
FAULTING_IP: MyApp!MyFunction+44 [c:\myapp\myapp\myapp.cpp @ 7] 00007ff6`3be11064 f77c2428 idiv eax,dword ptr [rsp+28h] EXCEPTION_RECORD: ffffffffffffffff -- (.exr 0xffffffffffffffff) ExceptionAddress: 00007ff63be11064 (MyApp!MyFunction+0x0000000000000044) ExceptionCode: c0000094 (Integer divide-by-zero) ExceptionFlags: 00000000 NumberParameters: 0 ... STACK_TEXT: 00000063`2036f7e0 00007ff6`3be110b8 : ... : MyApp!MyFunction+0x44 00000063`2036f800 00007ff6`3be1141d : ... : MyApp!main+0x38 00000063`2036f840 00007ff6`3be1154e : ... : MyApp!__tmainCRTStartup+0x19d 00000063`2036f8b0 00007ffc`b1cf16ad : ... : MyApp!mainCRTStartup+0xe 00000063`2036f8e0 00007ffc`b1fc4629 : ... : KERNEL32!BaseThreadInitThunk+0xd 00000063`2036f910 00000000`00000000 : ... : ntdll!RtlUserThreadStart+0x1d STACK_COMMAND: dt ntdll!LdrpLastDllInitializer BaseDllName ;dt ntdll!LdrpFailureData ;.cxr 0x0 ;kb FOLLOWUP_IP: MyApp!MyFunction+44 [c:\myapp\myapp\myapp.cpp @ 7] 00007ff6`3be11064 f77c2428 idiv eax,dword ptr [rsp+28h] FAULTING_SOURCE_LINE: c:\myapp\myapp\myapp.cpp FAULTING_SOURCE_FILE: c:\myapp\myapp\myapp.cpp FAULTING_SOURCE_LINE_NUMBER: 7 FAULTING_SOURCE_CODE: 3: void MyFunction(long p1, long p2, long p3) 4: { 5: long x = p1 + p2 + p3; 6: long y = 0; > 7: y = x / p2; 8: } 9: 10: void main () 11: { 12: long a = 2; ...
Résumé des commandes
Contents
commande dans le menuHelp
- .sympath (Définir le chemin du symbole)
- .reload (Recharger le module)
- x (Examiner les symboles)
- g (Go)
Break
commande dans le menuDebug
- lm (Lister les modules chargés)
- k (Afficher l’arborescence des appels de procédure)
- bu (Définir un point d’arrêt)
- bl (Liste des points d’arrêt)
- ~ (État du thread)
- ~s (Définir le thread actuel)
- .sympath+ (Définir le chemin des symboles) ajouter au chemin des symboles existant
- .srcpath (Définir le chemin de la source)
Step Into
commande dans le menuDebug
(F11)- !analyze -v
- qd (Quitter et détacher)
Voir aussi
Prise en main de WinDbg (mode noyau)