Partilhar via


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