Convertendo endereços virtuais em endereços físicos
A maioria dos comandos do depurador usa endereços virtuais, não endereços físicos, como entrada e saída. No entanto, há momentos em que ter o endereço físico pode ser útil.
Há duas maneiras de converter um endereço virtual em um endereço físico: usando a extensão !vtop e usando a extensão !pte .
Para obter uma visão geral do endereço virtual no Windows, consulte Espaços de endereço virtuais.
Conversão de endereço usando !vtop
Suponha que você esteja depurando um computador de destino no qual o processo de MyApp.exe está em execução e queira investigar o endereço virtual 0x0012F980. Este é o procedimento que você usaria com a extensão !vtop para determinar o endereço físico correspondente.
Convertendo um endereço virtual em um endereço físico usando !vtop
Verifique se você está trabalhando em hexadecimal. Se necessário, defina a base atual com o comando N 16 .
Determine o índice de bytes do endereço. Esse número é igual aos 12 bits mais baixos do endereço virtual. Portanto, o endereço virtual 0x0012F980 tem um índice de bytes de 0x980.
Determine a base de diretório do endereço usando a extensão !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 o número do quadro de página da base do diretório. Essa é simplesmente a base de diretório sem os três zeros hexadecimais à direita. Neste exemplo, a base de diretório é 0x098FD000, portanto, o número do quadro de página é 0x098FD.
Use a extensão !vtop . O primeiro parâmetro dessa extensão deve ser o número do quadro de página. O segundo parâmetro de !vtop deve ser o endereço virtual em questão:
kd> !vtop 98fd 12f980 Pdi 0 Pti 12f 0012f980 09de9000 pfn(09de9)
O segundo número mostrado na linha final é o endereço físico do início da página física.
Adicione o índice de bytes ao endereço do início da página: 0x09DE9000 + 0x980 = 0x09DE9980. Esse é o endereço físico desejado.
Você pode verificar se essa computação foi feita corretamente exibindo a memória em cada endereço. A extensão !d\* exibe memória em um endereço físico especificado:
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 .....
O comando d* (Exibir Memória) usa um endereço 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 .....
Como os resultados são os mesmos, isso indica que o endereço físico 0x09DE9980 realmente corresponde ao endereço virtual 0x0012F980.
Conversão de endereço usando !pte
Novamente, suponha que você esteja investigando o endereço virtual 0x0012F980 pertencente ao processo de MyApp.exe. Este é o procedimento que você usaria com a extensão !pte para determinar o endereço físico correspondente:
Convertendo um endereço virtual em um endereço físico usando !pte
Verifique se você está trabalhando em hexadecimal. Se necessário, defina a base atual com o comando N 16 .
Determine o índice de bytes do endereço. Esse número é igual aos 12 bits mais baixos do endereço virtual. Portanto, o endereço virtual 0x0012F980 tem um índice de bytes de 0x980.
Defina o contexto do processo para o processo desejado:
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 a extensão !pte com o endereço virtual como seu argumento. Isso exibe informações em duas colunas. A coluna à esquerda descreve a PDE (entrada de diretório de página) para esse endereço; a coluna à direita descreve sua PTE (entrada de tabela de página):
kd> !pte 12f980 VA 0012f980 PDE at C0300000 PTE at C00004BC contains 0BA58067 contains 09DE9067 pfn ba58 ---DA--UWV pfn 9de9 ---DA--UWV
Examine a última linha da coluna à direita. A notação "pfn 9de9" é exibida. O número 0x9DE9 é o PFN ( número de quadro de página ) desse PTE. Multiplique o número do quadro de página por 0x1000 (por exemplo, desloque-o para a esquerda 12 bits). O resultado, 0x09DE9000, é o endereço físico do início da página.
Adicione o índice de bytes ao endereço do início da página: 0x09DE9000 + 0x980 = 0x09DE9980. Esse é o endereço físico desejado.
Esse é o mesmo resultado obtido pelo método anterior.
Convertendo endereços manualmente
Embora as extensões !ptov e pte forneçam a maneira mais rápida de converter endereços virtuais em endereços físicos, essa conversão também pode ser feita manualmente. Uma descrição desse processo lançará luz sobre alguns dos detalhes da arquitetura de memória virtual.
As estruturas de memória variam de tamanho, dependendo do processador e da configuração de hardware. Este exemplo é obtido de um sistema x86 que não tem a PAE (Extensão de Endereço Físico) habilitada.
Usando 0x0012F980 novamente como o endereço virtual, primeiro você precisa convertê-lo em binário, manualmente ou usando o 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
Esse endereço virtual é uma combinação de três campos. Os bits de 0 a 11 são o índice de bytes. Os bits 12 a 21 são o índice da tabela de páginas. Os bits de 22 a 31 são o índice de diretório de página. Separando os campos, você tem:
0x0012F980 = 0y 00000000 00 010010 1111 1001 10000000
Isso expõe as três partes do endereço virtual:
Índice de diretório de página = 0y0000000000 = 0x0
Índice da tabela de página = 0y0100101111 = 0x12F
Índice de bytes = 0y100110000000 = 0x980
Em seguida, você precisa de três informações adicionais para seu sistema.
O tamanho de cada PTE. São 4 bytes em sistemas não PAE x86.
O tamanho de uma página. Isso é 0x1000 bytes.
O PTE_BASE endereço virtual. Em um sistema não PAE, isso é 0xC0000000.
Usando esses dados, você pode calcular o endereço do próprio PTE:
PTE address = PTE_BASE
+ (page directory index) * PAGE_SIZE
+ (page table index) * sizeof(MMPTE)
= 0xc0000000
+ 0x0 * 0x1000
+ 0x12F * 4
= 0xC00004BC
Esse é o endereço da PTE. O PTE é um DWORD de 32 bits. Examine seu conteúdo:
kd> dd 0xc00004bc L1
c00004bc 09de9067
Essa PTE tem valor 0x09DE9067. Ele é feito de dois campos:
Os 12 bits baixos do PTE são os sinalizadores status. Nesse caso, esses sinalizadores são iguais 0x067 ou, em binário, 0y000001100111. Para obter uma explicação dos sinalizadores de status, consulte a página de referência !pte.
Os 20 bits altos do PTE são iguais ao PFN ( número de quadro de página ) do PTE. Nesse caso, o PFN é 0x09DE9.
O primeiro endereço físico na página física é o PFN multiplicado por 0x1000 (deslocado para a esquerda 12 bits). O índice de bytes é o deslocamento nesta página. Portanto, o endereço físico que você está procurando é 0x09DE9000 + 0x980 = 0x09DE9980. Esse é o mesmo resultado obtido pelos métodos anteriores.