Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding out the messages count in thread message queue from a memory dump

I aware of the fact that it’s not possible to determine how many messages are in the thread queue at any given time with any sort of Win API calls. I’ve an application that doesn’t work because PostMessage fails sometimes (possibly due to the queue growing to 10000, although I don’t see how could it grow so big). It’s an intermittent issue and I have several memory dumps taken at exactly the moment when it happens. Obviously the queue has to be somewhere and this article explains how to get it http://moyix.blogspot.com/2008_09_01_archive.html

Each thread in Windows (represented by the _ETHREAD strucutre) has a field in its Thread Control Block (or Tcb, which is a _KTHREAD) called Win32Thread. This field points to a data structure, _W32THREAD, which is defined in the kernel-mode portion of the Windows graphical subsystem, win32k.sys. You can actually examine the _W32THREAD structure by issuing "dt win32k!_W32THREAD" in WinDbg; however, if you start reverse engineering win32k.sys, you'll quickly find that the information given there is far from complete. In fact, _W32THREAD is a much larger data structure, which includes information about the current desktop, keyboard layout, installed window hooks, and, most importantly for us, the input message queue. In Windows XP SP2, the message queue is found at offset 0xD0 of _W32THREAD, and looks like:

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

Basically I’m trying to find a pointer MSG_QUEUE (which will give me NumberOfMessages, plus I can enumerate them starting from Head). However it doesn't look I can find pointers to any of _ETHREAD, _KTHREAD and _W32THREAD by analyzing memory dump. Where exactly are they stored, are they in process memory space? Do I have to run in kernel mode? Do I need to load symbols for win32k.sys? Anything else I need to do? Thanks.

like image 649
pullo_van Avatar asked Nov 11 '22 13:11

pullo_van


1 Answers

This is not a full answer with all WinDbg commands, but maybe still helpful.

The message queue is only accessible in kernel mode, so you need a kernel dump or use SysInternals livekd. Use the -y switch to set the symbol path.

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

Once you are in kernel mode, find the process you want to debug

!process 0 0 executable.exe

Then get the threads of the process

!process <process> 4

All threads which have Win32Thread not equal to 0 are potentially interesting.

The blog post Jumping the queues describes the rest for Windows 7. I couldn't immediately follow and the article does not actually describe which WinDbg commands to use. I remember it was much easier on Windows XP.

like image 110
Thomas Weller Avatar answered Nov 14 '22 22:11

Thomas Weller