所以几年后我在这里得到了答案。
答案
在没有符号文件的情况下,这是我找到的获取崩溃可执行文件名称的最佳方法,以便可以在文件名中使用它来编写日志文件或从脚本进行崩溃转储:
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 in hex)这是必要的,因为.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
$spat
是 MASM 通配符字符串匹配函数。它将第一个参数与第二个参数中的模式匹配。它不区分大小写,因此这将匹配 NOTEPAD.EXE 以及 NotePad.eXe 等。
.if($spat("${name}","*.exe") !=0) {.echo "found it!"}
${}
${}
是别名解释器。您可以将${<alias name>}
别名值写入字符串中的任何位置。如果您在命令中使用别名,则可以直接使用它,所以.echo CrashFirstmodule
会 echo out notepad.exe
。在您实际上是指别名的名称的情况下,您可以将其指定为${/v:<alias name>}
仅解析为别名的名称。重新分配别名时,这种扩展预防是必要的。aS CrashFirstModule "${name}"
会导致将别名设置UnknownModule
为notepad.exe
,因为CrashFirstModule
在执行命令之前会扩展为它的值。
作为
aS
是分配别名的命令之一。 aS
由 ; 终止 或行尾,并将“从条目中删除。以下行将别名CrashFirstModule
为UnknownModule
:
aS ${/v:CrashFirstModule} "UnknownModule"
。休息
.break
.foreach
在找到匹配项后结束。
结尾
这就是构成我正在使用的命令的所有部分。我希望其他人从这个问题和答案中得到一些好处!