Dump文件数据存储格式(二)
四、系统信息流
流目录后面紧接着就是流数据了。第一个流数据就是系统信息流。
可知,这个流的起始于文件偏移0xEC,大小是0x38,也就是56个字节。
从上图可知,系统信息流就是紧挨着流目录尾部。这个流包含了如下操作系统和处理器信息:处理器架构、级别、版本,CPU信息等。数据结构如下:
typedef struct_MINIDUMP_SYSTEM_INFO {
USHORT ProcessorArchitecture;
USHORT ProcessorLevel;
USHORT ProcessorRevision;
union {
USHORT Reserved0;struct{
UCHAR NumberOfProcessors;
UCHAR ProductType;
};
};
ULONG32 MajorVersion;
ULONG32 MinorVersion;
ULONG32 BuildNumber;
ULONG32 PlatformId;
RVA CSDVersionRva;
union {
ULONG32 Reserved1;struct{
USHORT SuiteMask;
USHORT Reserved2;
};
};
CPU_INFORMATION Cpu;
} MINIDUMP_SYSTEM_INFO,*PMINIDUMP_SYSTEM_INFO;
Dump文件数据存储格式(三)
五、杂项信息流(MiscInfoStream
)
在系统信息流后紧挨着的就是杂项信息流。而系统信息流信息如下
0xEC+0n56=0x124
而杂项信息流如下:
可知偏移是0x124,即证明杂项信息流是紧挨着系统信息流,大小有1364字节。
MiscInfoStream
包含各种信息。数据结构如下:
typedef struct_MINIDUMP_MISC_INFO_5 {
ULONG32 SizeOfInfo;
ULONG32 Flags1;
ULONG32 ProcessId;
ULONG32 ProcessCreateTime;
ULONG32 ProcessUserTime;
ULONG32 ProcessKernelTime;
ULONG32 ProcessorMaxMhz;
ULONG32 ProcessorCurrentMhz;
ULONG32 ProcessorMhzLimit;
ULONG32 ProcessorMaxIdleState;
ULONG32 ProcessorCurrentIdleState;
ULONG32 ProcessIntegrityLevel;
ULONG32 ProcessExecuteFlags;
ULONG32 ProtectedProcess;
ULONG32 TimeZoneId;
TIME_ZONE_INFORMATION TimeZone;
WCHAR BuildString[MAX_PATH];
WCHAR DbgBldStr[40];
XSTATE_CONFIG_FEATURE_MSC_INFO XStateData;
ULONG32 ProcessCookie;
} MINIDUMP_MISC_INFO_5,*PMINIDUMP_MISC_INFO_5;
typedefstruct_TIME_ZONE_INFORMATION {
LONG Bias;
WCHAR StandardName[32];
SYSTEMTIME StandardDate;
LONG StandardBias;
WCHAR DaylightName[32];
SYSTEMTIME DaylightDate;
LONG DaylightBias;
} TIME_ZONE_INFORMATION,*PTIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
typedefstruct_XSTATE_CONFIG_FEATURE_MSC_INFO
{
ULONG32 SizeOfInfo;
ULONG32 ContextSize;
ULONG64 EnabledFeatures;
XSTATE_FEATURE Features[MAXIMUM_XSTATE_FEATURES];
} XSTATE_CONFIG_FEATURE_MSC_INFO,*PXSTATE_CONFIG_FEATURE_MSC_INFO;
使用Microsoft Windows调试工具连接到远程存根(Remote Stub)的远程调试
Microsoft调试工具for Windows提供了两种创建远程调试连接的方法,包括“连接到远程会话”和“连接到远程存根”。连接到远程会话是这两个会话中最常用的,也是您通常需要的全部内容,但是它不允许客户端访问远程上缺少的调试符号。
通常,远程调试会话将在所有用户都可以访问符号信息的公司网络中完成,但是如果我们在无法自由共享符号的安全环境之外进行调试,调试将变得更加困难。
Microsoft调试工具包有两个服务器端命令行应用程序,可通过连接到远程存根来帮助我们完成此操作:Dbgsrv.exe文件用于用户模式调试和Kdsrv.exe文件用于内核模式调试。它们为调试器提供了一个精简的服务器层,以充分利用本地符号和源代码进行附加。
让我们通过展示连接到远程会话时遇到的问题来说明使用远程存根的好处。
此图显示了传统的远程调试会话。调试主机和目标都在运行windbg,不过我们可以使用KD或CDB。目标是调试一个有缺陷的应用程序Getif.exe它在调试目标上运行。我们在调试主机上有应用程序的符号,但是出于安全原因,调试目标没有符号访问权限Getif.exe. 在这两台计算机上,我们都从http://msdl.microsoft.com/download/symbols取符号。
以下是调试目标计算机上的符号路径。因为此系统不在我们的安全环境之外,所以它没有Getif.exe应用程序。这对于调试是有问题的。
这是调试主机上的符号路径,其中包括指向应用程序符号的路径,因为它位于安全位置内
要在目标计算机上创建远程调试服务器,请使用.server命令指定用于连接的本地端口:.server tcp:port=<localport>
接下来,我在调试主机上选择“connect to remotesession”。
然后输入端口和服务器名称:
这就是我们头疼的地方!因为我们没有Getif.exe符号访问位于安全环境外部的计算机上,堆栈getif.exe不显示符号信息。这使得调试应用程序变得很困难,因为我们无法转储数据类型或查看其他符号信息。
如果我们想调试Getif.exe对于符号,我们需要将符号文件复制到调试目标计算机,并将位置添加到目标的符号路径中。在我们的场景中,这可能是不可能的,因为符号通常仅限于内部使用,不允许自由复制。
通过在调试目标计算机上激活Dbgsrv,调试主机上的调试器将通过对目标计算机上用户模式进程的完全符号访问进行连接。上图说明了这个过程。
让我们在调试目标上运行一个使用dbgsrv的示例。在调试目标上输入:<path to debugging tools>\dbgsrv -t tcp:port=<localport>
Dbgsrv返回命令提示符,命令窗口中没有输出,调试端口可以是系统上任何打开的端口。最好用netstat确认我们正在监听我们选择的端口。下面是一个例子
现在让我们把焦点转移到调试主机上。我们没有选择典型的“连接远程会话”,而是使用“文件”菜单中的“连接到远程存根”选项。
接下来输入端口和服务器名称。
选择OK之后,我们将返回到空的命令窗口。在连接到目标进程之前,我们不会看到任何文本:
下一步选择“文件附加到进程”选项
请注意,“附加到进程”对话框显示调试目标计算机上运行的进程列表。
现在让我们来看看这个过程。标题栏确认我们已连接到kdsrv目标上的进程:
在这里您可以看到与远程存根连接的好处。符号getif.exe正在为运行在安全环境之外的计算机上的应用程序工作。
但是如果我需要内核调试呢?您可以使用Kdsrv对内核调试执行相同的操作。
如果需要的话,我们可以使用内核调试器srkdv。与前面的示例非常相似,我们输入命令:kdsrv -t tcp:port=<localport>
我们可以看到我们正在监听我们选择的本地端口:
现在,我们必须在调试主机上启动调试器,命令行包含连接到KdSrv主机所需的信息。从Windbg 6.10.3.233开始,我们无法从Windbg图形界面连接到kdsrv远程存根,然后再将内核连接到调试目标。
我在上面的图中用的是字符串-windbg -k kdsrv:server=@{tcp:server=rodolpho,port=5004},trans=@{com:pipe,port=\\mimi\pipe\2008target}
请注意,我们正在调试运行在Microsoft Hyper-V下的内核调试目标上的命名管道!这是一个很好的调试方法,无需设置第二台计算机和连接空调制解调器电缆。如果我们想用空调制解调器电缆连接到COM1,我们将使用:windbg -k kdsrv:server=@{tcp:server=rodolpho,port=5004},trans=@{com:port=com1,baud=11500}
Windbg启动后,命令窗口看起来就像我们附加了一个本地调试器一样。标题栏将确认我们正在通过调试服务器附加:
我们还可以将上下文更改为Getif.exe连接到远程存根后处理。当我们查看应用程序堆栈时,我们有应用程序的符号:
在我们有了远程存根连接之后,我们就可以作为远程会话共享我们的客户机,但是我们将始终处理远程存根客户机上的符号。一旦你设置了一个远程存根几次,它就像设置一个远程会话一样简单,并且可以使远程调试更加顺利。
安全说明:这些示例使用TCP/IP或命名管道,不受密码保护。如果您需要更高的安全性,调试器远程将允许SSL和安全管道连接以及密码和证书身份验证。
使用进程内存转储轻松解决事件查看器错误
今天我将写一篇关于我如何使用SOS.Net框架调试扩展(和!analyze-v)以轻松解决.NETFramework异常。此异常阻止事件查看器正确显示。事件查看器返回了一个错误,该错误提供了有关导致该问题的实际原因的很少信息。在本例中,我将演示如何使用windbg来获取有关出错的信息。我不必对此问题执行实时调试。相反,我使用进程转储来获取与根本原因相关的非常精确的信息,这些信息由调试器返回。然后我可以使用进程监视器来识别需要检查的文件。这些行动使我找到了问题的根源,很容易就得到了纠正。
报告的问题:打开时遇到以下错误事件vwr.msc(事件查看器)在Windows 2008 Server系统上:
"MMC could not create the snap-in."MMC could not create the snap-in.
The snap-inmight not have been installed correctly
Name: Event Viewer
CLSID: FX:{b05566ad-fe9c-4363-be05-7a4cbb7cb510}
Dump文件数据存储格式(四)
六、异常信息流(ExceptionStream
)
异常信息流包含异常信息。包括发生异常的线程、异常记录信息、线程上下文等信息。它紧挨着杂项信息流(MiscInfoStream
)后面。
MiscInfoStream
信息如下:
0x124+0n1365=0x678
我们看看ExceptionStream
信息
可知ExceptionStream的RVA为678h=0x124+0n1365。所以,
MiscInfoStream
后面就是ExceptionStream
。大小168字节,ExceptionStream
数据如下:
ExceptionStream
的数据结构如下:
typedef structMINIDUMP_EXCEPTION_STREAM {
ULONG32 ThreadId;
ULONG32 __alignment;
MINIDUMP_EXCEPTION ExceptionRecord;
MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
} MINIDUMP_EXCEPTION_STREAM,*PMINIDUMP_EXCEPTION_STREAM;