admin管理员组

文章数量:1122832

I want to observe when the default process heap gets created, i.e. have a breakpoint and get the callstack of the creation. This has no practical background. I just want to understand the Windows internals and explore stuff written in the Windows Internals book.

I am trying this with a simple Hello World application:

#include <iostream>

int main()
{
    std::cout << "Hello World!\n";
}

My debugging procedure is:

  1. Preparing a debug session that starts as soon as possible
    1. Start WinDbg
    2. Launch the HelloWorld application with WinDbg
    3. At the initial breakpoint, run the following commands:
      sxe cpr
      sxe ld *
      
    4. Start the early debug procedure. This will break when only the executable was loaded.
      .restart
      
  2. Confirm that I am in an early debug session. Not even ntdll is present at that point.
    0:000> lm
    start    end        module name
    00100000 00122000   HelloWorld   (deferred)  
    
  3. Set a breakpoint for heap creation. It must be unresolved, because kernelbase was not loaded yet.
    bu kernelbase!heapcreate
    
  4. Confirm that no heaps are present.
    1. Initially, we don't know for sure, because !heap may just not work at all.
      0:000> !heap
      Invalid type information
      
    2. Wait until ntdll is loaded. (We have set sxe ld *)
      0:000> g
      ModLoad: 77940000 77ae4000   ntdll.dll
      [...]
      
    3. Confirm that no heaps are present.
      0:000> !heap
              Heap Address      NT/Segment Heap
      

However, with the next loaded module, there already is a heap, even though the breakpoint wasn't hit (and kernelbase wasn't even loaded, so it isn't even resolved):

0:000> g
ModLoad: 76540000 76630000   C:\Windows\SysWOW64\KERNEL32.DLL
[...]
0:000> !heap
        Heap Address      NT/Segment Heap

            012d0000              NT Heap

How would I break when the default process heap gets created?

I want to observe when the default process heap gets created, i.e. have a breakpoint and get the callstack of the creation. This has no practical background. I just want to understand the Windows internals and explore stuff written in the Windows Internals book.

I am trying this with a simple Hello World application:

#include <iostream>

int main()
{
    std::cout << "Hello World!\n";
}

My debugging procedure is:

  1. Preparing a debug session that starts as soon as possible
    1. Start WinDbg
    2. Launch the HelloWorld application with WinDbg
    3. At the initial breakpoint, run the following commands:
      sxe cpr
      sxe ld *
      
    4. Start the early debug procedure. This will break when only the executable was loaded.
      .restart
      
  2. Confirm that I am in an early debug session. Not even ntdll is present at that point.
    0:000> lm
    start    end        module name
    00100000 00122000   HelloWorld   (deferred)  
    
  3. Set a breakpoint for heap creation. It must be unresolved, because kernelbase was not loaded yet.
    bu kernelbase!heapcreate
    
  4. Confirm that no heaps are present.
    1. Initially, we don't know for sure, because !heap may just not work at all.
      0:000> !heap
      Invalid type information
      
    2. Wait until ntdll is loaded. (We have set sxe ld *)
      0:000> g
      ModLoad: 77940000 77ae4000   ntdll.dll
      [...]
      
    3. Confirm that no heaps are present.
      0:000> !heap
              Heap Address      NT/Segment Heap
      

However, with the next loaded module, there already is a heap, even though the breakpoint wasn't hit (and kernelbase wasn't even loaded, so it isn't even resolved):

0:000> g
ModLoad: 76540000 76630000   C:\Windows\SysWOW64\KERNEL32.DLL
[...]
0:000> !heap
        Heap Address      NT/Segment Heap

            012d0000              NT Heap

How would I break when the default process heap gets created?

Share Improve this question asked yesterday Thomas WellerThomas Weller 59k23 gold badges136 silver badges249 bronze badges 1
  • @Someprogrammerdude: Virtual memory on Windows is typically managed in blocks of 64k. Since 64k is too much for a new int, that memory is then split into smaller items by the Windows Heap Manager. That's what what the nt!_HEAP and similar structures are made for, isn't it? I know that .NET uses a different model due to garbage collection, however, the question is tagged C++. If there's a new approach that I don't know of, just drop me the name of the new thing and I will do my research on that. – Thomas Weller Commented yesterday
Add a comment  | 

1 Answer 1

Reset to default 1

The breakpoint needs to be set on ntdll!RtlCreateHeap:

0:000> .restart
[...]

0:000> g
ModLoad: 77940000 77ae4000   ntdll.dll
[...]

0:000> !heap
        Heap Address      NT/Segment Heap

0:000> g
Breakpoint 0 hit
[...]

0:000> k
 # ChildEBP RetAddr      
00 009bf588 779f2fdf     ntdll!RtlCreateHeap
01 009bf63c 779eac70     ntdll!LdrpInitializeProcessHeap+0x1b0
02 009bf8a4 779a6a31     ntdll!LdrpInitializeProcess+0x85c
03 009bf8fc 779a6921     ntdll!_LdrpInitialize+0xba
04 009bf908 00000000     ntdll!LdrInitializeThunk+0x11

0:000> lm
start    end        module name
00100000 00122000   HelloWorld   (deferred)             
77940000 77ae4000   ntdll      (pdb symbols) [...]

0:000> gu
[...]
ntdll!LdrpInitializeProcessHeap+0x1b0:
[...]

0:000> !heap
        Heap Address      NT/Segment Heap

            00fc0000              NT Heap

The callstack confirms that this is the default process heap.

本文标签: cObserving the default process heap getting created (breakpoint on heap creation)Stack Overflow