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
Asegúrese de que está trabajando en hexadecimal. Si es necesario, establezca la base actual con el comando N 16 .
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.
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
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.
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.
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
Asegúrese de que está trabajando en hexadecimal. Si es necesario, establezca la base actual con el comando N 16 .
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.
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
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
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.
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.