Conversion d’adresses virtuelles en adresses physiques
La plupart des commandes de débogueur utilisent des adresses virtuelles, et non des adresses physiques, comme entrée et sortie. Toutefois, il arrive que l’adresse physique soit utile.
Il existe deux façons de convertir une adresse virtuelle en adresse physique : à l’aide de l’extension !vtop et à l’aide de l’extension !pte .
Pour obtenir une vue d’ensemble de l’adresse virtuelle dans Windows, consultez Espaces d’adressage virtuels.
Conversion d’adresses à l’aide de !vtop
Supposons que vous déboguez un ordinateur cible sur lequel le processus MyApp.exe est en cours d’exécution et que vous souhaitez examiner l’adresse virtuelle 0x0012F980. Voici la procédure que vous utiliseriez avec l’extension !vtop pour déterminer l’adresse physique correspondante.
Conversion d’une adresse virtuelle en adresse physique à l’aide de !vtop
Vérifiez que vous travaillez en hexadécimal. Si nécessaire, définissez la base actuelle avec la commande N 16 .
Déterminez l’index d’octets de l’adresse. Ce nombre est égal aux 12 bits les plus bas de l’adresse virtuelle. Ainsi, l’adresse virtuelle 0x0012F980 a un index d’octets de 0x980.
Déterminez la base de répertoires de l’adresse à l’aide de l’extension !process :
kd> !process 0 0 **** NT ACTIVE PROCESS DUMP **** .... PROCESS ff779190 SessionId: 0 Cid: 04fc Peb: 7ffdf000 ParentCid: 0394 DirBase: 098fd000 ObjectTable: e1646b30 TableSize: 8. Image: MyApp.exe
Déterminez le numéro de cadre de page de la base du répertoire. Il s’agit simplement de la base de répertoire sans les trois zéros hexadécimaux de fin. Dans cet exemple, la base de répertoires étant 0x098FD000, le numéro de cadre de page est 0x098FD.
Utilisez l’extension !vtop . Le premier paramètre de cette extension doit être le numéro de cadre de page. Le deuxième paramètre de !vtop doit être l’adresse virtuelle en question :
kd> !vtop 98fd 12f980 Pdi 0 Pti 12f 0012f980 09de9000 pfn(09de9)
Le deuxième numéro indiqué sur la dernière ligne est l’adresse physique du début de la page physique.
Ajoutez l’index d’octets à l’adresse du début de la page : 0x09DE9000 + 0x980 = 0x09DE9980. Il s’agit de l’adresse physique souhaitée.
Vous pouvez vérifier que ce calcul a été effectué correctement en affichant la mémoire à chaque adresse. L’extension !d\* affiche la mémoire à une adresse physique spécifiée :
kd> !dc 9de9980
# 9de9980 6d206e49 726f6d65 00120079 0012f9f4 In memory.......
# 9de9990 0012f9f8 77e57119 77e8e618 ffffffff .....q.w...w....
# 9de99a0 77e727e0 77f6f13e 77f747e0 ffffffff .'.w>..w.G.w....
# 9de99b0 .....
La commande d* (Mémoire d’affichage) utilise une adresse virtuelle comme argument :
kd> dc 12f980
0012f980 6d206e49 726f6d65 00120079 0012f9f4 In memory.......
0012f990 0012f9f8 77e57119 77e8e618 ffffffff .....q.w...w....
0012f9a0 77e727e0 77f6f13e 77f747e0 ffffffff .'.w>..w.G.w....
0012f9b0 .....
Étant donné que les résultats sont identiques, cela indique que l’adresse physique 0x09DE9980 correspond effectivement à l’adresse virtuelle 0x0012F980.
Conversion d’adresse à l’aide de !pte
Là encore, supposons que vous examinez l’adresse virtuelle 0x0012F980 appartenant au processus MyApp.exe. Voici la procédure que vous utiliseriez avec l’extension !pte pour déterminer l’adresse physique correspondante :
Conversion d’une adresse virtuelle en adresse physique à l’aide de !pte
Vérifiez que vous travaillez en hexadécimal. Si nécessaire, définissez la base actuelle avec la commande N 16 .
Déterminez l’index d’octets de l’adresse. Ce nombre est égal aux 12 bits les plus bas de l’adresse virtuelle. Ainsi, l’adresse virtuelle 0x0012F980 a un index d’octets de 0x980.
Définissez le contexte de processus sur le processus souhaité :
kd> !process 0 0 **** NT ACTIVE PROCESS DUMP **** .... PROCESS ff779190 SessionId: 0 Cid: 04fc Peb: 7ffdf000 ParentCid: 0394 DirBase: 098fd000 ObjectTable: e1646b30 TableSize: 8. Image: MyApp.exe kd> .process /p ff779190 Implicit process is now ff779190 .cache forcedecodeuser done
Utilisez l’extension !pte avec l’adresse virtuelle comme argument. Cela affiche des informations en deux colonnes. La colonne de gauche décrit l’entrée de répertoire de page (PDE) pour cette adresse ; la colonne de droite décrit son entrée de table de pages (PTE) :
kd> !pte 12f980 VA 0012f980 PDE at C0300000 PTE at C00004BC contains 0BA58067 contains 09DE9067 pfn ba58 ---DA--UWV pfn 9de9 ---DA--UWV
Regardez dans la dernière ligne de la colonne de droite. La notation « pfn 9de9 » s’affiche. Le nombre 0x9DE9 est le numéro de cadre de page (PFN) de ce PTE. Multipliez le numéro de cadre de page par 0x1000 (par exemple, décaler de 12 bits). Le résultat, 0x09DE9000, est l’adresse physique du début de la page.
Ajoutez l’index d’octets à l’adresse du début de la page : 0x09DE9000 + 0x980 = 0x09DE9980. Il s’agit de l’adresse physique souhaitée.
Il s’agit du même résultat obtenu par la méthode précédente.
Conversion manuelle des adresses
Bien que les extensions !ptov et pte fournissent le moyen le plus rapide de convertir des adresses virtuelles en adresses physiques, cette conversion peut également être effectuée manuellement. Une description de ce processus vous permettra d’éclaircir certains des détails de l’architecture de la mémoire virtuelle.
La taille des structures de mémoire varie en fonction du processeur et de la configuration matérielle. Cet exemple est tiré d’un système x86 sur lequel l’extension d’adresse physique (PAE) n’est pas activée.
En utilisant 0x0012F980 comme adresse virtuelle, vous devez d’abord la convertir en binaire, soit manuellement, soit à l’aide de la commande .formats (Afficher les formats numériques) :
kd> .formats 12f980
Evaluate expression:
Hex: 0012f980
Decimal: 1243520
Octal: 00004574600
Binary: 00000000 00010010 11111001 10000000
Chars: ....
Time: Thu Jan 15 01:25:20 1970
Float: low 1.74254e-039 high 0
Double: 6.14381e-318
Cette adresse virtuelle est une combinaison de trois champs. Les bits 0 à 11 sont l’index d’octets. Les bits 12 à 21 sont l’index de la table de pages. Les bits 22 à 31 sont l’index du répertoire de pages. En séparant les champs, vous disposez des éléments suivants :
0x0012F980 = 0y 00000000 00 010010 1111 1001 10000000
Cela expose les trois parties de l’adresse virtuelle :
Index du répertoire de pages = 0y000000000 = 0x0
Index de table de pages = 0y0100101111 = 0x12F
Index d’octet = 0y100110000000 = 0x980
Vous avez ensuite besoin de trois informations supplémentaires pour votre système.
Taille de chaque PTE. Il s’agit de 4 octets sur les systèmes x86 non PAE.
Taille d’une page. Il s’agit de 0x1000 octets.
Adresse virtuelle PTE_BASE. Sur un système non PAE, il s’agit de 0xC0000000.
À l’aide de ces données, vous pouvez calculer l’adresse du PTE lui-même :
PTE address = PTE_BASE
+ (page directory index) * PAGE_SIZE
+ (page table index) * sizeof(MMPTE)
= 0xc0000000
+ 0x0 * 0x1000
+ 0x12F * 4
= 0xC00004BC
Il s’agit de l’adresse du PTE. Le PTE est un DWORD 32 bits. Examinez son contenu :
kd> dd 0xc00004bc L1
c00004bc 09de9067
Ce PTE a une valeur 0x09DE9067. Il est composé de deux champs :
Les 12 bits faibles du PTE sont les indicateurs status. Dans ce cas, ces indicateurs sont égaux 0x067 -- ou, en binaire, 0y0000011100111. Pour obtenir une explication des indicateurs de status, consultez la page de référence !pte.
Les 20 bits élevés du PTE sont égaux au numéro de trame de page (PFN) du PTE. Dans ce cas, le PFN est 0x09DE9.
La première adresse physique de la page physique est le PFN multiplié par 0x1000 (décalé vers la gauche de 12 bits). L’index d’octets est le décalage de cette page. Ainsi, l’adresse physique que vous recherchez est 0x09DE9000 + 0x980 = 0x09DE9980. Il s’agit du même résultat obtenu par les méthodes précédentes.