Chaos um das Heaplisting
Der folgende
Artikel bezieht sich auf die Betriebsysteme Windows2000/XP sowie
Windows98. Die hier aufgeführten Tests wurden unter Windows98
sowie unter Windows2000 unter einem Administratoraccount
durchgeführt.
Für das Nachvollziehen der hier gemachten
Aussagen sind folgende Zusatzprogramme erforderlich:
- Eine
Version von XProfan.
Demjenigen, der sich schon einmal
mit dem Listen von Heaps und Heapblöcken über die Toolhelp
Funktionen befasst hat, werden wohl spätestens ab Windows2000
graue Haare wachen. Auf der MSDN Homepage findet man folgende
Dokumentationen:
Zitat:" |
HEAPLIST32 |
Describes an entry from a list that enumerates the heaps used by a specified process. |
typedef struct tagHEAPLIST32 { |
SIZE_T dwSize; |
DWORD th32ProcessID; |
ULONG_PTR th32HeapID; |
DWORD dwFlags; |
} HEAPLIST32, |
*PHEAPLIST32; |
Members: |
dwSize |
The size of the structure, in bytes. Before calling the Heap32ListFirst function, |
set this member to sizeof(HEAPLIST32). |
If you do not initialize dwSize, Heap32ListFirst will fail. |
th32ProcessID |
The identifier of the process to be examined. |
th32HeapID |
The heap identifier. This is not a handle, and has meaning only to the tool help functions. |
dwFlags |
This member can be one of the following values. Value Meaning |
HF32_DEFAULT => Process's default heap" |
Zitat:" |
|
HEAPENTRY32 |
|
Describes one entry (block) of a heap that is being examined. |
|
typedef struct tagHEAPENTRY32 { |
|
SIZE_T dwSize; |
|
HANDLE hHandle; |
|
ULONG_PTR dwAddress; |
|
DWORD dwFlags; |
|
DWORD dwLockCount; |
|
DWORD dwResvd; |
|
DWORD th32ProcessID; |
|
ULONG_PTR th32HeapID; |
|
} HEAPENTRY32, |
|
*PHEAPENTRY32; |
|
Members: |
|
dwSize |
|
Size of the structure, in bytes. Before calling the Heap32First function, |
|
set this member to sizeof(HEAPENTRY32). If you do not initialize dwSize, Heap32First fails. |
|
hHandle |
|
Handle to the heap block. |
|
dwAddress |
|
Linear address of the start of the block. |
|
dwBlockSize |
|
Size of the heap block, in bytes. |
|
dwFlags |
|
This member can be one of the following values. |
|
Value |
Meaning |
LF32_FIXED |
The memory block has a fixed (unmovable) location. |
LF32_FREE |
The memory block is not used. |
LF32_MOVEABLE |
The memory block location can be moved. |
dwLockCount |
|
This member is no longer used and is always set to zero. |
|
dwResvd |
|
Reserved; do not use or alter. |
|
th32ProcessID |
|
Process identifier of the process that uses the heap. |
|
th32HeapID |
|
Heap identifier. This is not a handle, and has meaning only to the tool help functions." |
Wer das ganze
der Beschreibung entsprechend versuchsweise umsetzt, wird in etwa zu
ddiesem Quelltext kommen:
Def @GetWindowThreadProcessId(2) !"USER32","GetWindowThreadProcessId" |
Def @CreateToolhelp32Snapshot(2) !"kernel32","CreateToolhelp32Snapshot" |
Def @Heap32ListNext(2) !"kernel32","Heap32ListNext" |
Def @Heap32ListFirst(2) !"kernel32","Heap32ListFirst" |
Def @Heap32Next(1) !"kernel32","Heap32Next" |
Def @Heap32First(3) !"kernel32","Heap32First" |
Def @CloseHandle(1) !"KERNEL32","CloseHandle" |
Def @GetLastError(0) !"KERNEL32","GetLastError" |
Def @GetVersionEx(1) !"KERNEL32","GetVersionExA" |
DEF &Ver_Platform_Win32_Windows 1 |
DEF &Ver_Platform_Win32_NT 2 |
Declare Fenster&, PROCESSID#, ThreadID&, PROCESSID&, HEAPLIST32#, Result_HL&, hSnapshot&, HeapCount% |
Declare HEAPENTRY32#, HeapBlockCount%, Result2&, Zwischenmerker&, Zwischenmerker$ |
Declare WinVer&, Winver$, OS# |
Struct HEAPLIST32 = LISTdwsize&, Listth32ProcessID&, LISTth32HeapID&, dwLISTFlags& |
Struct HEAPENTRY32 = HEdwsize&, hHandle&, dwAddress&, dwBlockSize&, dwFlags&, dwLockCount&, dwResvd&, HEth32ProcessID&, HEth32HeapID& |
Struct OSVERSIONINFO = dwOSVersionInfoSize&,dwMajorVersion&,dwMinorVersion&,dwBuildNumber&,dwPlatformId&,szCSDVersion$(128) |
Proc ?_GetWinVersion |
Parameters ServicePack% |
Declare ServicePack$ |
'Windows-Version ermitteln |
Dim OS#,OSVERSIONINFO |
OS#.dwOSVersionInfoSize& = 148 |
External("Kernel32","GetVersionExA",OS#) |
LET Winver& = 100 |
LET ServicePack$ = " ("+OS#.szCSDVersion$+")" |
If OS#.dwPlatformId& = &Ver_Platform_Win32_Windows |
If OS#.dwMajorVersion& = 4 |
Case OS#.dwMinorVersion& = 0 : Winver& = 1 |
Case OS#.dwMinorVersion& = 10 : Winver& = 2 |
Case OS#.dwMinorVersion& = 90 : Winver& = 3 |
Endif |
ElseIf OS#.dwPlatformId& = &Ver_Platform_Win32_NT |
Case OS#.dwMajorVersion& = 3 : Winver& = 4 |
Case OS#.dwMajorVersion& = 4 : Winver& = 5 |
IF @and(OS#.dwMajorVersion& = 5,OS#.dwMinorVersion& <> 2) |
LET Winver& = 6 |
Elseif @and(OS#.dwMajorVersion& = 5,OS#.dwMinorVersion& = 2) |
LET Winver& = 8 |
endif |
IF @and(OS#.dwMajorVersion& = 6,OS#.dwMinorVersion& = 0) |
LET Winver& = 9 |
endif |
Case OS#.dwMinorVersion& = 1 : Winver& = 7 |
Endif |
Dispose OS# |
case WinVer& = 1: Let Winver$ = "Windows95" |
case WinVer& = 2: Let Winver$ = "Windows98" |
case WinVer& = 3: Let Winver$ = "WindowsME" |
case WinVer& = 4: Let Winver$ = "WindowsNT 3.5" |
case WinVer& = 5: Let Winver$ = "WindowesNT 4" |
case WinVer& = 6: Let Winver$ = "Windows2000" |
case WinVer& = 7: Let Winver$ = "WindowsXP" |
case WinVer& = 8: Let Winver$ = "Windows Server 2003" |
case WinVer& = 9: Let Winver$ = "WindowsVista oder Longhorn" |
case WinVer& = 100: Let Winver$ = "unbekannte Windowsversion" |
CASE ServicePack% = 1 : Let Winver$ = Winver$ + ServicePack$ |
EndProc |
@winexec("WRITE.EXE", 1) |
Sleep 500 |
LET Fenster& = @FindWindow("Dokument - ") |
DIM PROCESSID#, 4 |
LET ThreadID& = @GetWindowThreadProcessId(Fenster&, PROCESSID#) |
LET PROCESSID& = @Long(PROCESSID#, 0) |
Dispose PROCESSID# |
Dim HEAPLIST32#, HEAPLIST32 |
Dim HEAPENTRY32#, HEAPENTRY32 |
Clear HEAPLIST32# |
HEAPLIST32#.LISTdwsize& = 16 |
LET hSnapshot& = @CreateToolhelp32Snapshot($1, ProcessID&) |
IfNot hSnapshot& = -1 |
Clearlist |
?_GetWinVersion 1 |
Addstring "Windowsversion: "+Winver$ |
LET Result_HL& = @Heap32ListFirst(hSnapshot&, HEAPLIST32#) |
While Result_HL& = 1 |
Clear HEAPENTRY32# |
HEAPENTRY32#.HEdwsize& = 36 |
INC HeapCount% |
Clear HeapBlockCount% |
Addstring "____________________________" |
LET Result2& = @Heap32First(HEAPENTRY32#, ProcessID&, HEAPLIST32#.Listth32HeapID&) |
LET Zwischenmerker& = HEAPLIST32#.dwLISTFlags& |
Addstring "Daten des "+@STR$(HEAPCOUNT%)+".Heaps" |
Addstring "Heapflags: $"+@HEX$(Zwischenmerker&) |
IF @or(Zwischenmerker&, $1) = Zwischenmerker& |
Addstring "Typ: "+"Standard Prozessheap" |
LET Zwischenmerker& = Zwischenmerker&-$1 |
endif |
IF @or(Zwischenmerker&, $2) = Zwischenmerker& |
Addstring "Speicherverwaltung: "+"Shared Heap" |
LET Zwischenmerker& = Zwischenmerker&-$2 |
endif |
IF Zwischenmerker&<>0 |
Addstring "Nicht erkannte Heapflags: "+"$"+@Hex$(Zwischenmerker&) |
endif |
While Result2& = 1 |
INC HeapBlockCount% |
Addstring "" |
Addstring @STR$(HEAPCOUNT%)+".Heap "+@Str$(HeapBlockCount%)+".Block Handle im Prozess: "+@STR$(HEAPENTRY32#.hHandle&) |
Addstring @STR$(HEAPCOUNT%)+".Heap "+@Str$(HeapBlockCount%)+".Block Startadresse: "+@STR$(HEAPENTRY32#.dwAddress&) |
Let Zwischenmerker$ = " (" |
IF HEAPENTRY32#.dwFlags& = $1 |
LET Zwischenmerker$ = Zwischenmerker$+"feste Adresse" |
ElseIf HEAPENTRY32#.dwFlags& = $2 |
LET Zwischenmerker$ = Zwischenmerker$+"frei" |
ElseIf HEAPENTRY32#.dwFlags& = $4 |
LET Zwischenmerker$ = Zwischenmerker$+"beweglich" |
Else |
LET Zwischenmerker$ = Zwischenmerker$+"$"+@HEX$(HEAPENTRY32#.dwFlags&) |
endif |
Let Zwischenmerker$ = Zwischenmerker$+")" |
Addstring @STR$(HEAPCOUNT%)+".Heap "+@Str$(HeapBlockCount%)+".Block Größe / Status: "+@STR$(HEAPENTRY32#.dwBlockSize&)+" Bytes"+Zwischenmerker$ |
LET Result2& = @Heap32Next(HEAPENTRY32#) |
wend |
LET Result_HL& = @Heap32ListNext(hSnapshot&, HEAPLIST32#) |
wend |
@CloseHandle(hSnapshot&) |
endif |
Dispose HEAPLIST32# |
Dispose HEAPENTRY32# |
@Editbox("Infos über Heaps von Wordpad", 1) |
Der von mir
hier als Beispiel genommene Quelltext startet die Anwendung Wordpad
und listet deren Heaps und Heapblöcke.
Unter Windows98 sieht
das ganze in etwa so aus:
Hier mal ein kleiner Auszug der zurückgegebenen Daten:
Windowsversion: Windows98 ( A ) |
____________________________ Daten des 1.Heaps |
Heapflags: $0 |
1.Heap 1.Block Handle im Prozess: 5767288 |
1.Heap 1.Block Startadresse: 5767288 |
1.Heap 1.Block Größe / Status: 528 Bytes (feste Adresse) |
1.Heap 2.Block Handle im Prozess: 5767820 |
1.Heap 2.Block Startadresse: 5767820 |
1.Heap 2.Block Größe / Status: 9232 Bytes (feste Adresse) |
1.Heap 3.Block Handle im Prozess: 5777056 |
1.Heap 3.Block Startadresse: 5777056 |
1.Heap 3.Block Größe / Status: 5136 Bytes (feste Adresse) |
1.Heap 4.Block Handle im Prozess: 5782196 |
1.Heap 4.Block Startadresse: 5782196 |
1.Heap 4.Block Größe / Status: 3696 Bytes (feste Adresse) |
1.Heap 5.Block Handle im Prozess: 5785896 |
1.Heap 5.Block Startadresse: 5785896 |
1.Heap 5.Block Größe / Status: 528 Bytes (feste Adresse) |
Das sieht
alles ganz wunderbar aus und scheint ja ganz hervorragend hinzuhauen
- tut es auch - aber nur unter nicht NT basierenden Windowsversionen!
Unter Windows2000 (zum Beispiel) sieht das schon ganz, ganz anders
aus:
Windowsversion: Windows2000 (Service Pack 2) |
____________________________ |
Daten des 1.Heaps |
Heapflags: $2 |
Speicherverwaltung: Shared Heap |
1.Heap 1.Block Handle im Prozess: 458752 |
1.Heap 1.Block Startadresse: 460424 |
1.Heap 1.Block Größe / Status: 6152 Bytes (feste Adresse) |
1.Heap 2.Block Handle im Prozess: 458752 |
1.Heap 2.Block Startadresse: 466576 |
1.Heap 2.Block Größe / Status: 48 Bytes (feste Adresse) |
1.Heap 3.Block Handle im Prozess: 458752 |
1.Heap 3.Block Startadresse: 466624 |
1.Heap 3.Block Größe / Status: 80 Bytes (feste Adresse) |
1.Heap 4.Block Handle im Prozess: 458752 |
1.Heap 4.Block Startadresse: 466704 |
1.Heap 4.Block Größe / Status: 32 Bytes (feste Adresse) |
1.Heap 5.Block Handle im Prozess: 458752 |
1.Heap 5.Block Startadresse: 466736 |
1.Heap 5.Block Größe / Status: 80 Bytes (feste Adresse) |
1.Heap 6.Block Handle im Prozess: 458752 |
1.Heap 6.Block Startadresse: 466816 |
1.Heap 6.Block Größe / Status: 64 Bytes (feste Adresse) |
1.Heap 7.Block Handle im Prozess: 458752 |
1.Heap 7.Block Startadresse: 466880 |
1.Heap 7.Block Größe / Status: 528 Bytes (feste Adresse) |
1.Heap 8.Block Handle im Prozess: 458752 |
1.Heap 8.Block Startadresse: 467408 |
1.Heap 8.Block Größe / Status: 552 Bytes (feste Adresse) |
Holla! Was
ist denn das? Haben da alle Heapblöcke das gleiche Handle
(458752)? Unter Windows98 funktionierte doch alles? Unter Windows2000
scheint (im Gegensatz zu Windows98) beim Member hHandle nicht
das Handle des Heapblocks zu stehen, das steht fest! Mehrere
Speicherobjekte können nicht das gleiche Handle haben, also
stimmt die MSDN Erklärung beim besten Willen nicht mit den
Gegebenheiten unter Windows NT überein. Aber was gibt dann
hHandle unter NT basierenden Windowsversionen an? Dieser
Quelltext gibt da etwas näheren Einblick:
Def @GetWindowThreadProcessId(2) !"USER32","GetWindowThreadProcessId" |
Def @CreateToolhelp32Snapshot(2) !"kernel32","CreateToolhelp32Snapshot" |
Def @Heap32ListNext(2) !"kernel32","Heap32ListNext" |
Def @Heap32ListFirst(2) !"kernel32","Heap32ListFirst" |
Def @Heap32Next(1) !"kernel32","Heap32Next" |
Def @Heap32First(3) !"kernel32","Heap32First" |
Def @CloseHandle(1) !"KERNEL32","CloseHandle" |
Def @GetLastError(0) !"KERNEL32","GetLastError" |
Def @GetVersionEx(1) !"KERNEL32","GetVersionExA" |
Def @HeapAlloc(3) !"KERNEL32","HeapAlloc" |
Def @HeapFree(3) !"KERNEL32","HeapFree" |
Def @HeapCreate(3) !"KERNEL32","HeapCreate" |
Def @HeapDestroy(1) !"KERNEL32","HeapDestroy" |
Def @GlobalLock(1) !"KERNEL32","GlobalLock" |
Def @GlobalHandle(1) !"KERNEL32","GlobalHandle" |
Def @GetCurrentProcessId(0) !"KERNEL32","GetCurrentProcessId" |
DEF &Ver_Platform_Win32_Windows 1 |
DEF &Ver_Platform_Win32_NT 2 |
Declare Fenster&, PROCESSID#, ThreadID&, PROCESSID&, HEAPLIST32#, Result_HL&, hSnapshot&, HeapCount% |
Declare HEAPENTRY32#, HeapBlockCount%, Result2&, Zwischenmerker&, Zwischenmerker$ |
Declare WinVer&, Winver$, OS# |
Declare HMEM&,Heap& |
Struct HEAPLIST32 = LISTdwsize&, Listth32ProcessID&, LISTth32HeapID&, dwLISTFlags& |
Struct HEAPENTRY32 = HEdwsize&, hHandle&, dwAddress&, dwBlockSize&, dwFlags&, dwLockCount&, dwResvd&, HEth32ProcessID&, HEth32HeapID& |
Struct OSVERSIONINFO = dwOSVersionInfoSize&,dwMajorVersion&,dwMinorVersion&,dwBuildNumber&,dwPlatformId&,szCSDVersion$(128) |
Proc ?_GetWinVersion |
Parameters ServicePack% |
Declare ServicePack$ |
'Windows-Version ermitteln |
Dim OS#,OSVERSIONINFO |
OS#.dwOSVersionInfoSize& = 148 |
External("Kernel32","GetVersionExA",OS#) |
LET Winver& = 100 |
LET ServicePack$ = " ("+OS#.szCSDVersion$+")" |
If OS#.dwPlatformId& = &Ver_Platform_Win32_Windows |
If OS#.dwMajorVersion& = 4 |
Case OS#.dwMinorVersion& = 0 : Winver& = 1 |
Case OS#.dwMinorVersion& = 10 : Winver& = 2 |
Case OS#.dwMinorVersion& = 90 : Winver& = 3 |
Endif |
ElseIf OS#.dwPlatformId& = &Ver_Platform_Win32_NT |
Case OS#.dwMajorVersion& = 3 : Winver& = 4 |
Case OS#.dwMajorVersion& = 4 : Winver& = 5 |
IF @and(OS#.dwMajorVersion& = 5,OS#.dwMinorVersion& <> 2) |
LET Winver& = 6 |
Elseif @and(OS#.dwMajorVersion& = 5,OS#.dwMinorVersion& = 2) |
LET Winver& = 8 |
endif |
IF @and(OS#.dwMajorVersion& = 6,OS#.dwMinorVersion& = 0) |
LET Winver& = 9 |
endif |
Case OS#.dwMinorVersion& = 1 : Winver& = 7 |
Endif |
Dispose OS# |
case WinVer& = 1: Let Winver$ = "Windows95" |
case WinVer& = 2: Let Winver$ = "Windows98" |
case WinVer& = 3: Let Winver$ = "WindowsME" |
case WinVer& = 4: Let Winver$ = "WindowsNT 3.5" |
case WinVer& = 5: Let Winver$ = "WindowesNT 4" |
case WinVer& = 6: Let Winver$ = "Windows2000" |
case WinVer& = 7: Let Winver$ = "WindowsXP" |
case WinVer& = 8: Let Winver$ = "Windows Server 2003" |
case WinVer& = 9: Let Winver$ = "WindowsVista oder Longhorn" |
case WinVer& = 100: Let Winver$ = "unbekannte Windowsversion" |
CASE ServicePack% = 1 : Let Winver$ = Winver$ + ServicePack$ |
EndProc |
Let ProcessID&=@GetCurrentProcessId() |
Dim HEAPLIST32#, HEAPLIST32 |
Dim HEAPENTRY32#, HEAPENTRY32 |
Clear HEAPLIST32# |
Clearlist |
HEAPLIST32#.LISTdwsize& = 16 |
LET Heap&=@HeapCreate($1,5000,10000) |
Addstring "Handle des erzeugten Heaps: "+@str$(Heap&) |
LET HMEM&=@HeapAlloc(Heap&,$1,5000) |
Addstring "Pointer auf den Heapblock: "+@str$(HMEM&) |
Addstring "" |
LET hSnapshot& = @CreateToolhelp32Snapshot($1, ProcessID&) |
IfNot hSnapshot& = -1 |
?_GetWinVersion 1 |
Addstring "Windowsversion: "+Winver$ |
LET Result_HL& = @Heap32ListFirst(hSnapshot&, HEAPLIST32#) |
While Result_HL& = 1 |
Clear HEAPENTRY32# |
HEAPENTRY32#.HEdwsize& = 36 |
INC HeapCount% |
Clear HeapBlockCount% |
Addstring "____________________________" |
LET Result2& = @Heap32First(HEAPENTRY32#, ProcessID&, HEAPLIST32#.Listth32HeapID&) |
LET Zwischenmerker& = HEAPLIST32#.dwLISTFlags& |
Addstring "Daten des "+@STR$(HEAPCOUNT%)+".Heaps" |
Addstring "Heapflags: $"+@HEX$(Zwischenmerker&) |
IF @or(Zwischenmerker&, $1) = Zwischenmerker& |
Addstring "Typ: "+"Standard Prozessheap" |
LET Zwischenmerker& = Zwischenmerker&-$1 |
endif |
IF @or(Zwischenmerker&, $2) = Zwischenmerker& |
Addstring "Speicherverwaltung: "+"Shared Heap" |
LET Zwischenmerker& = Zwischenmerker&-$2 |
endif |
IF Zwischenmerker&<>0 |
Addstring "Nicht erkannte Heapflags: "+"$"+@Hex$(Zwischenmerker&) |
endif |
Addstring "Toolhelp Heap-ID: "+@STR$(HEAPLIST32#.LISTth32HeapID&) |
While Result2& = 1 |
INC HeapBlockCount% |
Addstring "" |
Addstring @STR$(HEAPCOUNT%)+".Heap "+@Str$(HeapBlockCount%)+".Block Handle im Prozess: "+@STR$(HEAPENTRY32#.hHandle&) |
Addstring @STR$(HEAPCOUNT%)+".Heap "+@Str$(HeapBlockCount%)+".Block Startadresse: "+@STR$(HEAPENTRY32#.dwAddress&) |
Let Zwischenmerker$ = " (" |
IF HEAPENTRY32#.dwFlags& = $1 |
LET Zwischenmerker$ = Zwischenmerker$+"feste Adresse" |
ElseIf HEAPENTRY32#.dwFlags& = $2 |
LET Zwischenmerker$ = Zwischenmerker$+"frei" |
ElseIf HEAPENTRY32#.dwFlags& = $4 |
LET Zwischenmerker$ = Zwischenmerker$+"beweglich" |
Else |
LET Zwischenmerker$ = Zwischenmerker$+"$"+@HEX$(HEAPENTRY32#.dwFlags&) |
endif |
Let Zwischenmerker$ = Zwischenmerker$+")" |
Addstring @STR$(HEAPCOUNT%)+".Heap "+@Str$(HeapBlockCount%)+".Block Größe / Status: "+@STR$(HEAPENTRY32#.dwBlockSize&)+" Bytes"+Zwischenmerker$ |
Addstring @STR$(HEAPCOUNT%)+".Heap "+@Str$(HeapBlockCount%)+".Block Toolhelp Heap-ID: "+@STR$(HEAPENTRY32#.HEth32HeapID&) |
LET Result2& = @Heap32Next(HEAPENTRY32#) |
wend |
LET Result_HL& = @Heap32ListNext(hSnapshot&, HEAPLIST32#) |
wend |
@CloseHandle(hSnapshot&) |
endif |
Dispose HEAPLIST32# |
Dispose HEAPENTRY32# |
@HeapFree(Heap&,0,HMEM&) |
@HeapDestroy(Heap&) |
@Editbox("Infos über Heaps von Wordpad", 1) |
Handle des erzeugten Heaps: 50135040 |
Pointer auf den Heapblock: 50136656 |
Windowsversion: Windows2000 (Service Pack 2) |
____________________________ |
...Daten des 5.Heaps |
Heapflags: $1001 |
Typ: Standard Prozessheap |
Nicht erkannte Heapflags: $1000 |
5.Heap 1.Block Handle im Prozess: 50135040 |
5.Heap 1.Block Startadresse: 50136656 |
5.Heap 1.Block Größe / Status: 5008 Bytes (feste Adresse) |
5.Heap 2.Block Handle im Prozess: 50135040 |
5.Heap 2.Block Startadresse: 50141664 |
5.Heap 2.Block Größe / Status: 1576 Bytes (feste Adresse) |
5.Heap 3.Block Handle im Prozess: 50135040 |
5.Heap 3.Block Startadresse: 50143240 |
5.Heap 3.Block Größe / Status: 4096 Bytes (frei) |
Wie man hier
sieht, gibt [i]hHandle[/i] unter Windows2000 (und XP) nicht das
Handle des Heapblocks, sondern das Handle des Heaps an. Auch diese
Aussage
Zitat:" |
th32HeapID |
Heap identifier. This is not a handle, and has meaning only to the tool help functions." |
scheint hier
nicht zuzutreffen.
Jetzt schauen wir uns mal die Heapflags
an:
Daten des 5.Heaps |
Heapflags: $1001 |
Typ: Standard Prozessheap |
Erzeugt wurde der Heap durch folgenden Code:
LET Heap&=@HeapCreate($1,5000,10000) |
Erzeugt man
den Heap so
LET Heap&=@HeapCreate($4,5000,10000) |
, sehen die
Flags so aus:
____________________________ |
Daten des 5.Heaps |
Heapflags: $1004 |
Nicht erkannte Heapflags: $1004 |
Und erzeugt
man den Heap so
LET Heap&=@HeapCreate($5,5000,10000) |
, sehen die
Flags so aus:
____________________________ |
Daten des 5.Heaps |
Heapflags: $1005 |
Typ: Standard Prozessheap |
Nicht erkannte Heapflags: $1005 |
Was hier bei
den Heapflags zurückgegeben wird, hat also - anders als unter
Nicht-NT - etwas mit den Flags zu tun, die bei der Erzeugung des
Heaps übergeben wurden.
Demzufolge ist dieses hier
Zitat:" |
dwFlags |
This member can be one of the following values. Value Meaning |
HF32_DEFAULT => Process's default heap" |
ebenfalls mit
Vorsicht zu genießen!
Aber - wie sieht das mit Vista
aus? Dazu (mit bestem Dank an Rolf Koch) folgende Rückmeldungen
des ersten Quelltextes:
Windowsversion: WindowsVista oder Longhorn () |
____________________________ |
Daten des 1.Heaps |
Heapflags: $1 |
Typ: Standard Prozessheap |
1.Heap 1.Block Handle im Prozess: 2097152 |
1.Heap 1.Block Startadresse: 2097160 |
1.Heap 1.Block Größe / Status: 32 Bytes (feste Adresse) |
1.Heap 2.Block Handle im Prozess: 2097152 |
1.Heap 2.Block Startadresse: 2097192 |
1.Heap 2.Block Größe / Status: 1880 Bytes (feste Adresse) |
... |
____________________________ |
Daten des 2.Heaps |
Heapflags: $0 |
2.Heap 1.Block Handle im Prozess: 65536 |
2.Heap 1.Block Startadresse: 65544 |
2.Heap 1.Block Größe / Status: 10848 Bytes ($0) |
2.Heap 2.Block Handle im Prozess: 65536 |
2.Heap 2.Block Startadresse: 76392 |
2.Heap 2.Block Größe / Status: 53248 Bytes (frei) |
____________________________ |
Daten des 3.Heaps |
Heapflags: $0 |
3.Heap 1.Block Handle im Prozess: 4194304 |
3.Heap 1.Block Startadresse: 4194312 |
3.Heap 1.Block Größe / Status: 544 Bytes (feste Adresse) |
3.Heap 2.Block Handle im Prozess: 4194304 |
3.Heap 2.Block Startadresse: 4194856 |
3.Heap 2.Block Größe / Status: 136 Bytes (feste Adresse) |
... |
Auch hier stimmt also offensichtlich das
Handle des Heapblocks nicht! Bei den Flags scheint Microsoft aber
wieder auf den dokumentierten Standard zurückgegriffen zu haben.
Fazit: Wer beim Heaplisting auf die Dokumentation baut, hat
sein Haus wohl auf Treibsand gesetzt...