Partager via


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

  1. Vérifiez que vous travaillez en hexadécimal. Si nécessaire, définissez la base actuelle avec la commande N 16 .

  2. 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.

  3. 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
    
  4. 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.

  5. 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.

  6. 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

  1. Vérifiez que vous travaillez en hexadécimal. Si nécessaire, définissez la base actuelle avec la commande N 16 .

  2. 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.

  3. 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
    
  4. 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
    
  5. 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.

  6. 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.