从内存转储中查找消息队列中的消息计数

时间:2014-01-30 14:13:28

标签: c++ debugging winapi windbg

我意识到在任何给定时间使用任何类型的Win API调用都无法确定线程队列中有多少消息。我有一个不起作用的应用程序,因为PostMessage有时失败(可能是由于队列增长到10000,虽然我不知道它怎么会变得这么大)。这是一个间歇性的问题,我发生了几次内存转储。 显然,队列必须在某个地方,本文将解释如何获取它http://moyix.blogspot.com/2008_09_01_archive.html

  

Windows中的每个线程(由_ETHREAD结构表示)都有一个   调用其线程控制块(或Tcb,即_KTHREAD)中的字段   Win32Thread。该字段指向数据结构_W32THREAD,其中   在Windows图形的内核模式部分中定义   子系统,win32k.sys。您实际上可以检查_W32THREAD   通过在WinDbg中发出“dt win32k!_W32THREAD”结构;但是,如果你   启动逆向工程win32k.sys,你会很快发现的   给出的信息远未完成。实际上,_W32THREAD是一个   更大的数据结构,其中包括有关的信息   当前的桌面,键盘布局,安装的窗口挂钩,以及大多数   对我们来说重要的是输入消息队列。在Windows XP SP2中   消息队列位于_W32THREAD的偏移量0xD0处,如下所示:

typedef struct _MSG_QUEUE  {   PMSG_QUEUE_ENTRY Head; 
PMSG_QUEUE_ENTRY Tail;  unsigned long NumberOfMessages;   } MSG_QUEUE;

基本上我正在尝试找到一个指针MSG_QUEUE(它会给我NumberOfMessages,加上我可以从Head开始枚举它们)。但是看起来我看不到通过分析内存转储找到_ETHREAD,_KTHREAD和_W32THREAD中的任何一个的指针。它们究竟存储在哪里,是否处于存储空间?我必须在内核模式下运行吗?我是否需要为win32k.sys加载符号?还有什么我需要做的吗?感谢。

1 个答案:

答案 0 :(得分:1)

这不是所有WinDbg命令的完整答案,但可能仍然有帮助。

消息队列只能在内核模式下访问,因此您需要内核转储或使用SysInternals livekd。 使用-y开关设置符号路径。

livekd -y srv*d:\debug\symbols*http://msdl.microsoft.com/download/symbols

进入内核模式后,找到要调试的进程

!process 0 0 executable.exe

然后获取流程的主题

!process <process> 4

Win32Thread不等于0的所有线程都可能很有用。

博文Jumping the queues介绍了Windows 7的其余部分。 我无法立即关注,文章实际上并未描述要使用的WinDbg命令。我记得在Windows XP上它更容易。