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:
sxe cpr
sxe ld *
.restart
ntdll
is present at that point.
0:000> lm
start end module name
00100000 00122000 HelloWorld (deferred)
kernelbase
was not loaded yet.
bu kernelbase!heapcreate
!heap
may just not work at all.
0:000> !heap
Invalid type information
ntdll
is loaded. (We have set sxe ld *
)
0:000> g
ModLoad: 77940000 77ae4000 ntdll.dll
[...]
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?
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.