Как лучше всего использовать псевдоним для имени исполняемого файла в сценарии сбоя WinDBG?

StackOverflow https://stackoverflow.com/questions/420442

Вопрос

Исходная информация

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

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

Вопрос

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

Это было полезно?

Решение

И вот спустя годы я получил ответ.

Ответ

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

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 используется для перемещения по списку изображений. /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 было бы расширено до его значения до выполнения команды.

как

aS — одна из команд для назначения псевдонимов. aS завершается ;или конец строки и удалит " из записи.Следующая строка будет псевдонимом CrashFirstModule к UnknownModule:

aS ${/v:CrashFirstModule} "UnknownModule"

.перерыв

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

Конец

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

Другие советы

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

?? @$peb->ProcessParameters

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

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

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

.foreach(Module {lm 1m a $exentry}) { aS CrashApp Module }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top