Debugging Tools for Windows

!for_each_module

!for_each_module 扩展对每个已加载模块执行指定的调试器命令一次。

语法

!for_each_module ["CommandString"
!for_each_module -? 

参数

CommandString
指定要为调试器的模块列表中每个模块执行一次的调试器命令。如果CommandString包含多条命令,必须用分号分隔它们,并且将整个CommandString 包含在引号中。如果有多条命令,则CommandString 中的每一条命令都不能使用引号。

CommandStringCommandString 的命令执行的任何脚本中,都可以使用以下这些别名。

别名 数据类型
@#FileVersion string 模块的文件版本。
@#ProductVersion string 模块的产品版本。
@#ModuleIndex ULONG 模块号。模块是从0开始连续的枚举的。
@#ModuleName string 模块名。这个名字一般是不带扩展名的文件名。某些情况下,模块名和文件名会有显著不同。更多信息,查看可执行映像路径
@#ImageName string 可执行文件的名字,包含扩展名。一般来说,用户模式下会包含全路径,而内核模式不会。
@#LoadedImageName string 如果不存在Microsoft CodeView符号,该别名和映像名一样。
@#MappedImageName string 大多数情况下该别名为NULL。如果调试器映射了映像文件(例如调试minidump时),该别名是被映射的映像名。
@#SymbolFileName string 符号文件的路径和名字。如果没有加载任何符号,该别名是可执行文件的名字。
@#ModuleNameSize ULONG 模块名字符串的长度加1。
@#ImageNameSize ULONG 映像名字符串的长度加1。
@#LoadedImageNameSize ULONG 已加载映像名的字符串长度加1。
@#MappedImageNameSize ULONG 已映射的映像名的字符串长度加1。
@#SymbolFileNameSize ULONG 符号文件名字符串长度加1。
@#Base ULONG64 映像开始位置的地址。
@#Size ULONG 映像大小,以字节为单位。
@#End ULONG64 映像的结束地址。
@#TimeDateStamp ULONG 映像的时间和日期。如果要将该时间和日期展开为可读的形式,需要使用.formats (Show Number Formats)命令。
@#Checksum ULONG 模块的校验和。
@#Flags ULONG 模块的标志。DEBUG_MODULE_Xxx 值的列表,参见Dbgeng.h
@#SymbolType USHORT 符号类型。DEBUG_SYMTYPE_Xxx 的值的列表,参见Dbgeng.h

这些别名都在每个模块执行CommandString 之前以及进行任何其他的分析之前被替换。它们是区分大小写的。别名前后都必须加上空格,即使使用括号括起来。如果使用C++表达式语法,必须以@@( @#alias )的形式来使用。

这些别名仅在!for_each_module 的生命周期中可用。不要将它们和伪寄存器、预定义别名或自定义别名混淆。

-?
调试器命令窗口中显示该扩展命令的帮助。

DLL

Windows 2000 Ext.dll
Windows XP和之后 Ext.dll

注释

如果未指定任何参数,!for_each_module显示所有已加载模块的信息。该信息和使用下面命令的输出类似。

!for_each_module .echo @#ModuleIndex : @#Base @#End @#ModuleName @#ImageName  @#LoadedImageName

查看已加载和已卸载模块的更多信息,可以使用lm (List Loaded Modules)命令。

如果启用了详细的调试器输出,则调用该扩展命令时还会显示已加载和已卸载模块的总数,并且针对每个模块的CommandString命令执行前会显示详细信息(包括每个可用的别名的值) 。

下面是如何使用!for_each_module的例子。这个命令显示全局调试标志。

!for_each_module x ${@#ModuleName}!*Debug*Flag*
!for_each_module x ${@#ModuleName}!g*Debug*

下面的命令使用!chkimg检查每个模块是否被修改过了:

!for_each_module !chkimg @#ModuleName

下面的命令再每个已加载模块中搜索"MZ"。

!for_each_module s-a @#Base @#End "MZ"

下面的例子演示了对每个模块名使用@#FileVersion@#ProductVersion:

0:000> !for_each_module .echo @#ModuleName fver = @#FileVersion pver = @#ProductVersion 
USER32 fver = 6.0.6000.16438 (vista_gdr.070214-1610) pver = 6.0.6000.16438
kernel32 fver = 6.0.6000.16386 (vista_rtm.061101-2205) pver = 6.0.6000.16386
ntdll fver = 6.0.6000.16386 (vista_rtm.061101-2205) pver = 6.0.6000.16386
notepad fver = 6.0.6000.16386 (vista_rtm.061101-2205) pver = 6.0.6000.16386
WINSPOOL fver = 6.0.6000.16386 (vista_rtm.061101-2205) pver = 6.0.6000.16386
COMCTL32 fver = 6.10 (vista_rtm.061101-2205) pver = 6.0.6000.16386
SHLWAPI fver = 6.0.6000.16386 (vista_rtm.061101-2205) pver = 6.0.6000.16386
msvcrt fver = 7.0.6000.16386 (vista_rtm.061101-2205) pver = 7.0.6000.16386
GDI32 fver = 6.0.6000.16386 (vista_rtm.061101-2205) pver = 6.0.6000.16386
RPCRT4 fver = 6.0.6000.16525 (vista_gdr.070716-1600) pver = 6.0.6000.16525
SHELL32 fver = 6.0.6000.16513 (vista_gdr.070626-1505) pver = 6.0.6000.16513
ole32 fver = 6.0.6000.16386 (vista_rtm.061101-2205) pver = 6.0.6000.16386
ADVAPI32 fver = 6.0.6000.16386 (vista_rtm.061101-2205) pver = 6.0.6000.16386
COMDLG32 fver = 6.0.6000.16386 (vista_rtm.061101-2205) pver = 6.0.6000.16386

附加信息

关于如何定义和使用别名来作为输入字符串的快捷方式 (包括 ${ } 标记的使用)的更多信息,查看使用别名

Build machine: CAPEBUILD