Exemplos adicionais de DBH
Aqui estão exemplos adicionais de comandos que podem ser emitidos no prompt DBH.
Exibindo símbolos privados e símbolos públicos
Se o destino for um arquivo de símbolo completo, cada símbolo público aparecerá duas vezes no arquivo: na tabela de símbolos públicos e nos dados de símbolos privados. A cópia na tabela de símbolos públicos geralmente contém várias decorações (prefixos e sufixos). Para obter detalhes, consulte Símbolos públicos e privados.
O DBH pode exibir informações sobre este símbolo a partir dos dados do símbolo privado, da tabela de símbolos públicos sem decorações e da tabela de símbolos públicos com decorações. Aqui está um exemplo em que todos os três são exibidos, usando o comando addr 414fe0 cada vez.
Na primeira vez que esse comando aparece neste exemplo, o DBH usa as opções de símbolo padrão, portanto, as informações resultantes vêm dos dados de símbolo privado. Observe que essas informações incluem o endereço, o tamanho e o tipo de dados da função fgets. Em seguida, o comando symopt +4000 é usado, que ativa a opção SYMOPT_PUBLICS_ONLY. Isso faz com que o DBH ignore os dados de símbolo privado e, portanto, quando o comando addr 414fe0 é executado pela segunda vez, o DBH usa a tabela de símbolos públicos e nenhuma informação de tamanho ou tipo de dados é mostrada para a função fgets. Finalmente, o comando symopt -2 é usado, desativando a opção SYMOPT_UNDNAME e fazendo com que o DBH inclua decorações. Quando o addr 414fe0 é executado desta última vez, ele mostra a versão decorada do nome da função, _fgets.
pid:4308 mod:TimeTest[400000]: addr 414fe0
fgets
name : fgets
addr : 414fe0
size : 113
flags : 0
type : 7e
modbase : 400000
value : 0
reg : 0
scope : SymTagNull (0)
tag : SymTagFunction (5)
index : 7d
pid:4308 mod:TimeTest[400000]: symopt +4000
Symbol Options: 0x10c13
Symbol Options: 0x14c13
pid:4308 mod:TimeTest[400000]: addr 414fe0
fgets
name : fgets
addr : 414fe0
size : 0
flags : 0
type : 0
modbase : 400000
value : 0
reg : 0
scope : SymTagNull (0)
tag : SymTagPublicSymbol (a)
index : 7f
pid:4308 mod:TimeTest[400000]: symopt -2
Symbol Options: 0x14c13
Symbol Options: 0x14c11
pid:4308 mod:TimeTest[400000]: addr 414fe0
_fgets
name : _fgets
addr : 414fe0
size : 0
flags : 0
type : 0
modbase : 400000
value : 0
reg : 0
scope : SymTagNull (0)
tag : SymTagPublicSymbol (a)
index : 7f
Se a opção de linha de comando -d tivesse sido usada, os resultados teriam mostrado o nome público decorado desde o início.
Determinando as decorações de um símbolo específico
DBH pode determinar as decorações em um símbolo específico. Isso pode ser útil quando usado em conjunto com um programa que requer símbolos a serem especificados com suas decorações, como PDBCopy.
Por exemplo, suponha que você saiba que o arquivo de símbolo mysymbols.pdb contém um símbolo cujo nome não decorado é MyFunction1. Para localizar o nome decorado, use o procedimento a seguir.
Primeiro, inicie o DBH sem a opção de linha de comando -d e, em seguida, use o comando symopt +4000 para que todas as informações venham da tabela de símbolos públicos:
C:\> dbh c:\mydir\mysymbols.pdb
mysymbols [1000000]: symopt +4000
Symbol Options: 0x10c13
Symbol Options: 0x14c13
Em seguida, use o comando name ou o comando enum para exibir o endereço do símbolo desejado:
mysymbols [1000000]: enum myfunction1
index address name
2ab 102cb4e : MyFunction1
Agora use symopt -2 para tornar as decorações de símbolos visíveis e, em seguida, use o comando addr com o endereço deste símbolo:
mysymbols [1000000]: symopt -2
Symbol Options: 0x14c13
Symbol Options: 0x14c11
mysymbols [1000000]: addr 102cb4e
_MyFunction1@4
name : _InterlockedIncrement@4
addr : 102cb4e
size : 0
flags : 0
type : 0
modbase : 1000000
value : 0
reg : 0
scope : SymTagNull (0)
tag : SymTagPublicSymbol (a)
index : 2ab
Isso revela que o nome decorado do símbolo é _MyFunction1@4.
Decodificação de decorações de símbolos
O comando undec pode ser usado para revelar o significado das decorações de símbolos C++. No exemplo a seguir, as decorações anexadas a ?? _C@_03GGCAPAJC@Sep?$AA@ são decodificados para indicar que é uma cadeia de caracteres:
dbh: undec ??_C@_03GGCAPAJC@Sep?$AA@
??_C@_03GGCAPAJC@Sep?$AA@ =
`string'
Os exemplos a seguir decodificam as decorações anexadas a três nomes de função, revelando seus protótipos:
dbh: undec ?gcontext@@3_KA
?gcontext@@3_KA =
unsigned __int64 gcontext
dbh: undec ?pathcpy@@YGXPAGPBG1K@Z
?pathcpy@@YGXPAGPBG1K@Z =
void __stdcall pathcpy(unsigned short *,unsigned short const *,unsigned short const *,unsigned long)
dbh: undec ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z
?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z =
int (__cdecl*__cdecl _set_new_handler(int (__cdecl*)(unsigned int)))(unsigned int)
O comando undec não exibe informações sobre sublinhados iniciais, o prefixo __imp_ ou decorações de "@endereço" à direita, que são comumente encontradas anexadas a nomes de função.
Você pode usar o comando undec com qualquer cadeia de caracteres, não apenas o nome de um símbolo no módulo carregado no momento.
Classificando uma lista de símbolos por endereço
Se você simplesmente quiser uma lista de símbolos, classificados em ordem de endereço, você pode executar DBH no modo de lote e canalizar os resultados para um comando de classificação . Os valores de endereço normalmente começam na 18ª coluna de cada linha, portanto, o comando a seguir classifica os resultados por endereço:
dbh -p:4672 enum mymodule!* | sort /+18
Exibindo informações de linha de origem
Quando você usa um arquivo de símbolo completo, o DBH pode exibir informações da linha de origem. Isso não requer acesso a nenhum arquivo de origem, uma vez que essas informações são armazenadas nos próprios arquivos de símbolo.
Aqui, o comando line exibe o endereço hexadecimal das instruções binárias correspondentes à linha de origem especificada e exibe os símbolos associados a essa linha. (Neste exemplo, não há símbolos associados à linha.)
dbh [1000000]: line myprogram.cpp#767
file : e:\mydirectory\src\myprogram.cpp
line : 767
addr : 1006191
key : 0000000000000000
disp : 0
Aqui, o comando srclines exibe os arquivos de objeto associados à linha de origem especificada:
dbh [1000000]: srclines myprogram.cpp 767
0x1006191: e:\mydirectory\objchk\amd64\myprogram.obj
line 767 e:\mydirectory\src\myprogram.cpp
Observe que a saída de srclines é semelhante à do comando depurador ln (List Nearest Symbols).
Exibindo um tipo de dados
O comando type pode ser usado para exibir informações sobre um tipo de dados. Aqui ele exibe dados sobre o tipo CMDPROC:
dbh [1000000]: type CMDPROC
name : CMDPROC
addr : 0
size : 8
flags : 0
type : c
modbase : 1000000
value : 0
reg : 0
scope : SymTagNull (0)
tag : SymTagTypedef (11)
index : c
O valor listado após "tag" especifica a natureza desse tipo de dados. Nesse caso, SymTagTypedef indica que esse tipo foi definido usando uma instrução typedef .
Usando símbolos imaginários
O comando add pode adicionar um símbolo imaginário ao módulo carregado. O arquivo de símbolo real não é alterado; apenas a imagem desse arquivo na memória do DBH é alterada.
O comando add pode ser útil se você desejar substituir temporariamente quais símbolos estão associados a um determinado intervalo de endereços. No exemplo a seguir, uma parte do intervalo de endereços associado a MyModule!main é substituída pelo símbolo imaginário MyModule!magic.
Aqui está como o módulo aparece antes que o símbolo imaginário seja adicionado. Observe que a função principal começa em 0x0042CC56 e tem tamanho 0x42B. Assim, quando o comando addr é usado com o endereço 0x0042CD10, ele reconhece esse endereço como estando dentro dos limites da função principal :
pid:6040 mod:MyModule[400000]: enum timetest!ma*
index address name
1 42cc56 : main
3 415810 : malloc
5 415450 : mainCRTStartup
pid:6040 mod:MyModule[400000]: addr 42cc56
main
name : main
addr : 42cc56
size : 42b
flags : 0
type : 2
modbase : 400000
value : 0
reg : 0
scope : SymTagNull (0)
tag : SymTagFunction (5)
index : 1
pid:6040 mod:MyModule[400000]: addr 42cd10
main+ba
name : main
addr : 42cc56
size : 42b
flags : 0
type : 2
modbase : 400000
value : 0
reg : 0
scope : SymTagNull (0)
tag : SymTagFunction (5)
index : 1
Agora, a magia do símbolo é adicionada no endereço 0x0042CD00, com tamanho 0x10 bytes. Quando o comando enum é usado, o bit alto no índice é definido, mostrando que este é um símbolo imaginário:
pid:6040 mod:MyModule[400000]: add magic 42cd00 10
pid:6040 mod:MyModule[400000]: enum timetest!ma*
index address name
1 42cc56 : main
3 415810 : malloc
5 415450 : mainCRTStartup
80000001 42cd00 : magic
Quando o comando addr é usado, ele procura quaisquer símbolos cujos intervalos incluam o endereço especificado. Como essa pesquisa começa com o endereço especificado e é executada para trás, o endereço 0x004CD10 agora está associado à magia. Por outro lado, o endereço 0x004CD40 ainda está associado ao principal, porque está fora do alcance do símbolo mágico . Observe também que a tag SymTagCustom indica um símbolo imaginário:
pid:6040 mod:MyModule[400000]: addr 42cd10
magic+10
name : magic
addr : 42cd00
size : 10
flags : 1000
type : 0
modbase : 400000
value : 0
reg : 0
scope : SymTagNull (0)
tag : SymTagCustom (1a)
index : 80000001
pid:6040 mod:MyModule[400000]: addr 42cd40
main+ea
name : main
addr : 42cc56
size : 42b
flags : 0
type : 2
modbase : 400000
value : 0
reg : 0
scope : SymTagNull (0)
tag : SymTagFunction (5)
index : 1
Finalmente, o comando del pode excluir a magia do símbolo, retornando todos os símbolos aos seus intervalos originais:
pid:6040 mod:MyModule[400000]: del magic
pid:6040 mod:MyModule[400000]: enum timetest!ma*
index address name
1 42cc56 : main
3 415810 : malloc
5 415450 : mainCRTStartup