Das Handle von beweglichen Speicherobjekten

Der folgende Artikel bezieht sich auf die Betriebsysteme Windows2000/XP. Die hier aufgeführten Tests wurden unter Windows2000 unter einem Administratoraccount durchgeführt.
Für das Nachvollziehen der hier gemachten Aussagen sind folgende Zusatzprogramme erforderlich:
- Tasks and Token
- Eine Version von Profan² bzw. XProfan.
- Profan2Cpp

Es geht erst einmal um folgenden Quelltext:

Def @LocalAlloc(2) !"KERNEL32","LocalAlloc"

Def @LocalFree(1) !"KERNEL32","LocalFree"

Declare HMEM&

LET HMEM&=@LocalAlloc($2 | $40,32)

PRINT HMEM&

Waitinput

@LocalFree(HMEM&)


Da Profan etwas verschwenderisch mit Heaps umgeht, habe ich den Quelltext der Einfachheit halber mit Profan2Cpp compiliert. Auf dem Bildschirm wird hier das Handle des mit LocalAlloc erzeugten Speicherobjektes ausgegeben (bei mir 44564492):


Zuerst liste ich dann mit Tasks and Token Heaps des mit dem Quelltext erzeugten Prozesses:


Jetzt tue ich mal so, als wäre das mit LocalAlloc erlangte Handle eine Adresse und lese mit Tasks and Token 4 Bytes ab dieser Adresse als dezimales Doublewords aus:

Bei mir erhalte ich die Zahl 38118320.


Jetzt tue ich wieder mal so als wäre die erhaltene Zahl eine Adresse. Wenn ich mir jetzt die vorher ausgelesenen Heapblöcke ansehe, finde ich diese Adresse bei mir im 1.Heap wieder:


Als nächtes schaue ich mir mal mit Tasks and Token den Inhalt dieses Heapblocks etwas genauer an, und zwar als dezimale Doublewords:



Nach dem Kopieren in die Zwischenablage kommt bei mir das heraus:

X1=0

X2=0

X3=0

X4=0

X5=0

X6=0

X7=0

X8=0

X9=0

X10=44564492

X11=393249

X12=524544


Am Ende dieses Heapblockes steht hier scheinbar die in der WIN32.HLP beschriebene Heapkontrollstruktur - und am Anfang dieser Struktur steht wiederum das Handle des vorher mit LocalAlloc erzeugten Speicherbereichs (bei mir, wie gesagt, 44564492).

Die ganze Sache läßt sich mittels folgendem Code auch nochmals näher überprüfen:

Def @LocalAlloc(2) !"KERNEL32","LocalAlloc"

Def @LocalFree(1) !"KERNEL32","LocalFree"

Def @LocalLock(1) !"KERNEL32","LocalLock"

Def @LocalUnlock(1) !"KERNEL32","LocalUnlock"

Declare HMEM&

LET HMEM&=@LocalAlloc($2 | $40,32)

PRINT HMEM&

Print @Locallock(HMEM&)

Waitinput

@LocalUnlock(HMEM&)
@LocalFree(HMEM&)



Und auch so funktioniert es:

Def @GlobalAlloc(2) !"KERNEL32","GlobalAlloc"

Def @GlobalFree(1) !"KERNEL32","GlobalFree"

Declare HMEM&

LET HMEM&=@GlobalAlloc($2 | $40,32)

PRINT HMEM&

Waitinput

@GlobalFree(HMEM&)



Fazit: Hat man ein Handle eines Speicherbereichs - beweglich oder nicht ist egal - kommt man auch in fremden Prozessen relativ unproblematisch an die Adresse, an der die dazugehörigen Daten stehen.


Impressum