Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Verständnisfrage zu SetWindowsHookEx und CallNextHookEx (https://www.delphipraxis.net/93871-verstaendnisfrage-zu-setwindowshookex-und-callnexthookex.html)

SirThornberry 12. Jun 2007 15:14


Verständnisfrage zu SetWindowsHookEx und CallNextHookEx
 
Hallo,

Wenn man mit SetWindowsHookEx einen Hook installiert bekommtman ja ein Hookhandle zurück geliefert und die HookProcedure wird in jeden Prozess geladen (inclusive dll)?! (ich hoffe das ist nicht schon die erste stelle wo ich mich irre).

In der HookProcedure ist es ja laut Hilfe dann des öfteren nötige bzw. wird dringend empfohlen, die Funktion CallNextHookEx aufzurufen welche eben das HookHandle haben will. Aber woher bekomm ich das Handle, schließlich hab ich das ja nur innerhalb der DLL-Instanz in der ich den Hookinstalliere, oder?
Delphi-Quellcode:
library APIHook;

uses
  Windows;

var
  HookHandle: THandle;

function HookProc(code: Integer; ALParam: Integer; AWParam: Integer): Integer; stdcall;
begin
  //kann ich hier auf HookHandle zugreifen? Eigentlich ist dieses doch nur in der DLL-Instanz initialisiert in welcher der Hook instanziert wurde.
  result := CallNextHookEx(HookHandle, ALParam, AWParam);
end;

//diese funktion wird nur in im Prozess aufgerufen der den Hook installiert?!
procedure StartHook; stdcall;
begin
  //Da die Funktion nur dem Prozess aufgerufen wird welche den Hook installiert sollte HookHandle ja auch nur in diesem Prozess verfügbar sein bzw. initialisiert sein
  HookHandle := SetWindowsHookEx(WH_GETMESSAGE, @GetMsgProc, HInstance, 0);
end;

procedure StopHook; stdcall;
begin
  UnhookWindowsHookEx(HookHandle);
  UnHookFunctions;
end;

exports
  StartHook,
  StopHook;

begin
  HookFunctions;
end.

Robert Marquardt 12. Jun 2007 15:16

Re: Verständnisfrage zu SetWindowsHookEx und CallNextHookEx
 
Das ist genau der Punkt bei globalen Hooks. Der Hook-Handle muss in allen Kopien der DLL zugreifbar sein. Bei Visual C++ kann man per Pragma die Variable in ein shared Segment bugsieren. Bei Delphi nutzt man ma einfachsten ein Memory Mapped File.

SirThornberry 12. Jun 2007 15:23

Re: Verständnisfrage zu SetWindowsHookEx und CallNextHookEx
 
ok :-D
Daraus ergibt sich das nächste Problem (vielleicht seh ich das auch einfach nru schlimmer als es ist):
Und war ist der Hook ja aktiv sobald die Funktion SetWindowsHookEx abgearbeitet wurde, also auch bevor das Result von SetWindowsHookEx in meiner Variablen bzw. einem MemoryMappedFile steckt. Das ist zwar nur im Bruchteil von Millisekunden so aber letztendlich ist dadurch ja für kurze Zeit das HookHandle undefiniert und kann nicht verwendet werden. Gibt es dafür eine Lösung?

[OT]
Wie macht es der C-Compiler möglich das die Variable in allen Prozessen verfügbar ist, wird diese dann auch in einem gemeinsam genutzen Speicherbereich abgelegt?
[/OT]

Robert Marquardt 12. Jun 2007 15:45

Re: Verständnisfrage zu SetWindowsHookEx und CallNextHookEx
 
Der Hook ist nicht aktiv bevor die Zuweisung stattgefunden hat. Da passt Windows schon auf.
Visual C++ erlaubt einfach das man in der Programmsource Anweisungen an den Linker platziert. Es wird die Variable in ein eigenes Segment verlagert, statt dem normalen DATA oder BSS. Das Segment bekommt das shared flag und wird damit in alle Kopien der DLL eingeblendet. Das CODE-Segment funktioniert ja genauso. Die DLL-Kopien nutzen natuerlich den Code gemeinsam.

SirThornberry 12. Jun 2007 15:55

Re: Verständnisfrage zu SetWindowsHookEx und CallNextHookEx
 
Wenn die DLL-Kopien den Code gemeinsam nutzen, wäre es dann nicht auch möglich das ich zur Laufzeit die Hookprocedure patche so dass, das Hookhandle direkt drin steht?
Also:
1.) SetWindowsHookEx aufrufen
2.) die Adresse von der HookProcedure holen
3.) das Hookhandle an das entsprechende Offset bedingt aus der adresse von Schritt schreiben.

Dürfte das nicht auch funktionieren?

jbg 12. Jun 2007 17:41

Re: Verständnisfrage zu SetWindowsHookEx und CallNextHookEx
 
Nein, denn das CodeSegment ist CopyOnWrite. Das heißt, wenn du etwas daran änderst, wird die Speicherseite in deinen Prozess kopiert und die originale bleibt für die anderen Prozesse erhalten.

Robert Marquardt 12. Jun 2007 18:40

Re: Verständnisfrage zu SetWindowsHookEx und CallNextHookEx
 
Es geht aber trotzdem. Bei CodeGear in der Codesammlung steht ein Tool von Petr Vones das nachtraeglich ein Shared Segment einpatcht. ich hab jetzt gerade keine Lust das zu suchen, aber "Petr Vones" und "shared segment" fuer die Suche bei CodeGear sollte es finden.

SirThornberry 12. Jun 2007 18:42

Re: Verständnisfrage zu SetWindowsHookEx und CallNextHookEx
 
hmm, ich hätte es sonst mit mmf's gelöst.

bitsetter 7. Mär 2008 17:40

Re: Verständnisfrage zu SetWindowsHookEx und CallNextHookEx
 
Zitat:

Zitat von Robert Marquardt
Das ist genau der Punkt bei globalen Hooks. Der Hook-Handle muss in allen Kopien der DLL zugreifbar sein. Bei Visual C++ kann man per Pragma die Variable in ein shared Segment bugsieren. Bei Delphi nutzt man ma einfachsten ein Memory Mapped File.

Hallo,

es wird ja sehr oft auf das Mouse- und Tastatur-Hooks Tutorial von Olli verwiesen das würde ja bedeuten, dass der Code nicht ganz korrekt ist. Da er einen globalen Hook installiert, müsste er zum Beispiel mit MMF arbeiten damit auf das korrekte Hook-Handle in allen Kopien der DLL zugegriffen werden kann. Das Hook-Handle wird ja für die Funktion CallNextHookEx() benötigt.
Ansonsten wird das Handle nur innerhalb der DLL-Instanz in der ich den Hook installiere ungleich Null sein.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:19 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz