Lire en anglais

Partager via


Exemples de programme de commande du débogueur

Les sections suivantes décrivent les programmes de commandes du débogueur.

Utilisation du jeton .foreach

L’exemple suivant utilise le jeton .foreach pour rechercher les valeurs WORD 5a4d. Pour chaque valeur 5a4d trouvée, le débogueur affiche 8 valeurs DWORD, en commençant à l’adresse de l’emplacement où le DWORD 5a4d a été trouvé.

0:000> .foreach (place { s-[1]w 77000000 L?4000000 5a4d }) { dc place L8 } 

L’exemple suivant utilise le jeton .foreach pour rechercher les valeurs WORD 5a4d. Pour chaque valeur 5a4d trouvée, le débogueur affiche 8 valeurs DWORD, en commençant 4 octets avant l’adresse où le DWORD 5a4d a été trouvé.

0:000> .foreach (place { s-[1]w 77000000 L?4000000 5a4d }) { dc place -0x4 L8 } 

L’exemple suivant affiche les mêmes valeurs.

0:000> .foreach (place { s-[1]w 77000000 L?4000000 5a4d }) { dc ( place -0x4 ) L8 } 

Remarque Si vous souhaitez utiliser le nom de la variable dans la partie OutCommands de la commande, vous devez ajouter un espace après le nom de la variable. Par exemple, dans l’exemple de précédage, il existe un espace entre la variable place et l’opérateur de soustraction.

L’option -[1] avec la commande (Rechercher en mémoire) entraîne l’inclure uniquement les adresses qu’il trouve, et non les valeurs trouvées à ces adresses.

La commande suivante affiche des informations détaillées sur le module pour tous les modules situés dans la plage de mémoire de 0x77000000 à 0x7F000000.

0:000> .foreach (place { lm1m }) { .if ((${place} >= 0x77000000) & (${place} <= 0x7f000000)) { lmva place } } 

L’option 1m avec la commande lm (List Loaded Modules) entraîne l’inclure uniquement les adresses des modules, et non la description complète des modules.

L’exemple précédent utilise le jeton${ } (Interpréteur d’alias)pour vous assurer que les alias sont remplacés même s’ils sont en regard d’un autre texte. Si la commande n’a pas inclus ce jeton, la parenthèse ouvrante en regard de placer empêche le remplacement de l’alias. Notez que le jeton ${} fonctionne sur les variables utilisées dans .foreach et sur les vrais alias.

Marche à pied de la liste des processus

L’exemple suivant décrit la liste des processus en mode noyau et affiche le nom exécutable de chaque entrée de la liste.

Cet exemple doit être stocké en tant que fichier texte et exécuté avec la commande $$>< (Exécuter le fichier de script). Cette commande charge l’intégralité du fichier, remplace toutes les retours chariot par des points-virgules et exécute le bloc résultant. Cette commande vous permet d’écrire des programmes lisibles à l’aide de plusieurs lignes et retraits, au lieu d’avoir à presser l’ensemble du programme sur une seule ligne.

Cet exemple illustre les fonctionnalités suivantes :

  • Les pseudo-registres $t 0, $t 1et $t 2 sont utilisés comme variables dans ce programme. Le programme utilise également des alias nommés Procc et $ImageName.

  • Ce programme utilise l’évaluateur d’expression MASM. Toutefois, le jeton @@c++ ( ) apparaît une fois. Ce jeton entraîne l’utilisation de l’évaluateur d’expression C++ pour analyser l’expression entre parenthèses. Cette utilisation permet au programme d’utiliser directement les jetons de structure C++.

  • Le ? indicateur est utilisé avec la commander (Registers). Cet indicateur affecte des valeurs typées au pseudo-registre $t 2.

$$  Get process list LIST_ENTRY in $t0.
r $t0 = nt!PsActiveProcessHead

$$  Iterate over all processes in list.
.for (r $t1 = poi(@$t0);
      (@$t1 != 0) & (@$t1 != @$t0);
      r $t1 = poi(@$t1))
{
    r? $t2 = #CONTAINING_RECORD(@$t1, nt!_EPROCESS, ActiveProcessLinks);
    as /x Procc @$t2

 $$  Get image name into $ImageName.
 as /ma $ImageName @@c++(&@$t2->ImageFileName[0])

 .block
    {
        .echo ${$ImageName} at ${Procc}
    }

    ad $ImageName
    ad Procc
}

Marche à pied de la liste des LDR_DATA_TABLE_ENTRY

L’exemple suivant décrit la liste LDR_DATA_TABLE_ENTRY en mode utilisateur et affiche l’adresse de base et le chemin complet de chaque entrée de liste.

Comme dans l’exemple précédent, ce programme doit être enregistré dans un fichier et exécuté avec la commande $$>< (Exécuter le fichier de script).

Cet exemple illustre les fonctionnalités suivantes :

  • Ce programme utilise l’évaluateur d’expression MASM. Toutefois, à deux endroits, le jeton @@c++( ) s’affiche. Ce jeton entraîne l’utilisation de l’évaluateur d’expression C++ pour analyser l’expression entre parenthèses. Cette utilisation permet au programme d’utiliser directement des jetons de structure C++.

  • Le ? indicateur est utilisé avec la commander (Registers). Cet indicateur affecte des valeurs typées aux pseudo-registres $t 0 et $t 1. Dans le corps de la boucle, $t 1 a le type ntdll !_LDR_DATA_TABLE_ENTRY\*, afin que le programme puisse faire des références directes aux membres.

  • Les alias nommés par l’utilisateur $Base et $Mod sont utilisés dans ce programme. Les signes dollar réduisent la possibilité que ces alias aient été utilisés précédemment dans la session du débogueur actuel. Les signes de dollar ne sont pas nécessaires. Le jeton ${/v : } interprète littéralement l’alias, ce qui l’empêche d’être remplacé s’il a été défini avant l’exécution du script. Vous pouvez également utiliser ce jeton avec n’importe quel bloc pour empêcher l’utilisation des définitions d’alias avant l’utilisation du bloc.

  • Le jeton.blockest utilisé pour ajouter une étape de remplacement d’alias supplémentaire. Le remplacement d’alias se produit une fois pour l’ensemble du script lorsqu’il est chargé et une fois lorsque chaque bloc est entré. Sans le jeton .block et ses accolades, la commande .echo ne reçoit pas les valeurs des alias $Mod et $Base affectés dans les lignes précédentes.

$$ Get module list LIST_ENTRY in $t0.
r? $t0 = &@$peb->Ldr->InLoadOrderModuleList
 
$$ Iterate over all modules in list.
.for (r? $t1 = *(ntdll!_LDR_DATA_TABLE_ENTRY**)@$t0;
 (@$t1 != 0) & (@$t1 != @$t0);
      r? $t1 = (ntdll!_LDR_DATA_TABLE_ENTRY*)@$t1->InLoadOrderLinks.Flink)
{
    $$ Get base address in $Base.
 as /x ${/v:$Base} @@c++(@$t1->DllBase)
 
 $$ Get full name into $Mod.
 as /msu ${/v:$Mod} @@c++(&@$t1->FullDllName)
 
 .block
    {
        .echo ${$Mod} at ${$Base}
    }
 
    ad ${/v:$Base}
    ad ${/v:$Mod}
}