Compartir a través de


Conversión de direcciones virtuales a direcciones físicas

La mayoría de los comandos del depurador usan direcciones virtuales, no direcciones físicas, como entrada y salida. Sin embargo, hay veces que tener la dirección física puede ser útil.

Hay dos maneras de convertir una dirección virtual en una dirección física: mediante la extensión !vtop y mediante la extensión !pte .

Para obtener información general sobre la dirección virtual en Windows, consulte Espacios de direcciones virtuales.

Conversión de direcciones con !vtop

Supongamos que está depurando un equipo de destino en el que se ejecuta el proceso de MyApp.exe y desea investigar la dirección virtual 0x0012F980. Este es el procedimiento que usaría con la extensión !vtop para determinar la dirección física correspondiente.

Conversión de una dirección virtual en una dirección física mediante !vtop

  1. Asegúrese de que está trabajando en hexadecimal. Si es necesario, establezca la base actual con el comando N 16 .

  2. Determine el índice de bytes de la dirección. Este número es igual a los 12 bits más bajos de la dirección virtual. Por lo tanto, la dirección virtual 0x0012F980 tiene un índice de bytes de 0x980.

  3. Determine la base del directorio de la dirección mediante la extensión !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. Determine el número de marco de página de la base del directorio. Esto es simplemente la base del directorio sin los tres ceros hexadecimales finales. En este ejemplo, la base del directorio es 0x098FD000, por lo que se 0x098FD el número de marco de página.

  5. Use la extensión !vtop . El primer parámetro de esta extensión debe ser el número de marco de página. El segundo parámetro de !vtop debe ser la dirección virtual en cuestión:

    kd> !vtop 98fd 12f980
    Pdi 0 Pti 12f
    0012f980 09de9000 pfn(09de9)
    

    El segundo número que se muestra en la línea final es la dirección física del principio de la página física.

  6. Agregue el índice de bytes a la dirección del principio de la página: 0x09DE9000 + 0x980 = 0x09DE9980. Esta es la dirección física deseada.

Puede comprobar que este cálculo se ha realizado correctamente mostrando la memoria en cada dirección. La extensión !d\* muestra la memoria en una dirección física especificada:

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

El comando d* (Memoria para mostrar) usa una dirección virtual como argumento:

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

Dado que los resultados son los mismos, esto indica que la dirección física 0x09DE9980 corresponde realmente a la dirección virtual 0x0012F980.

Conversión de direcciones mediante !pte

De nuevo, suponga que está investigando la dirección virtual 0x0012F980 que pertenece al proceso de MyApp.exe. Este es el procedimiento que usaría con la extensión !pte para determinar la dirección física correspondiente:

Convertir una dirección virtual en una dirección física mediante !pte

  1. Asegúrese de que está trabajando en hexadecimal. Si es necesario, establezca la base actual con el comando N 16 .

  2. Determine el índice de bytes de la dirección. Este número es igual a los 12 bits más bajos de la dirección virtual. Por lo tanto, la dirección virtual 0x0012F980 tiene un índice de bytes de 0x980.

  3. Establezca el contexto del proceso en el proceso deseado:

    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. Use la extensión !pte con la dirección virtual como argumento. Esto muestra información en dos columnas. En la columna izquierda se describe la entrada del directorio de página (PDE) para esta dirección; la columna derecha describe su entrada de tabla de páginas (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. Busque en la última fila de la columna derecha. Aparece la notación "pfn 9de9". El número 0x9DE9 es el número de marco de página (PFN) de este PTE. Multiplique el número de marco de página por 0x1000 (por ejemplo, desplazándolo a 12 bits). El resultado, 0x09DE9000, es la dirección física del principio de la página.

  6. Agregue el índice de bytes a la dirección del principio de la página: 0x09DE9000 + 0x980 = 0x09DE9980. Esta es la dirección física deseada.

Este es el mismo resultado obtenido por el método anterior.

Convertir direcciones a mano

Aunque las extensiones !ptov y pte proporcionan la manera más rápida de convertir direcciones virtuales en direcciones físicas, esta conversión también se puede realizar manualmente. Una descripción de este proceso dará luz sobre algunos de los detalles de la arquitectura de memoria virtual.

Las estructuras de memoria varían en tamaño, según el procesador y la configuración de hardware. Este ejemplo se toma de un sistema x86 que no tiene habilitada la extensión de dirección física (PAE).

Con 0x0012F980 de nuevo como dirección virtual, primero debe convertirlo a binario, ya sea a mano o mediante el comando .formats (Mostrar formatos de número):

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

Esta dirección virtual es una combinación de tres campos. Los bits de 0 a 11 son el índice de bytes. Los bits de 12 a 21 son el índice de la tabla de páginas. Los bits de 22 a 31 son el índice del directorio de páginas. Separar los campos, tiene:

0x0012F980  =  0y  00000000 00   010010 1111   1001 10000000

Esto expone las tres partes de la dirección virtual:

  • Índice del directorio de página = 0y000000000 = 0x0

  • Índice de tabla de página = 0y0100101111 = 0x12F

  • Índice de bytes = 0y100110000000 = 0x980

A continuación, necesita tres fragmentos adicionales de información para el sistema.

  • Tamaño de cada PTE. Se trata de 4 bytes en sistemas que no son PAE x86.

  • Tamaño de una página. Esto es 0x1000 bytes.

  • Dirección virtual PTE_BASE. En un sistema que no es PAE, esto es 0xC0000000.

Con estos datos, puede calcular la dirección del propio PTE:

PTE address   =   PTE_BASE  
                + (page directory index) * PAGE_SIZE
                + (page table index) * sizeof(MMPTE)
              =   0xc0000000
                + 0x0   * 0x1000
                + 0x12F * 4
              =   0xC00004BC

Esta es la dirección del PTE. El PTE es un DWORD de 32 bits. Examine su contenido:

kd> dd 0xc00004bc L1
c00004bc  09de9067

Este PTE tiene 0x09DE9067 de valor. Se compone de dos campos:

  • Los 12 bits bajos del PTE son las marcas de estado. En este caso, estas marcas son iguales a 0x067, o en binario, 0y000001100111. Para obtener una explicación de las marcas de estado, vea la página de referencia !pte .

  • Los 20 bits altos del PTE son iguales al número de marco de página (PFN) del PTE. En este caso, el PFN se 0x09DE9.

La primera dirección física de la página física es el PFN multiplicado por 0x1000 (desplazado a la izquierda 12 bits). El índice de bytes es el desplazamiento de esta página. Por lo tanto, la dirección física que busca es 0x09DE9000 + 0x980 = 0x09DE9980. Este es el mismo resultado obtenido por los métodos anteriores.