Home BlogTracking Down Memory Corruption (Bug Check 0x19)

Tracking Down Memory Corruption (Bug Check 0x19)

by dnaadmin

In our previous article, we looked at IRQL issues. Today, we dive into one of the most challenging areas of Windows debugging: Pool Corruption.

When a driver or kernel component writes past the end of its allocated memory buffer, it doesn’t always crash immediately. It might overwrite the “header” of the next memory block. The system only notices the damage later when it tries to allocate or free that next block, leading to a Bug Check 0x19: BAD_POOL_HEADER.


1. Understanding the Windows Kernel Pool

The Kernel Pool is the heap for kernel-mode drivers. It is divided into Pool Chunks. Each chunk starts with a Pool Header that contains metadata:

  • Previous Size: Size of the preceding chunk.
  • Pool Index: Used for tracking.
  • Block Size: Size of the current chunk.
  • Pool Tag: A 4-character “signature” (e.g., ExAl) identifying who allocated the memory.

If a driver performs an “off-by-one” error or a memcpy with an incorrect length, it overwrites the header of the adjacent chunk. When the Pool Manager later inspects that corrupted header, it triggers the BSOD to prevent further data loss.


2. Real Use Case: The “Ghost” Overwriter

Scenario: A server crashes randomly every few hours with 0x19. The stack trace usually points to nt!ExFreePoolWithTag, which is just the “victim” trying to clean up memory.

Step 1: Analyze the Parameters

In WinDbg, run !analyze -v. Look at the parameters for 0x19:

  • Arg1: 0x20 (The pool block header is corrupt)
  • Arg2: The address of the corrupted pool block.
  • Arg3/4: Internal tracking data.

Step 2: Inspecting the Neighborhood

We use the !pool command to look at the memory surrounding the crash address:

Plaintext

kd> !pool fffff801`4a220000
fffff801`4a220000 size:  40 previous size:   0  (Free)      ....
fffff801`4a220400 size:  60 previous size:  40  (Allocated)  Leak
fffff801`4a220460 size:  ?? previous size:  ??  (Corrupt)    Tag?

The debugger tells us the chunk at 0x460 is corrupt. This means the chunk immediately before it (at 0x400) is likely the one that overran its boundary.

Step 3: Identifying the Culprit via Pool Tags

Look at the tag for the chunk at 0x400. Let’s say it is Prot.

To find which driver owns that tag, use the strings command or search your source code:

findstr /s "Prot" *.c

If you don’t have the source, use:

!libpooltag Prot

This identifies the “Protocol” driver as the one that likely wrote too much data into its 0x60 byte allocation, destroying the header of the next block.


3. Advanced Technique: Special Pool

Sometimes the corruption is so subtle that !pool isn’t enough. This is where Driver Verifier and Special Pool come in.

By enabling Special Pool for a specific driver tag, Windows places each allocation on a separate memory page, right against a “guard page.”

  • The Result: Instead of corrupting a neighbor and crashing later, the driver will trigger an immediate 0x50 (PAGE_FAULT_IN_NONPAGED_AREA) the very millisecond it tries to write one byte too far.

4. Best Practices for Blog Readers

  • Always use Pool Tags: Never use ExAllocatePool. Use ExAllocatePoolWithTag. It’s your primary breadcrumb during a crash.
  • Validate Buffer Lengths: Before every RtlCopyMemory or memcpy, check your destination buffer size against the source length.
  • Use !poolval: This WinDbg command can help validate the entire pool structure if you suspect widespread corruption.

Summary of Memory Bug Checks

Bug CheckNameDescription
0x19BAD_POOL_HEADERA pool header was found to be invalid during a pool operation.
0x50PAGE_FAULT_IN_NONPAGED_AREAInvalid system memory was referenced (often due to bad pointers).
0xC4DRIVER_VERIFIER_DETECTED_VIOLATIONCaught by Verifier—this is the “Gold Standard” for debugging.
0xBEATTEMPTED_WRITE_TO_READONLY_MEMORYA driver tried to write to a segment of memory marked as read-only.

In the next article, we will tackle Deadlocks and Timeouts (0x133)—how to find out which thread is “hogging” the CPU and stalling the entire system.

You may also like

Leave a Comment