Der Windows Message Manager bietet Anwendungen die Möglichkeit, auf kontrollierte Nachrichtenflüsse zuzugreifen.
Der sogenannte Hook-Mechanismus (HOOK) von 'c4. Es gibt viele Arten von Hooks, die jeweils zum Erfassen eines bestimmten Nachrichtentyps oder -bereichs verwendet werden. Zum Beispiel: Tastaturnachrichten, Mausnachrichten usw. Wir nehmen hier nur die Verwendung von Tastatur-Hooks als Beispiel, um zu besprechen, wie man DLL-Programme unter DELPHI schreibt und wie man Tastatur-Hook-Funktionen in eigenen Programmen installiert und verwendet. Außerdem besprechen wir, wie man Daten teilt, wenn verschiedene Programme dieselbe DLL-Datei verwenden .
1. Anweisungen zum Schreiben von Hook-Filterfunktionen
Da sich die Hook-Filterfunktion in einem unabhängigen Modul befinden muss, müssen wir zunächst ein DLL-Framework generieren und diesem dann den Hook-Funktionscode und andere verwandte Funktionscodes hinzufügen. Hier nehmen wir zur Veranschaulichung das Schreiben der Tastatur-Hook-Filterfunktion als Beispiel. Die spezifischen Schritte sind wie folgt:
1. Erzeugen Sie zunächst einen DLL-Korb 2
2. Schreiben Sie Ihre eigene Tastatur-Hook-Filterfunktion
Die Hook-Filterfunktion muss eine Rückruffunktion sein und ihre Funktion hat die folgende Form:
functionKeyHookPRoc(
iCode:Integer;
wParam:WPARAM;
lParam:LPARAM): LRESULT; stdcall ;export;
Fügen Sie dem generierten DLL-Framework Ihre eigene Tastatur-Hook-Verarbeitungsfunktion hinzu, um Tastaturnachrichten zu verarbeiten.
Der Code lautet wie folgt:…
if(iCode>=0) dann beginnen
Ergebnis:=0; //Initialisierungsrückgabewert
//Fügen Sie hier Ihren eigenen Code hinzu
Ende sonst
beginnen
Ergebnis:=CallNextHook(hOldKeyHook,iCode,wParam,lParam);
//hOldKeyHook ist die gespeicherte ursprüngliche Tastaturfilterfunktion?
Ende;
3. Installieren Sie die Tastatur-Hook-Filterfunktion
Um einen Hook zu installieren, sollte die _fd-Filterfunktion die SetWindowsHookEx-Funktion aufrufen (die SetWindowsHook-Hook-Installationsfunktion für Windows 3.0 ist jetzt veraltet). Der Prototyp dieser Funktion lautet wie folgt:
HHOOK SetWindowsHookEx(
int idHook, // Installiert?_b3-Subtyp
HOOKPROC lpfn, //Hook-Filter??f Nummernadresse
HINWEIS hMod, //Aufgabenhandle
DWord dwThreadId // Der Zweck des Hooks
);
Es ist zu beachten, dass: ?_a8 häufig die MakeProcInstance-Funktion aufrufen sollte, um die Eintragsadresse der Präambel einer Ausgabefunktion zu erhalten, und diese Adresse dann als zweiten Parameter lpfn von SetWindowsHookEx verwenden sollte. Da Delphi jedoch einen „intelligenten Rückruf“ bereitstellt, kann MakeProcInstance weggelassen werden und der Name der Hook-Filterfunktion direkt als Eintragsadresse verwendet werden.
Wenn die Funktion _c3GetMessage oder PeekMessage der Anwendung Nachrichten aus der Nachrichtenwarteschlange liest oder Schlüsselnachrichten (WM_KEYDOWN oder WM_KEYUP) verarbeiten muss, ruft das System auf diese Weise die Hook-Filterfunktion KeyHookProc auf, um die Tastaturnachrichten zu verarbeiten.
4. Deinstallieren Sie die Hook-Filter-Funktion.
Wenn die Hook-Funktion nicht mehr benötigt wird, sollte UnHookWindowsHookProc aufgerufen werden, um den installierten Hook zu deinstallieren und Systemressourcen freizugeben.
Die vollständige Programmliste lautet wie folgt?_ba
Bibliotheks-SCHLÜSSELHAKEN;
verwendet Windows;
const BUFFER_SIZE=16*1024;
const HOOK_MEM_FILENAME='SAMPLE KEY_HOOK_MEM_FILE';
const HOOK_MUTEX_NAME ='SAMPLE KEY_HOOK_MUTEX_NAME';
Typ
TShared=Datensatz
Schlüssel: array[0..BUFFER_SIZE] of Char;
KeyCount: Ganzzahl;
Ende;
PShared=^TShared;
var
MemFile,HookMutex: THandle;
hOldKeyHook: HHook;
ProcSaveExit: Zeiger;
Geteilt: PShared;
//Tastatur-Hook-Filterfunktion
Funktion KeyHookProc(iCode: Integer; wParam: WPARAM ; lParam: LPARAM):LRESULT
; stdcall;
const KeyPressMask = $80000000;
beginnen
wenn iCode < 0 dann
Ergebnis := CallNextHookEx(hOldKeyHook, iCode, wParam, lParam)
sonst beginnen
if ((lParam and KeyPressMask)= 0) then // Taste gedrückt
beginnen
Shared^.Keys[Shared^.KeyCount]:=Char(wParam and $00ff);
Inc(Shared^.KeyCount);
wenn Shared^.KeyCount>=BUFFER_SIZE-1 dann Shared^.KeyCount:=0;
Ende;
iCode:=-1;
Ergebnis := CallNextHookEx(hOldKeyHook, iCode, wParam, lParam);
Ende;
Ende;
//Hook-Filterfunktion festlegen
Funktion EnableKeyHook: BOOL; export;
beginnen
Shared^.KeyCount:=0; //Tastaturzeiger initialisieren
Wenn hOldKeyHook=0, dann beginnen
hOldKeyHook := SetWindowsHookEx(WH_KEYBOARD,
KeyHookProc,
HInstanz,
0);
Ende;
Ergebnis := (hOldKeyHook <> 0);
Ende;
//Hook-Filterfunktion rückgängig machen
Funktion DisableKeyHook: BOOL;
beginnen
wenn hOldKeyHook<> 0 dann
beginnen
UnHookWindowsHookEx(hOldKeyHook); // Tastatur-Hook aushängen
hOldKeyHook:= 0;
Shared^.KeyCount:=0;
Ende;
Ergebnis := (hOldKeyHook = 0);
Ende;
//Die Anzahl der Tastenanschläge im Tastaturpuffer abrufen
Funktion GetKeyCount :Integer;
beginnen
Ergebnis:=Shared^.KeyCount;
Ende;
//Die Tasten des Tastaturpuffers abrufen
Funktion GetKey(index:Integer): Char ;
beginnen
Ergebnis:=Shared^.Keys[index];
Ende;
//Löschen Sie den Tastaturpuffer
Prozedur ClearKeyString;
beginnen
Shared^.KeyCount:=0;
Ende;
//DLL beendet den Verarbeitungsprozess
procedure KeyHookExit; far;
beginnen
wenn hOldKeyHook <> 0 dann DisableKeyHook;
UnMapViewOfFile(Shared); // Speicherbilddatei freigeben
CloseHandle(MemFile); // Bilddatei schließen
ExitProc := ProcSaveExit;
Ende;
exports // Ausgabefunktion definieren
EnableKeyHook,
DisableKeyHook,
GetKeyCount,
ClearKeyString,
GetKey;
beginnen
//DLL-Initialisierungsteil
HookMutex:=CreateMutex(nil,True,HOOK_MUTEX_NAME);
// Speicher freigeben, indem eine Speicher-Image-Datei erstellt wird
MemFile:=OpenFileMapping(FILE_MAP_WRITE,False,
HOOK_MEM_FILENAME);
wenn MemFile=0 dann
MemFile:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,
SizeOf(TShared) ,HOOK_MEM_FILENAME);
Shared:=MapViewOfFile(MemFile,File_MAP_WRITE,0,0,0);
ReleaseMutex(HookMutex);
CloseHandle(HookMutex);
ProcSaveExit := ExitProc; // Speichern Sie den ExitProc der DLL
ExitProc := @KeyHookExit; // Setze den neuen ExitProc der DLL
Ende.
//Ende des Quellcodes
2. Nutzen Sie die vorbereitete Tastatur-Hook-Filterfunktion in Ihrem eigenen Programm.
Nachdem die Hook-Funktion kompiliert wurde, ist sie eigentlich sehr einfach zu verwenden: Rufen Sie zunächst SetWindowsHookEx auf, um Ihre eigene Hook-Filterfunktion zu installieren, und speichern Sie gleichzeitig die ursprüngliche Adresse der Hook-Filterfunktion. Zu diesem Zeitpunkt kommt die Hook-Funktion ins Spiel und verarbeitet Tastaturnachrichten entsprechend Ihren Anforderungen. Wenn die Ausführung des Programms abgeschlossen ist oder die Überwachung von Tastaturmeldungen nicht mehr erforderlich ist, rufen Sie die UnHookWindowsHookProc-Funktion auf, um die installierte Hook-Funktion zu deinstallieren und die ursprüngliche Adresse der Hook-Filterfunktion wiederherzustellen.
Das Folgende ist ein Beispiel für die Verwendung der oben kompilierten Hook-Funktion:
Einheit Einheit1;
Schnittstelle
verwendet
Windows, Nachrichten, SysUtils, Klassen, Grafiken, Steuerelemente, Formulare, Dialoge,
StdStrgs, ExtStrgs;
Typ
TForm1 = Klasse(TForm)
Memo1: TMemo;
Panel1: TPanel;
bSetHook: TButton;
bCancelHook: TButton;
bReadKeys: TButton;
bClearKeys: TButton;
Panel2: TPanel;
Prozedur bSetHookClick(Sender: TObject);
procedure bCancelHookClick(Sender: TObject);
Prozedur bReadKeysClick(Sender: TObject);
procedure bClearKeysClick(Sender: TObject);
Ende;
var Form1: TForm1;
Durchführung
{$R *.DFM}
Funktion EnableKeyHook: BOOL; external 'KEYHOOK.DLL';
Funktion DisableKeyHook: BOOL; external 'KEYHOOK.DLL';
Funktion GetKeyCount: Integer; external 'KEYHOOK.DLL';
function GetKey(idx:Integer) : Char ; external 'KEYHOOK.DLL';
Prozedur ClearKeyString; externe 'KEYHOOK.DLL';
procedure TForm1.bSetHookClick(Sender: TObject); // Tastatur-Hook setzen 7ó
beginnen
EnableKeyHook;
bSetHook.Enabled :=False;
bCancelHook.Enabled:=True;
bReadKeys.Enabled :=True;
bClearKeys.Enabled :=True;
Panel2.Caption:='Tastatur-Hook wurde gesetzt';
Ende;
procedure TForm1.bCancelHookClick(Sender: TObject); // Tastatur-Hook deinstallieren
beginnen
DisableKeyHook;
bSetHook.Enabled :=True;
bCancelHook.Enabled:=False;
bReadKeys.Enabled :=False;
bClearKeys.Enabled :=False;
Panel2.Caption:='Tastatur-Hook ist nicht gesetzt';
Ende;
procedure TForm1.bReadKeysClick(Sender: TObject); // Tastenanschlagsverlauf abrufen
var i:Integer;
beginnen
Memo1.Lines.Clear; // Tastaturverlauf in Memo1 anzeigen
für i:=0 bis GetKeyCount-1 tun
Memo1.Text:=Memo1.Text+GetKey(i);
Ende;
procedure TForm1.bClearKeysClick(Sender: TObject); // Tastaturverlauf löschen
beginnen
Memo1.Clear;
ClearKeyString;
Ende;
Ende.
//Ende des Quellcodes
3. Implementierung von Shared Memory in DLL unter Windows95
In der DLL-Datei, in der sich die obige Hook-Funktion befindet, muss gemeinsamer Speicher verwendet werden, dh alle Tastenanschlagdatensätze werden im selben Datensegment gespeichert. Warum machen wir das? Dies liegt daran, dass sich die DLL-Aufrufmethode von Windows95 von der von Windows3.X unterscheidet. Wenn sich jeder Thread bei einer Dynamic Link Library anmeldet, übergibt er ein neues Instanzhandle (dh das Handle des DLL-Datensegments) an die Dynamic Link Library. Dadurch können sich die verschiedenen Instanzen der DLL nicht gegenseitig stören, es bringt jedoch einige Schwierigkeiten mit sich, wenn alle DLL-Instanzen einen Satz von Variablen gemeinsam nutzen. Um dieses Problem zu lösen, lösen wir es hier, indem wir eine Speicherzuordnungsdatei erstellen. Das heißt, es werden OpenFileMapping, CreateFileMapping und Windows verwendet
MapViewOfFile implementiert drei Funktionen. So verwenden Sie es:
…
MemFile ist ein THandle-Typ, Shared ist ein Zeigertyp und HOOK_MEM_FILENAME ist eine konstante Zeichenfolge.
…
MemFile:=OpenFileMapping(FILE_MAP_WRITE,False,
HOOK_MEM_FILENAME); // Speicherzuordnungsdatei öffnen
if MemFile=0 then //Wenn das Öffnen fehlschlägt?_c2 Eine Speicherzuordnungsdatei erstellen
MemFile:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,
SizeOf(TShared) ,HOOK_MEM_FILENAME);
//Dateien Variablen zuordnen
Shared:=MapViewOfFile(MemFile,File_MAP_WRITE,0,0,0);
Bisher wissen Sie bereits, wie einfach es ist, Hook-Funktionen in Delphi zu kompilieren. Abschließend muss ich alle daran erinnern: Obwohl die Hook-Funktion relativ leistungsfähig ist, beeinträchtigt sie bei unsachgemäßer Verwendung die Effizienz des Systems erheblich. Vermeiden Sie daher die Verwendung von System-Hooks. Bei der Verwendung ist besondere Vorsicht geboten, damit der Betrieb des Systems möglichst wenig beeinträchtigt wird.
[Ende des vollständigen Textes]