Using Special Pool to find out who is allocating a Pool Tag

OK, a quick disclaimer right at the start.  The steps we discuss in this post assume that you are very comfortable with kernel debugging, and in particular live debugging.  This is a bit of a niche post, but it is a question that we get every so often, so we figured we’d share the information.  The information in this post follows on from our post last Friday on Pool Tags.  So without further ado, here we go …

Let’s say that you have a server that is leaking Pool memory (either Paged or NonPaged).  You’ve done troubleshooting and identified the leaking tag, but you want to examine the actual stack leading up to the allocation.  Using Special Pool and the Debugger Tools you can find out exactly who is allocating the tag.  Now, we’re not going to dive too deep into Special Pool itself, but in a nutshell, this feature configures Windows to request memory allocations from a reserved memory pool when the memory is allocated with a specific pool tag or is within a specified size range.

So let’s take a look at an example.  We’re going to use the Ddk tag for our example.  The Ddk tag is the default tag for driver-allocated memory.

  • On the system where the tag is leaking, we navigate to the HKLM\System\CurrentControlSet\Control\Session Manager\Memory Management key
  • Create a REG_DWORD value called PoolTag.  In this value, we enter the tag value in little-endian format (i.e. backwards).  Remember that Pool Tags are four bytes(characters), so the tag is actually Ddk<space>.  When we convert this string into ASCII (and then into Hex) we get the following:
    Character ASCII Value HEX Value
    D 68 44
    d 100 64
    k 107 6b
    <space> 32 20

Note:  When doing the conversion, remember that ASCII differentiates between upper and lower case, so you have to ensure that you take case sensitivity into account.

Therefore, according to our conversion table above, the basic conversion becomes 44646b20.  When we enter this into the registry, it has to be In little-endian format. Thus the value for the REG_DWORD Pooltag entry for the Ddk tag is: 206b6444

  • Now that we have our registry value configured, it’s time to set up for the debug.  You’ll need a second machine (such as a laptop) and a null modem cable.  On the laptop, ensure that you have the latest version of the Debugging Tools for Windows.  A quick tip here – when installing the Debugging Tools, install them to a different location than the default, such as C:\Debug or C:\Debuggers.
  • On the system with the leaking tag, edit the boot.ini file so that you can attach to the debugger.  Copy your default entry (give it a different display name) and add the following switches: /debug /debugport=com1 /baudrate=19200
  • Create a batch file on the laptop, and save it with a .cmd extension – a sample is below:
@echo off
SET _NT_DEBUG_LOG_FILE_OPEN=c:\debug\debug.log
SET _NT_SYMBOL_PATH=SRV*c:\websymbols* 
kd -server npipe:pipe=livedebug

When you run this batch file, you will see a message, “Waiting to Connect” – the laptop is waiting for the server to allow it to break in.  Reboot the server, and select your Debug option that you configured in the boot.ini earlier.  As the server boots up, you will start to see debug output in the command window on the laptop.  Log into the server as soon as possible.  Once you are logged in to the server, you’ll need to break into it from the laptop by pressing the CTRL+BREAK keys.  When the >kd prompt appears (it may take a few moments, and during this time your server will be halted), we’re ready to set our breakpoint on the nt!MmAllocateSpecialPool function.  The command is: bp nt!MmAllocateSpecialPool “;kb;g” and hit the ENTER key.  With our breakpoint set, it’s time to let the server get back to work.  In the command window, type in the letter ‘g’ (without the quotes) and hit ENTER.  Now all we have to do is wait for an allocation that matches the tag we entered to be allocated.  So in our example, every time the Ddk tag is allocated, the allocation stack will be written to the debug log (c:\debug\debug.log) that we specified above in our batch file which we can examine offline without having to perform a full dump of the server.

And that’s it.  Remember, that these are some very advanced troubleshooting steps that we are getting into – for most people, being able to identify the leaking tag is 99% of the challenge.

Additional Resources:

Aaron Maxwell

Share this post :