Mapeando símbolos quando o PEB é paginado
Para carregar símbolos, o depurador examina a lista de módulos carregados pelo sistema operacional. O ponteiro para a lista de módulos do modo de usuário é um dos itens armazenados no PEB (bloco de ambiente de processo).
Para recuperar a memória, o Gerenciador de Memória pode exibir dados do modo de usuário para liberar espaço para outros componentes do processo ou do modo kernel. Os dados do modo de usuário que são paginado podem incluir a estrutura de dados PEB. Sem essa estrutura de dados, o depurador não pode determinar para quais imagens carregar símbolos.
Nota Isso afeta os arquivos de símbolo somente para os módulos do modo de usuário. Os módulos e símbolos do modo kernel não são afetados, pois são rastreados em uma lista diferente.
Suponha que um módulo de modo de usuário seja mapeado para o processo atual e você queira corrigir os símbolos para ele. Encontre qualquer endereço no intervalo de endereços virtuais do módulo. Por exemplo, suponha que um módulo seja mapeado para um intervalo de endereços virtuais que contém o endereço 7f78e9e000F. Insira o comando a seguir.
3: kd> !vad 7f78e9e000F 1
A saída do comando exibe informações sobre o VAD (descritor de endereço virtual) do módulo. A saída do comando também inclui uma cadeia de caracteres de comando Recarregar que você pode usar para carregar os símbolos do módulo. A cadeia de caracteres de comando Recarregar inclui o endereço inicial (000007f7'8e9e0000) e o tamanho (32000) do módulo do bloco de notas.
VAD @ fffffa80056fb960
...
Reload command: .reload notepad.exe=000007f7`8e9e0000,32000
Para carregar os símbolos, insira o comando que foi fornecido na cadeia de caracteres de comando Recarregar.
.reload notepad.exe=000007f7`8e9e0000,32000
Aqui está outro exemplo que usa uma técnica ligeiramente diferente. O exemplo demonstra como usar a extensão !vad para mapear símbolos quando o PEB é paginado. A ideia básica é localizar o endereço inicial e o tamanho da DLL relevante para que você possa usar o comando .reload para carregar os símbolos necessários. Suponha que o endereço do processo atual seja 0xE0000126'01BA0AF0 e você queira corrigir os símbolos para ele. Primeiro, use o comando !process para obter o endereço raiz do descritor de endereço virtual (VAD):
kd> !process e000012601ba0af0 1
PROCESS e000012601ba0af0
SessionId: 2 Cid: 0b50 Peb: 6fbfffde000 ParentCid: 0efc
DirBase: 079e8461 ObjectTable: e000000600fbceb0 HandleCount: 360.
Image: explorer.exe
VadRoot e000012601a35e70 Vads 201 Clone 0 Private 917. Modified 2198. Locked 0.
...
Em seguida, use a extensão !vad para listar a árvore VAD associada ao processo. Esses VADs rotulados como "EXECUTE_WRITECOPY" pertencem a módulos de código.
kd> !vad e000012601a35e70
VAD level start end commit
...
e0000126019f9790 ( 6) 3fff0 3fff7 -1 Private READONLY
e000012601be1080 ( 7) 37d9bd30 37d9bd3e 2 Mapped Exe EXECUTE_WRITECOPY <-- these are DLLs
e000012600acd970 ( 5) 37d9bec0 37d9bece 2 Mapped Exe EXECUTE_WRITECOPY
e000012601a5cba0 ( 7) 37d9c910 37d9c924 2 Mapped Exe EXECUTE_WRITECOPY
...
Em seguida, use a extensão !vad novamente para localizar o endereço inicial e o tamanho da memória paginada que contém a DLL de interesse. Isso confirma que você encontrou a DLL correta:
kd> !vad e000012601be1080 1
VAD @ e000012601be1080
Start VPN: 37d9bd30 End VPN: 37d9bd3e Control Area: e00001260197b8d0
First ProtoPte: e0000006013e00a0 Last PTE fffffffffffffffc Commit Charge 2 (2.)
Secured.Flink 0 Blink 0 Banked/Extend: 0
File Offset 0
ImageMap ViewShare EXECUTE_WRITECOPY
...
File: \Windows\System32\ExplorerFrame.dll
O campo "Iniciar VPN" – nesse caso, 0x37D9BD30 – indica o número da página virtual inicial. Isso deve ser convertido em um endereço real multiplicando-o pelo tamanho da página. Você pode usar o ? (Avaliar expressão) para multiplicar esse valor por 0x2000, que é o tamanho da página do computador baseado em Itanium do qual o exemplo vem.
kd> ? 37d9bd3e*2000
Evaluate expression: 7676040298496 = 000006fb`37a7c000
Em seguida, o tamanho do intervalo pode ser convertido em bytes:
kd> ? 37d9bd3e-37d9bd30+1 <-- computes the number of pages
Evaluate expression: 15 = 00000000`0000000f
kd> ? f*2000
Evaluate expression: 122880 = 00000000`0001e000
Portanto, ExplorerFrame.dll começa no endereço 0x000006Fb'37A7C000 e é 0x1E000 bytes grandes. Você pode carregar seus símbolos com:
kd> .reload /f ExplorerFrame.dll=6fb`37a7c000,1e000