Pergunta

Informação de fundo

Para salvar a despejos de memória, eu tenho um script passado para cdb.exe no valor Debugger da chave do Registro AeDebug:

C:\progra~1\debugg~1\cdb.exe -p %ld -e %ld -g -y SRV*c:\mss*http://msdl.microsoft.com/download/symbols -c "$<d:\tgticker\Dumps\RDFD.cdbscript"

Aqui está a primeira parte do script:

as /c CrashFirstModule .printf "%mu", @@c++((*(ntdll!_LDR_DATA_TABLE_ENTRY**)&@$peb->Ldr->InLoadOrderModuleList.Flink)->BaseDllName.Buffer) 

.logopen /t d:\tgticker\dumps\${CrashFirstModule}_process.log

* (...)

O Problema

Com símbolos, isso funciona exatamente como eu gostaria, eu recebo arquivos de log com nomes sensíveis como:

  • LHCBDRDT.exe_process_147c_2009-01-06_23-10-05-371.log

No entanto, se os símbolos não estão disponíveis, fico com um nome de arquivo de log assim:

  • ${CrashFirstModule}_process_17a8_2009-01-06_23-10-01-124.log

Isso ocorre porque o comando de alias não conseguiu definir o alias. O comando alias é um que eu colhidas a partir de DumpAnalysis.org . Este comando puxa o nome fora do cabeçalho PEB para a imagem, usando ntdll.dll. Sem símbolos para o OS, ele não sabe onde encontrar a função que ele está chamando de ntdll.dll.

A Pergunta

Alguém sabe ou tem um comando para obter o nome da imagem como um alias para uso em nomes de arquivos que ainda trabalham nestas situações?

Foi útil?

Solução

Por isso estou aqui anos depois com uma resposta.

A resposta

Na ausência de arquivos de símbolos, esta é a melhor maneira que eu encontrei para obter o nome do executável que caiu de modo que possa ser usado em um nome de arquivo para escrever um arquivo de log ou despejo de memória a partir de um script:

aS ${/v:CrashFirstModule} "UnknownModule"
.foreach /pS b /ps b (name {.imgscan}) { .if($spat("${name}","*.exe") !=0){aS ${/v:CrashFirstModule} "${name}"; .break} }

Depois destas duas linhas, CrashFirstModule será alias para qualquer um "UnknownModule" ou o nome do executável. Isso só funciona se as extremidades executáveis ??em ".exe", mas que parece razoável para mim, e funciona bem no caso em que eu estou usando. Você poderia adicionar outro .if para lidar com outra final, se você precisa para apoiar coisas como ".com".

A Resposta: Explicação

.imgscan

.imgscan dá uma lista de módulos executáveis, que irá incluir .exe, .dll .drv etc. Este é o ponto de partida para encontrar o nome do executável.

0:000> .imgscan
MZ at 01000000, prot 00000002, type 01000000 - size 14000
  Name: notepad.exe
MZ at 73070000, prot 00000002, type 01000000 - size 27000
  Name: WINSPOOL.DRV
MZ at 762b0000, prot 00000002, type 01000000 - size 49000
  Name: comdlg32.dll
MZ at 76f50000, prot 00000002, type 01000000 - size 13000
  Name: Secur32.dll
MZ at 77380000, prot 00000002, type 01000000 - size 91000
  Name: USER32.dll
MZ at 77420000, prot 00000002, type 01000000 - size 103000
  Name: COMCTL32.dll
MZ at 77ba0000, prot 00000002, type 01000000 - size 5a000
  Name: msvcrt.dll
MZ at 77c00000, prot 00000002, type 01000000 - size 48000
  Name: GDI32.dll
MZ at 77c50000, prot 00000002, type 01000000 - size a0000
  Name: RPCRT4.dll
MZ at 77e40000, prot 00000002, type 01000000 - size 102000
  Name: KERNEL32.dll
MZ at 7c800000, prot 00000002, type 01000000 - size c3000
  Name: ntdll.dll
MZ at 7c8d0000, prot 00000002, type 01000000 - size 7ff000
  Name: SHELL32.dll
MZ at 7d180000, prot 00000002, type 01000000 - size 52000
  Name: SHLWAPI.dll
MZ at 7d1e0000, prot 00000002, type 01000000 - size 9c000
  Name: ADVAPI32.dll

.foreach

.foreach é usado para percorrer a lista de imagens. Especifica /pS o quão longe no a lista o primeiro valor é. especifica /ps a distância entre os valores. (B = 11 em hexadecimal) Isto é necessário porque .foreach irá separar em espaços. Com estes argumentos, a lista torna-se:

0:000> .foreach /pS b /ps b (name {.imgscan}) { .echo name }
notepad.exe
WINSPOOL.DRV
comdlg32.dll
Secur32.dll
USER32.dll
COMCTL32.dll
msvcrt.dll
GDI32.dll
RPCRT4.dll
KERNEL32.dll
ntdll.dll
SHELL32.dll
SHLWAPI.dll
ADVAPI32.dll

$ cuspiu

$spat é a função de string match MASM curinga. Ele vai coincidir com o primeiro argumento contra o padrão no segundo argumento. Não é caso sensível, então isso vai corresponder NOTEPAD.EXE, bem como o Notepad.exe, etc.

.if($spat("${name}","*.exe") !=0) {.echo "found it!"}

$ {}

${} é o intérprete alias. Você incorpora ${<alias name>} onde quer que você deseja que o valor do seu alias escritos em uma string. se você estiver usando o alias em um comando, você pode simplesmente usá-lo, então .echo CrashFirstmodule ecoaria fora notepad.exe. Nos casos em que você realmente quer dizer o nome do alias, você pode especificá-lo como ${/v:<alias name>} que só vai resolver para o nome de alias. Esta prevenção expansão é necessária quando a reatribuição um alias. aS CrashFirstModule "${name}" teria resultado na criação do UnknownModule alias para notepad.exe, como CrashFirstModule teria sido expandida para o seu valor antes que o comando foi executado.

AS

aS é um dos comandos a aliases atribuir. aS é terminada por; ou a extremidade da linha e irá retirar o "a partir da entrada A seguir linha vontade aliás CrashFirstModule para UnknownModule:.

aS ${/v:CrashFirstModule} "UnknownModule"

.BREAK

.break termina a .foreach após uma correspondência for encontrada.

Fim

Isso é todas as peças que compõem o comando que estou usando. Espero que alguém recebe algum benefício a partir desta pergunta e resposta!

Outras dicas

por que não usar informações peb? Abaixo está o que você precisa:

?? @$peb->ProcessParameters

ntdll.dll estará presente em todo processo, então eu estou supondo que o problema é símbolo de carregamento.

De qualquer forma, isso deve funcionar para se livrar da quebra de linha:

.foreach(Module {lm 1m}) { aS CrashApp Module; .break }

.foreach(Module {lm 1m a $exentry}) { aS CrashApp Module }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top