Was ist ein Handle?

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    Unsere Datenschutzerklärung wurde aktualisiert. Mit der Nutzung unseres Forums akzeptierst Du unsere Datenschutzerklärung. Du bestätigst zudem, dass Du mindestens 16 Jahre alt bist.

    • Ein Handle ist so etwas wie ein Griff; im Softwarebereich also ein Wert, der einem den Zugriff auf bestimmte Daten ermöglicht. Ein Handle auf eine Bitmap ist also jener Wert, der mir den Zugriff auf die Eigenschaften und Daten dieser Bitmap ermöglicht. Das Ergebnis der Create-Funktionen in XProfan ist in der Regel ein solches Handle. Funktionen, die auf das erzeugte Objekt, sei es nun ein Bild, Icon, Dialogelement, eine Liste, ein String-Grid oder was auch immer. zugreifen und etwas damit anfangen, benötigen dieses eindeutige Handle.

      Erzeuge ich zum Beispiel mehrere Editfelder in einem Dialog, hat jedes ein eigenes eindeutiges Handle. Der Funktion Gettext$() übergebe ich nun das Handle des Editfeldes, dessen Inhalt ich ermitteln will.

      (Systemtechnisch gesehen verbergen sich hinter dem Wert des Handles oftmals Speicheradressen, an denen die Informationen über das Objekt liegen. Das muss allerdings nicht zwingend so sein. Es wären auch Handles denkbar, die eine Ordnungszahl o.ä. darstellen.)

      Gruß
      Roland
      (Intel Duo E8400 3,0 GHz / 4 GB RAM / 250 GB HDD / ATI Radeon HD4770 512 MB / Windows Vista - ausgemustert zum Verkauf)
      AMD Athlon II X2 2,9 GHz / 8 GB RAM / 500 + 1000 GB HDD / ATI Radeon 3000 (onboard) / Windows 10(64) - XProfan X4


      http://www.xprofan.de
    • Frabbing;682302 schrieb:

      Ein Handle ist ein Zeiger auf eine oder ein Schlüssel zu einer Datenstruktur, auf die ein Satz von Funktionen zugreift.

      Stimmt so nicht [B]ganz[/B]. Schau dir mal den Wert eines Fensterhandles oder den Wert eines Prozesshandles an - kann das ein Pointer sein? Gerade bei den Handles von Fenstern fällt da unter NT basierenden Systemen etwas ganz bestimmtes auf, das hier sehr wichtig ist.

      @Roland und @Carone: Zu ungenau, damit kann man in der Praxis nichts anfangen.
    • Also ich finde hier wurde einiges gesagt, was sehr richtig ist. Und meiner Meinung nach waren einige Beschreibungen nicht zu ungenau, sondern umgekehrt eher zu spezifisch.

      Denn in der Praxis ist es meiner Ansicht nach gerade nicht wichtig, was letztlich hinter der Zahl, die man "Handle" nennt, steckt, sondern nur, dass man darüber ein bestimmtes "Objekt" (Beispiele wurden ja schon genannt) gegenüber einer Schnittstelle (Satz von Funktionen) eindeutig identifizieren kann.

      MfG

      Sebastian
    • AHT;682605 schrieb:

      Stimmt so nicht [B]ganz[/B]. Schau dir mal den Wert eines Fensterhandles oder den Wert eines Prozesshandles an - kann das ein Pointer sein? Gerade bei den Handles von Fenstern fällt da unter NT basierenden Systemen etwas ganz bestimmtes auf, das hier sehr wichtig ist.


      Und was, bitte sehr? Wenn Du es schon weißt, dann frage doch nicht danach, sondern teile Dein Wissen der Welt mit! (Oder bist Du ein Lehrer? Die fragen auch immer nach Dingen, die sie schon wissen ... ;-) )

      In der Praxis reicht es mir, zu wissen, auf was ich mit dem Handle zugreifen. Wenn ich das Handle eines Editfeldes habe, dann kann ich in das Editfeld schreiben, es auslesen, sein Aussehen ändern und manches mehr. Dem Anwendungsprogrammierer ist es in der Regel völlig egal, was sich nun genau hinter dem Wert verbirgt, ob er nun eine Adresse, Listennummer oder sonst etwas ist.

      Gruß
      Roland
      (Intel Duo E8400 3,0 GHz / 4 GB RAM / 250 GB HDD / ATI Radeon HD4770 512 MB / Windows Vista - ausgemustert zum Verkauf)
      AMD Athlon II X2 2,9 GHz / 8 GB RAM / 500 + 1000 GB HDD / ATI Radeon 3000 (onboard) / Windows 10(64) - XProfan X4


      http://www.xprofan.de
    • Zitat:
      Zitat von Frabbing
      Ein Handle ist ein Zeiger auf eine oder ein Schlüssel zu einer Datenstruktur, auf die ein Satz von Funktionen zugreift.

      Stimmt so nicht [B]ganz[/B]. Schau dir mal den Wert eines Fensterhandles oder den Wert eines Prozesshandles an - kann das ein Pointer sein?


      Ein Pointer oder ein Schlüssel...
      Gruß, Frank
    • RGH;682662 schrieb:

      Und was, bitte sehr?

      Ich will es etwas genauer haben, warum kommt später.
      Nimms mir nicht übel, aber es gibt da eine alte "Bauernregel":

      Wenn der Hahn kräht auf dem Mist, ändert sich das Wetter, oder es bleibt wie es ist.

      Nimm mal deine Aussage und versuche darauf basierend ein Programm zu schreiben, dass von anderen Prozessen geöffnete Hooks schließt.
      Fazit: Man kann mit solchen Aussagen nicht arbeiten - und hier soll am Ende etwas stehen, mit dem man arbeiten kann. Es soll also ans "eingemachte" gehen und nicht an das vergammelte Kompott vom letzten Mittag.

      Wenn Du es schon weißt, dann frage doch nicht danach, sondern teile Dein Wissen der Welt mit! (Oder bist Du ein Lehrer? Die fragen auch immer nach Dingen, die sie schon wissen ... )

      Ich kenne die Antwort nicht komplett, sondern möchte, dass sich auch andere etwas Gedanken darüber machen - sonst nützt mir hier das Posten nichts und ich kann mein Wissen besser für mich behalten und selbst etwas damit anfangen.

      Denn in der Praxis ist es meiner Ansicht nach gerade nicht wichtig, was letztlich hinter der Zahl, die man "Handle" nennt, steckt, sondern nur, dass man darüber ein bestimmtes "Objekt" (Beispiele wurden ja schon genannt) gegenüber einer Schnittstelle (Satz von Funktionen) eindeutig identifizieren kann.

      Solange man sich im eigenen Prozess befindet, hast du damit recht - ansonsten nicht.

      Wie gesagt, das spiegelt meinen Wissenstand wieder - der ist nicht vollständig und an manchen Ecken wohl auch nicht korrekt.
      Ich fange noch einmal mit Franks Antwort an, die finde ich schon recht gut:
      Ein Handle ist ein Zeiger auf eine oder ein Schlüssel zu einer Datenstruktur, auf die ein Satz von Funktionen zugreift.

      Das worauf es mir ankommt, habe ich im Zitat markiert.
      Die Datenstruktur nennen wir mal hier Objekt (oder Object), die nennt Microsoft auch so, und dann wird es einfacher.

      Die API GetGuiResources bietet hier für den Anfang scheinbar etwas Hilfe. Über dies API kann man die Anzahl bestimmter Objekte ermitteln, die ein Prozess erzeugt hat. Der zweite Parameter gibt an, für welche Art von Objekt die Anzahl ermittelt werden soll - halt stopp - es gibt unterschiedliche Arten von Objekten?? Wenn es unterschiedliche Arten von Objekten gibt, gibt es vielleicht auch unterschiedliche Arten von Handles! Und genau das ist der Fall.

      Was ein Handle [B]genau im Einzellfall ist, ist also abhängig von dem Objekt, auf das ein Handle verweist.[/B] Es gibt Userhandles (Fensterobjekte), GDI Handles (Handles auf Objekte zum Zeichnen), Kernelhandles (Handles auf Objekte, die in der Regel durch APIs der Kernel32.dll erzeugt werden) und Handles auf Speicherbereiche - mehr sind mir im Augenblick nicht bekannt.

      DEsweiteren ist das, was ein Handle ist, abhängig davon, wie das jeweilige Betriebsystem diese Objekte verwaltet. Microsoft hat zwei Arten von Betriebsystemen herausgebracht
      a) Windows 95/98/ME
      b) NT basierende Betriebsysteme
      Was ein Handle ist, ist bei a) und b) nicht gleich - da ich von a) diesbezüglich keine Ahnung habe und die Technik veraltet ist, kann ich hier allerhöchsten Auskunft über b) geben :-). Wer für a) näheres weiß, kann sich gerne hier einbringen.
    • Es gibt Userhandles (Fensterobjekte), GDI Handles (Handles auf Objekte zum Zeichnen), Kernelhandles (Handles auf Objekte, die in der Regel durch APIs der Kernel32.dll erzeugt werden) und Handles auf Speicherbereiche - mehr sind mir im Augenblick nicht bekannt.


      Ja, aber ist dabei nicht egal, ab der Handle ein Zeiger auf einen Speicher ist, oder nur ein Schlüssel ist, um den passenden Zeiger aus einer Liste heraus zu finden, der wiederum nur ein Zeiger auf einen Speicher ist, oder vielleicht ein weiterer Schlüssel? :lupe:

      Ich denke, wenn ich "nur" API benutze, benötige ich dieses Wissen doch im Grunde gar nicht. Sollten in einer neuen Windowsversion Änderungen am Handle vorgenommen worden sein, so werden die ja innerhalb der API wieder ausgeglichen sein, um kompatibel zu bleiben. Für den Programmierer ändert sich dadurch (in der Regel) aber nichts.

      Anders ist es, wenn man nach deiner Methode vorgeht und bei den wesentlich Sachen gar nicht mit der API arbeitet, sondern sich mehr manuell durch den Handle-und Speicher-Dschungel hangelt, um seine Informationen zu erhalten. Diese Methode ist sicherlich sehr effektiv (Hut ab vor soviel Try&Error), da auch Beschränkungen durchbrochen werden können, die vom Betriebssystem (warum auch immer) auferlegt wurden.
      Gab es jedoch bei einem neuen Betriebssystem dort Änderungen, bist du gezwungen, in deinen Programmen Anpassungen vorzunehmen. Daher müsste wohl bei verschiedenen Systemen auch verschieden verfahren werden, und deine Programme an jedes neue System angepasst werden. Dieses Problem haben die Nur-API-Benutzer sicher seltener... ;-)

      Ich hoffe, ich hab das so mal überblickend zusammen gefasst. :cool:
      Gruß, Frank
    • Frabbing;682705 schrieb:

      Ich denke, wenn ich "nur" API benutze, benötige ich dieses Wissen doch im Grunde gar nicht.

      Das ist ein Irrtum, denn nur mit der API lassen sich da einige Sachen Zaubern, die man gar nicht für möglich hält - und das nur mit dem Wissen, was ein Handle ist.
      Es ist so richtiger: Wenn ich nichts spezielles programmieren will, benötige ich dieses Wissen nicht. Manch einer kommt ja auch mit dem zurecht, was XProfan von sich aus bietet - der braucht, um glücklich zu werden, auch keine API :D.

      Frabbing;682705 schrieb:


      Anders ist es, wenn man nach deiner Methode vorgeht und bei den wesentlich Sachen gar nicht mit der API arbeitet, sondern sich mehr manuell durch den Handle-und Speicher-Dschungel hangelt, um seine Informationen zu erhalten.

      Darum geht es mir hier nicht. Der "Dschungel", durch den man sich da wühlen müsste, befindet sich in der Regel im Kernel - und auf den haben normale Programme gar keinen Zugriff. Was du hier wohl im Auge hast, habe ich praktisch in PW-Show umgesetzt, um Vista auszutricksen. Das befindet sich aber auf einem ganz anderen Level - hat damals, als ich mich im XProfan Forum damit beschäftigt habe, ja sowieso nur Sebastian verstanden, was der Umstand im Prinzip sollte :lol:.

      Frabbing;682705 schrieb:


      Diese Methode ist sicherlich sehr effektiv (Hut ab vor soviel Try&Error), da auch Beschränkungen durchbrochen werden können, die vom Betriebssystem (warum auch immer) auferlegt wurden.

      Die "Zauberei" beschränkt sich bei mir vor allem auf "Zauberei" mittels API, der Try&Error geht gegen 0, da alles Neue auf dem selben Betriebsystem basiert.

      Frabbing;682705 schrieb:

      Daher müsste wohl bei verschiedenen Systemen auch verschieden verfahren werden, und deine Programme an jedes neue System angepasst werden.

      Das siehst du falsch. Microsoft hat zwei Arten von Betriebsystemen entwickelt: a) und b) -> siehe oben. Es geht hier um grundlegende Sachen von b). Solange Microsoft kein Betriebsystem c) entwickelt, wird sich da wohl nichts ändern. Bis Vista hat sich da jedenfalls nichts geändert.

      Frabbing;682705 schrieb:


      Dieses Problem haben die Nur-API-Benutzer sicher seltener... ;-)

      Irrtum, die schlagen sich auch mit a) und b) herum. :-D

      Es geht mir um das, was du anfänglich als "Schlüssel" bezeichnet hast und jetzt korrekter als "Liste" darstellst. :-)
      Um das mal weiterzuführen: Einige Objekthandles sind also direkte (oder indirekte?) Pointer auf einen (auslesbaren?) Speicherbereich, andere wiederum sind Einträge in einer Liste - oft der Index dieses Eintrages.
      Es geht mir darum, welche Objekthandles in welcher Liste zu finden sind und welche Objekthandles einfach nur Pointer sind. ;-)
      Welche Objekte gehören also, neben den Fenstern, zu den Userobjekten? Hat sich mal jemand damit befasst?
    • Es geht mir darum, welche Objekthandles in welcher Liste zu finden sind und welche Objekthandles einfach nur Pointer sind. :wink:
      Welche Objekte gehören also, neben den Fenstern, zu den Userobjekten? Hat sich mal jemand damit befasst?


      Ich bislang nicht. Informationen über solche Listen wären aber sicher nie verkehrt. :cool:
      Gruß, Frank
    • Frabbing;682833 schrieb:

      Ich bislang nicht. Informationen über solche Listen wären aber sicher nie verkehrt. :cool:

      Wie gesagt, hängt davon ab, was man tun möchte und ob man bereit ist, sich manche APIs auch mal "verkehrtherum" anzusehen.
      Soweit ich die habe, werden die Infos kommen - anhand einiger Beispielprogramme, damit man selbst nachsehen und mitdenken kann.
      Die Infos, von denen ich hier Rede, habe ich nirgendwo gelesen sondern basieren auf dem, was ich bei der Arbeit mit Windows selbst sehe - die sind also nicht komplett.
      Es gibt hier ja genug Leute, die viel mehr können, als nur Code von einer Ecke auf die andere zu kopieren. Vielleicht denkt ja manch einer von denen hier mit, bringt eigene Gedanken ein oder komplettiert hier oder da etwas - wäre schön. :-)
    • Hochinteressant... Mir fehlen nur leider sämtliche Voraussetzungen, Konzepte, Tools, Sprachregelungen, Übersichten, Konventionen, Algorithmenkenntnisse, programmatisch-philosophischen Konzepte, Durchblick und (vor allem) die Zeit dazu, das alles zu erforschen. Und ich fürchte, da bin ich beim einen oder anderen Punkt nicht allein.

      Der Witz daran ist: Ich war (in anderen Programmierdingen) früher ganz ähnlich, und konnte nicht verstehen, daß andere mir nicht mal ansatzweise folgen konnten. Allerdings hat sich dann herausgestellt, daß das auch ein Hindernis war, ein normales, bürgerliches Leben zu führen, sich anstädig um seine Alte zu kümmern und 16 Kinder in die Welt zu setzen. M.a.W.: Es ist eine Frage der Prioritäten.

      Nichts-desto-Trotz: Aus meiner Sicht bitte unbedingt weitermachen, solange das so tolle Resultate bringt! Man fühlt sich auch irgendwie gut, wenn da von den "M$-Programmiergöttern" gezeigt wird, daß sie auch nur mit Wasser kochen...

      Herzliche Grüße aus Wien
      P. Specht
      Win7-64HomPremSP1,XProfan11.2a,XPIA,JWasm,xpse,IntelCoreQuad2.5GHz/4GB/je1TB HD intern:esataBay:USB3
    • p. specht;682869 schrieb:

      Hochinteressant... Mir fehlen nur leider sämtliche Voraussetzungen, Konzepte, Tools, Sprachregelungen, Übersichten, Konventionen, Algorithmenkenntnisse, programmatisch-philosophischen Konzepte, Durchblick und (vor allem) die Zeit dazu, das alles zu erforschen. Und ich fürchte, da bin ich beim einen oder anderen Punkt nicht allein.

      Ist alles nicht so wichtig, das fehlt mir auch alles. :-D

      p. specht;682869 schrieb:


      Der Witz daran ist: Ich war (in anderen Programmierdingen) früher ganz ähnlich, und konnte nicht verstehen, daß andere mir nicht mal ansatzweise folgen konnten. Allerdings hat sich dann herausgestellt, daß das auch ein Hindernis war, ein normales, bürgerliches Leben zu führen, sich anstädig um seine Alte zu kümmern und 16 Kinder in die Welt zu setzen. M.a.W.: Es ist eine Frage der Prioritäten.

      :lol: Ich habe erst drei Kinder :(, fehlen also noch 13, um die ich mich heute abend erst mal vorrangig kümmern muss - ist also schon mal der richtige Denkansatz. :-D
    • Hehe, mit drei Kindern kann ich auch aufwarten!

      ... aber um zum Thema zurückzukommen: Eine nicht unwichtige Sache nach der Geburt eines Kindes ist die Namensgebung. Der Mensch braucht einen Namen, damit man ihn rufen und benennen kann. Der Name ist also quasi ein Handle. Innerhalb der Kleinfamilie reicht hier der Vorname, in der Großfamilie kommt dann, wenn der Namez.B.vom Großvater auf den Enkel vererbt wurde, ein Zusatz ("der Ältere", "der Jüngere", "junior", "senior", "Opa" oder auch eine Zahl) dazu, in noch größerem Rahmen dann der Nachname, ggf. ergänzt durch das Geburtsdatum. Und ganz eindeutig innerhalb der BRD wird die Person dann durch die Personalausweisnummer, die somit das Handle einer Person ist. ;-)

      Und im Windowsbereich fallen mir auf Anhieb noch einige weitere Handles ein, z.B. die Datei- und Stream-Handles oder im SQL-Bereich die Handles zu einer ODBC-Verbindung, dem ODBC-Environment oder einem SQL-Statement.

      Gruß
      Roland
      (dem zu dieser Tageszeit das Handle zum Morgenkaffee, vulgo: Henkel der Kaffeetasse, auch nicht ganz unwichtig ist)
      (Intel Duo E8400 3,0 GHz / 4 GB RAM / 250 GB HDD / ATI Radeon HD4770 512 MB / Windows Vista - ausgemustert zum Verkauf)
      AMD Athlon II X2 2,9 GHz / 8 GB RAM / 500 + 1000 GB HDD / ATI Radeon 3000 (onboard) / Windows 10(64) - XProfan X4


      http://www.xprofan.de
    • RGH;682971 schrieb:


      Und im Windowsbereich fallen mir auf Anhieb noch einige weitere Handles ein, z.B. die Datei- und Stream-Handles

      Ein Dateihandle gehört zu den "Kernelhandles" (-objekten), ist also in der gleichen Liste, wie zum Beispiel Prozesshandles und Threadhandles zu finden. Das Objekt heißt für Windows "FILE".

      RGH;682971 schrieb:


      oder im SQL-Bereich die Handles zu einer ODBC-Verbindung, dem ODBC-Environment oder einem SQL-Statement.

      Wo die einzuordnen sind, kann ich nicht genau sagen. Manche Objekte nennt Windows intern anders und fasst die Handles mit anderen zusammen - die stehen also in der gleichen Liste - da sich die Objekte von ihrem Aufbau her im Kernel nicht unterscheiden.

      RGH;682971 schrieb:


      (dem zu dieser Tageszeit das Handle zum Morgenkaffee, vulgo: Henkel der Kaffeetasse, auch nicht ganz unwichtig ist)

      Nach den noch fehlenden 13 Kindern :oops:, habe ich mich natürlich auch schon um dieses Handle gekümmert und mich ausgiebig damit befasst. :-)
    • a) Handles auf virtuelle Speicherbereiche

      Wo ich letztes mal stehen geblieben? Ah ja... Was ein Handle genau ist, hängt von der Art des Handles ab, um das es sich handelt. Ich fange mal mit Handles auf virtuelle Speicherbereiche an - ich denke, das ist für den Anfang am besten zu durchschauen.
      Mit der API GlobalAlloc lassen sich Speicherbereiche zuweisen und man bekommt ein Handle zurück. Ich fange mal so an:

      Quellcode

      1. $H Windows.PH
      2. Def @GlobalAlloc(2) !"KERNEL32","GlobalAlloc"
      3. Def @GlobalFree(1) !"KERNEL32","GlobalFree"
      4. Declare HMEM&
      5. LET HMEM&=@GlobalAlloc(~GMEM_FIXED | ~GMEM_ZEROINIT ,200)
      6. PRINT HMEM&
      7. Waitinput
      8. @GlobalFree(HMEM&)

      Wie man aus der MSDN Dokumentation entnehmen kann, liefert GlobalAlloc mit dem Flag ~GMEM_FIXED als erstem Parameter einen Pointer auf den jeweiligen Speicherbereich zurück, der mit GlobalAlloc zugewiesen wurde.
      Man Kann also direkt das hier tun:

      Quellcode

      1. $H Windows.PH
      2. Def @GlobalAlloc(2) !"KERNEL32","GlobalAlloc"
      3. Def @GlobalFree(1) !"KERNEL32","GlobalFree"
      4. DEF @CopyMemory(3) !"kernel32","RtlMoveMemory"
      5. DEF @ReadProcessMemory(5) !"KERNEL32","ReadProcessMemory"
      6. DEF @GetCurrentProcess(0) !"kernel32","GetCurrentProcess" 'Ermittel das Handle des aktiven Prozesses.
      7. Declare HMEM&,Text$,Ausgelesen#,Gelesen&
      8. LET HMEM&=@GlobalAlloc(~GMEM_FIXED | ~GMEM_ZEROINIT ,200)
      9. PRINT Str$(HMEM&)
      10. Let Text$ = "Hallo, hier bin ich!"
      11. DIM Ausgelesen#,len(Text$)+1
      12. @CopyMemory(HMEM&,addr(Text$),len(Text$)) 'auf HMEM& wird der String "Hallo, hier bin ich!" kopiert
      13. @ReadProcessMemory(@GetCurrentProcess(),HMEM&,Ausgelesen#,len(Text$),@addr(Gelesen&)) ' Mal scauen, ob der Text wirklich dort gelandet ist!
      14. Print @String$(Ausgelesen#,0)
      15. Waitinput
      16. @GlobalFree(HMEM&)
      17. Dispose Ausgelesen#
      Alles anzeigen

      Ein Handle ist in diesem Fall also ein direkter Pointer.
      Wenn man statt ~GMEM_FIXED aber ~GMEM_MOVEABLE, geht die Sache so aber nicht mehr - mn muss dann in dieser Art vorgehen:

      Quellcode

      1. $H Windows.PH
      2. Def @GlobalAlloc(2) !"KERNEL32","GlobalAlloc"
      3. Def @GlobalFree(1) !"KERNEL32","GlobalFree"
      4. DEF @CopyMemory(3) !"kernel32","RtlMoveMemory"
      5. DEF @ReadProcessMemory(5) !"KERNEL32","ReadProcessMemory"
      6. DEF @GetCurrentProcess(0) !"kernel32","GetCurrentProcess"
      7. Def @GlobalLock(1) !"kernel32","GlobalLock"
      8. Def @GlobalUnlock(1) !"kernel32","GlobalUnlock"
      9. Declare HMEM&,Text$,Ausgelesen#,Gelesen&,Pointer&
      10. LET HMEM&=@GlobalAlloc(~GMEM_MOVEABLE | ~GMEM_ZEROINIT ,200)
      11. Pointer&=@GlobalLock(HMEM&)
      12. PRINT "Handle="+@Str$(HMEM&)
      13. PRINT "Pointer="+@Str$(Pointer&)
      14. Let Text$ = "Hallo, hier bin ich!"
      15. DIM Ausgelesen#,len(Text$)+1
      16. @CopyMemory(Pointer&,addr(Text$),len(Text$)) 'auf Pointer& wird der String "Hallo, hier bin ich!" kopiert
      17. @ReadProcessMemory(@GetCurrentProcess(),Pointer&,Ausgelesen#,len(Text$),@addr(Gelesen&)) ' Mal scauen, ob der Text wirklich dort gelandet ist!
      18. Print @String$(Ausgelesen#,0)
      19. Waitinput
      20. @GlobalUnlock(HMEM&)
      21. @GlobalFree(HMEM&)
      22. Dispose Ausgelesen#
      Alles anzeigen

      Aber warum? Ist hier das Handle plötzlich kein Pointer mehr?
      Doch, ist es aber kein direkter Pointer!
      Hier der Beweis:

      Quellcode

      1. $H Windows.PH
      2. Def @GlobalAlloc(2) !"KERNEL32","GlobalAlloc"
      3. Def @GlobalFree(1) !"KERNEL32","GlobalFree"
      4. DEF @CopyMemory(3) !"kernel32","RtlMoveMemory"
      5. DEF @ReadProcessMemory(5) !"KERNEL32","ReadProcessMemory"
      6. DEF @GetCurrentProcess(0) !"kernel32","GetCurrentProcess"
      7. Def @GlobalLock(1) !"kernel32","GlobalLock"
      8. Def @GlobalUnlock(1) !"kernel32","GlobalUnlock"
      9. Declare HMEM&,Text$,Ausgelesen#,Gelesen&,Pointer&,Was_steht_auf_HMEM&
      10. LET HMEM&=@GlobalAlloc(~GMEM_MOVEABLE | ~GMEM_ZEROINIT ,200)
      11. Pointer&=@GlobalLock(HMEM&)
      12. PRINT "Handle="+@Str$(HMEM&)
      13. PRINT "Pointer="+@Str$(Pointer&)
      14. Let Text$ = "Hallo, hier bin ich!"
      15. DIM Ausgelesen#,len(Text$)+1
      16. @CopyMemory(Pointer&,addr(Text$),len(Text$)) 'auf Pointer& wird der String "Hallo, hier bin ich!" kopiert
      17. @ReadProcessMemory(@GetCurrentProcess(),HMEM&,@addr(Was_steht_auf_HMEM&),4,@addr(Gelesen&)) 'Ich kopiere das, was auf der Adresse HMEM& steht in eine Variable
      18. Print "Das steht auf HMEM&: "+@Str$(Was_steht_auf_HMEM&) 'und zeige diese an
      19. @ReadProcessMemory(@GetCurrentProcess(),Pointer&,Ausgelesen#,len(Text$),@addr(Gelesen&)) ' Mal scauen, ob der Text wirklich dort gelandet ist!
      20. Print @String$(Ausgelesen#,0)
      21. Waitinput
      22. @GlobalUnlock(HMEM&)
      23. @GlobalFree(HMEM&)
      24. Dispose Ausgelesen#
      Alles anzeigen

      [Blockierte Grafik: http://www.postimage.org/aV1crAwA.jpg]

      Ich denke, das ist eindeutig. Das Handle ist in diesem Fall ein Pointer, der auf einen Pointer verweist, der wiederum auf den String zeigt.
      Also:
      Handle -> Pointer -> String

      Hier noch was:

      Quellcode

      1. $H Windows.PH
      2. Def @GlobalAlloc(2) !"KERNEL32","GlobalAlloc"
      3. Def @GlobalFree(1) !"KERNEL32","GlobalFree"
      4. DEF @CopyMemory(3) !"kernel32","RtlMoveMemory"
      5. DEF @ReadProcessMemory(5) !"KERNEL32","ReadProcessMemory"
      6. DEF @GetCurrentProcess(0) !"kernel32","GetCurrentProcess"
      7. Def @GlobalLock(1) !"kernel32","GlobalLock"
      8. Def @GlobalUnlock(1) !"kernel32","GlobalUnlock"
      9. Declare HMEM&,HMEM2&,HMEM3&,HMEM4&
      10. LET HMEM&=@GlobalAlloc(~GMEM_MOVEABLE | ~GMEM_ZEROINIT ,200)
      11. PRINT "Handle 1 (Moveable)="+@Str$(HMEM&)
      12. LET HMEM2&=@GlobalAlloc(~GMEM_MOVEABLE | ~GMEM_ZEROINIT ,200)
      13. PRINT "Handle 2 (Moveable)="+@Str$(HMEM2&)
      14. LET HMEM3&=@GlobalAlloc(~GMEM_MOVEABLE | ~GMEM_ZEROINIT ,200)
      15. PRINT "Handle 3 (Moveable)="+@Str$(HMEM3&)
      16. LET HMEM4&=@GlobalAlloc(~GMEM_FIXED | ~GMEM_ZEROINIT ,200)
      17. PRINT "Handle 4 (Fixed)="+@Str$(HMEM4&)
      18. Waitinput
      19. @GlobalFree(HMEM&)
      20. @GlobalFree(HMEM2&)
      21. @GlobalFree(HMEM3&)
      22. @GlobalFree(HMEM4&)
      23. Dispose Ausgelesen#
      Alles anzeigen

      [Blockierte Grafik: http://www.postimage.org/gx1T4CJJ.jpg]

      Alle Moveable-Speicherhandles scheinen im selben Bereich zu liegen, ganz eng beieinander - stehen im Speicher also wie in einer Liste zusammen.
      Das Handle liefert also quasi den Einsprungspunkt (die Einsprungsadresse) in diese Liste, in der die Pointer stehen.

      Die Sache sieht im Augenblick ganz unscheinbar und nutzlos aus - es verbirgt sich hinter der ganzen Sache aber noch etwas anderes...
      Manche Handles, von dennen man es gar nicht auf den ersten Blick annimmt, sind ebenfalls solche Moveable-Speicherobjekte.
      Dazu gehören auch manche Fensterinhalte, wie zum Beispiel der Text in einem Edit (EM_GETHANDLE) oder ein Eintrag in einem Treeview (mal einfach nach Sachen im Fensterbereich schauen, die selbst kein Fenster sind, aber statt z.B. mit "Index" mit "Handle" bezeichnet werden).
      Anhand einer Message auf solche Objekte lässt sich mit Sicherheit ohne weiteres ein Einsprungspunkt in die angesprochene "Pointerliste" finden und so in einem fremden Prozess verwendete Speicherbereiche lokalisieren, Passwortedits auslesen etc. - ist wohl unter anderem ein kleines Sicherheitsproblem? Es wäre auf jedenfall zu überlegen, wo und wie man sensible Daten speichert 8O.

      Fazit: Handles auf virtuelle Speicherbereiche sind direkte oder indirekte Pointer.
    • Da du gerade eine meiner Lieblings-API seziert hast, sind das für mich persönlich keine Neuigkeiten. ;-)
      Mich würde noch interessieren, warum MS neben dem GlobalAlloc noch ein LocalAlloc eingeführt hat, aber beide Funktionen identisch sind? GlobalAlloc sagt ja schon vom Namen her aus, dass da mit Speicher gearbeitet wird, der überall erreichbar ist. Warum aber wurde das LocalAlloc-Konzept nicht weiter verfolgt? :cool:
      Gruß, Frank