Как лучше псевдоним имени исполняемого файла в сценарии сбоя WinDBG? - PullRequest
2 голосов
/ 07 января 2009

Справочная информация

Для сохранения аварийных дампов у меня есть скрипт, переданный cdb.exe в значении Debugger раздела реестра 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"

Вот первая часть скрипта:

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

* (...)

Проблема

С символами это работает именно так, как мне хотелось бы, я получаю файлы журналов с понятными именами, такими как:

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

Однако, если символы недоступны, я получаю имя файла журнала, например:

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

Это потому, что команда псевдонима не смогла установить псевдоним. Команду псевдонимов я получил с DumpAnalysis.org . Эта команда извлекает имя из заголовка PEB для изображения, используя ntdll.dll. Без символов для ОС она не знает, где найти функцию, которую она вызывает из ntdll.dll.

Вопрос

Кто-нибудь знает или имеет команду получить имя изображения в качестве псевдонима для использования в именах файлов, которые все еще будут работать в этих ситуациях?

Ответы [ 3 ]

3 голосов
/ 25 октября 2011

Итак, вот я через годы с ответом.

Ответ

При отсутствии файлов символов это лучший способ, который я нашел, чтобы получить имя исполняемого файла, потерпевшего крах, чтобы его можно было использовать в имени файла для записи файла журнала или аварийного дампа из сценария:

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

После этих двух строк, CrashFirstModule будет иметь псевдоним либо "UnknownModule", либо имя исполняемого файла. Это работает только в том случае, если исполняемый файл оканчивается на «.exe», но это кажется мне разумным, и прекрасно работает в случае, когда я его использую. Вы можете добавить еще один .if для обработки другого конца, если вам нужно поддерживать такие вещи, как ".com".

Ответ: Объяснено

.imgscan

.imgscan дает список исполняемых модулей, который будет включать в себя .exe, .dll, .drv и т. Д. Это отправная точка для поиска имени исполняемого файла.

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 используется для просмотра списка изображений. /pS указывает, насколько далеко в списке находится первое значение. /ps указывает расстояние между значениями. (b = 11 в шестнадцатеричном виде) Это необходимо, так как .foreach будет разделяться пробелами. С этими аргументами список становится:

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

$ сплюнул

$spat - это функция сопоставления подстановочных знаков MASM. Он будет сопоставлять первый аргумент с шаблоном во втором аргументе. Он не чувствителен к регистру, поэтому он будет соответствовать NOTEPAD.EXE, а также NotePad.eXe и т. Д.

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

$ {}

${} - интерпретатор псевдонимов. Вы вставляете ${<alias name>} везде, где хотите, чтобы значение вашего псевдонима было записано в строке. если вы используете псевдоним в команде, вы можете просто использовать его, поэтому .echo CrashFirstmodule отобразит notepad.exe. В тех случаях, когда вы на самом деле имеете в виду имя псевдонима, вы можете указать его как ${/v:<alias name>}, который будет просто преобразован в имя псевдонима. Это предотвращение расширения необходимо при переназначении псевдонима. aS CrashFirstModule "${name}" привело бы к установке псевдонима UnknownModule в notepad.exe, так как CrashFirstModule был бы расширен до его значения до выполнения команды.

1048 звездочками * aS является одной из команд для назначения псевдонимов. aS завершается; или конец строки и будет лишать "от записи. Следующая строка будет псевдоним от CrashFirstModule до UnknownModule: aS ${/v:CrashFirstModule} "UnknownModule" .BREAK

.break заканчивает .foreach после того, как совпадение найдено.

Конец

Это все части, которые составляют команду, которую я использую. Я надеюсь, что кто-то еще получит некоторую пользу от этого вопроса и ответа!

1 голос
/ 08 марта 2019

почему бы не использовать информацию о колышках? Ниже то, что вам нужно:

?? @$peb->ProcessParameters
0 голосов
/ 27 апреля 2009

ntdll.dll будет присутствовать в каждом процессе, поэтому я предполагаю, что проблема заключается в загрузке символов.

В любом случае, это должно сработать, чтобы избавиться от разрыва строки:

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

.foreach(Module {lm 1m a $exentry}) { aS CrashApp Module }
...