AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL ab

Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL ab

Offene Frage von "blackdrake"
Ein Thema von blackdrake · begonnen am 3. Dez 2008 · letzter Beitrag vom 8. Dez 2008
Antwort Antwort
Seite 1 von 3  1 23   
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#1

Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL ab

  Alt 3. Dez 2008, 21:48
Hallo.

Ich habe mit Unterstützung des Forums und Tutorials einen Maus/Tastaturhook geschrieben, der Tastaturereignisse erkennt und die Maus für eine gewisse Zeit sperrt.

Ich habe jetzt ein großes Problem gefunden: Bei meinem Testsystem - Vista - stürzt Internet Explorer aufgrund der Hook-DLL ab.

Die Fehlermeldung scheint irgendetwas mit Buffer-Overrun zu tun zu haben (was bei Delphi aber unwahrscheinlich ist) und ich weiß echt nicht, woran es liegt. Weiß jemand weiter?

Zitat:
Produkt
Internet Explorer

Problem
Funktioniert nicht mehr

Datum
01.12.2008 17:52

Status
Bericht gesendet

Problemsignatur
Problemereignisame: APPCRASH
Anwendungsname: iexplore.exe
Anwendungsversion: 7.0.6001.18000
Anwendungszeitstempel: 47918f11
Fehlermodulname: atl_hooks.dll
Fehlermodulversion: 0.0.0.0
Fehlermodulzeitstempel: 2a425e19
Ausnahmecode: c0000005
Ausnahmeoffset: 00003c5e
Betriebsystemversion: 6.0.6001.2.1.0.768.3
Gebietsschema-ID: 1031
Zusatzinformation 1: 6718
Zusatzinformation 2: 3fab1118733fd991e6b3f07ef0d90511
Zusatzinformation 3: 7591
Zusatzinformation 4: 18cb549cf9e0d1d27b18034a323f5b99
Die DLL:

Delphi-Quellcode:
library atl_hooks;

uses
  Windows,
  Messages;

var
  Mouse_HookHandle: Cardinal = 0;
  Keyboard_HookHandle: Cardinal = 0;

  WM_ANYKEYPRESSED: Cardinal = 0;
  WM_LMB_KEY_CONFIRM: Cardinal = 0;
  WM_RMB_KEY_CONFIRM: Cardinal = 0;

  TargetHandle, hMapping: Cardinal;
  pView: pointer;

const
  MappingGUID = '{C8B1CCD2-4B00-45F1-9B96-9B82E086D473}';
  MsgTimeOut = 10;
  RES_LMB_LOCKED = 10;
  RES_RMB_LOCKED = 11;

type
  ULONG_PTR = ^DWORD;

  PKBDLLHOOKSTRUCT = ^TKBDLLHOOKSTRUCT;
  TKBDLLHOOKSTRUCT = packed record
    vkCode : DWORD;
    scanCode : DWORD;
    flags : DWORD;
    time : DWORD;
    dwExtraInfo : ULONG_PTR;
  end;

const
  WH_KEYBOARD_LL = 13; // WINUSER.H

function KeyboardHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
  //res: Cardinal;
  KHSp: PKBDLLHOOKSTRUCT;
  KHSd: TKBDLLHOOKSTRUCT;
begin
  Result := CallNextHookEx(Keyboard_HookHandle, nCode, wParam, lParam);
  case nCode < 0 of
    TRUE: exit;
    FALSE:
      begin
        // Strg/Shift+Maustaste ist legitim für Mehrfachselektion
        if (wParam = WM_KEYDOWN) then
        begin
          KHSp := PKBDLLHOOKSTRUCT(lParam);
          KHSd := KHSp^;
          if not
              (
                ( KHSd.vkCode = 160 ) and ( KHSd.scanCode = 42 ) or // Shift Left
                ( KHSd.vkCode = 162 ) and ( KHSd.scanCode = 29 ) or // Ctrl Left
                ( KHSd.vkCode = 161 ) and ( KHSd.scanCode = 54 ) or // Shift Right
                ( KHSd.vkCode = 163 ) and ( KHSd.scanCode = 29 ) // Ctrl Right
              )
          then
            //SendMessageTimeOut(TargetHandle, WM_ANYKEYPRESSED, wParam, lParam,
            // SMTO_ABORTIFHUNG or SMTO_BLOCK, MsgTimeOut, res);
            SendMessage(TargetHandle, WM_ANYKEYPRESSED, wParam, lParam);
        end;
      end;
  end;
end;

function MouseHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
  res: Cardinal;
begin
  Result := CallNextHookEx(Mouse_HookHandle, nCode, wParam, lParam);
  case nCode < 0 of
    TRUE: exit;
    FALSE:
      begin
        // Handelt es sich um einen linken Mausklick?
        if (wParam = WM_LBUTTONUP) or (wParam = WM_NCLBUTTONUP) or
           (wParam = WM_LBUTTONDOWN) or (wParam = WM_NCLBUTTONDOWN) or
           (wParam = WM_LBUTTONDBLCLK) or (wParam = WM_NCLBUTTONDBLCLK) then
        begin
          SendMessageTimeOut(TargetHandle, WM_LMB_KEY_CONFIRM, wParam, lParam,
                             SMTO_ABORTIFHUNG or SMTO_BLOCK, MsgTimeOut, res);

          // Host-Application verweigert den Tastenklick
          if res = RES_LMB_LOCKED then
          begin
            Result := 1; // Maustaste verwerfen
          end;
        end;

        // oder um einen rechten Mausklick?
        if (wParam = WM_RBUTTONUP) or (wParam = WM_NCRBUTTONUP) or
           (wParam = WM_RBUTTONDOWN) or (wParam = WM_NCRBUTTONDOWN) or
           (wParam = WM_RBUTTONDBLCLK) or (wParam = WM_NCRBUTTONDBLCLK) then
        begin
          SendMessageTimeOut(TargetHandle, WM_RMB_KEY_CONFIRM, wParam, lParam,
                             SMTO_ABORTIFHUNG or SMTO_BLOCK, MsgTimeOut, res);

          // Host-Application verweigert den Tastenklick
          if res = RES_RMB_LOCKED then
          begin
            Result := 1; // Maustaste verwerfen
          end;
        end;
      end;
  end;
end;

function InstallHooks(Hwnd: Cardinal): Boolean; stdcall;
var
  mouseh, keybh: boolean;
begin
  keybh := false;
  mouseh := false;

  case Mouse_HookHandle of
    0: begin
        Mouse_HookHandle := SetWindowsHookEx(WH_MOUSE, @MouseHookProc, HInstance, 0);
        mouseh := true;
      end;
  end;
  case Keyboard_HookHandle of
    0: begin
        Keyboard_HookHandle := SetWindowsHookEx(WH_KEYBOARD_LL, @KeyboardHookProc, HInstance, 0);
        keybh := true;
      end;
  end;

  Result := keybh and mouseh;
end;

function UninstallHooks: Boolean; stdcall;
var
  mouseh, keybh: boolean;
begin
  mouseh := UnhookWindowsHookEx(Mouse_HookHandle);
  keybh := UnhookWindowsHookEx(Keyboard_HookHandle);
  Mouse_HookHandle := 0;
  Keyboard_HookHandle := 0;
  Result := keybh and mouseh;
end;

exports
  InstallHooks,
  UninstallHooks;

procedure Initalisation(Reason: DWORD);
begin
  case Reason of
    DLL_PROCESS_ATTACH:
      begin
        hMapping := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, MappingGUID);
        pView := MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);

        TargetHandle := PCardinal(pView)^;
      end;
    DLL_PROCESS_DETACH:
      begin
        // Wird das auch tatsächlich aufgerufen??
        UnmapViewOfFile(pView);
        CloseHandle(hMapping);
      end;
  end;
end;

begin
  WM_ANYKEYPRESSED := RegisterWindowMessage('WM_ANYKEYPRESSED');
  WM_LMB_KEY_CONFIRM := RegisterWindowMessage('WM_LMB_KEY_CONFIRM');
  WM_RMB_KEY_CONFIRM := RegisterWindowMessage('WM_RMB_KEY_CONFIRM');

  Initalisation(DLL_PROCESS_ATTACH); // Ist das so OK?
end.
Anbei auch das reproduzierbare Projekt.

Gruß
blackdrake
Angehängte Dateien
Dateityp: zip atl_buggy_110.zip (529,4 KB, 16x aufgerufen)
Daniel Marschall
  Mit Zitat antworten Zitat
Relicted

Registriert seit: 24. Jan 2006
Ort: Iserlohn
646 Beiträge
 
Delphi 10.4 Sydney
 
#2

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a

  Alt 3. Dez 2008, 22:48
Ist bei mir unter Vista x64 auch reproduzierbar der Fehler.
Liegt vielleicht daran, dass der Iexplorer in ner speziellen abgeschotteten Umgebung läuft unter Vista? Nur ne Vermutung.

Gruß
reli
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#3

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a

  Alt 3. Dez 2008, 22:50
Hallo. Ja, irgendwas macht IE anders, aber trotzdem darf es keinen Fehler geben. Andere Hook-DLLs funktionieren aber irgendwie. Und meine DLL macht ja nichts großartig besonderes. Deswegen vermute ich, dass ich irgendwo etwas mit dem Speicher, z.B. der Mem-Map-File unsauber gemacht habe.
Daniel Marschall
  Mit Zitat antworten Zitat
Relicted

Registriert seit: 24. Jan 2006
Ort: Iserlohn
646 Beiträge
 
Delphi 10.4 Sydney
 
#4

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a

  Alt 3. Dez 2008, 23:17
kommentier mal einzelne Parts aus... Versuch mal mit nur Maushook und mit nur Keyboardhook den IE zu starten. So kannst es evtl. eingrenzen.

Gruß
reli
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#5

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a

  Alt 4. Dez 2008, 17:00
Prüfe mal, ob du einen gültigen Zeiger für pView erhältst. Wenn du nicht genügend Rechte hast, sollte bereits hMapping ungültig sein und MapViewOfFile gibt nil zurück.

Deine Prozedur wird übrigens nicht aufgerufen, wenn die DLL beendet wird. Dazu musst du die globale Variable DllProc setzen.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a

  Alt 4. Dez 2008, 18:02
bzgl.
Zitat von blackdrake:
Delphi-Quellcode:
begin
  ...
  Initalisation(DLL_PROCESS_ATTACH); // Ist das so OK?
end.
schau mal hier Controling DLL loading

und ob eine bestimmter Teil in einer DLL auch ausgeführt wird, das bekommt man am einfachsten raus, wenn man in dem Teil eine Ausgabe in einer Datei produziert (Log-Datei). Wenn da, dann war die DLL auch da

cu

Oliver
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#7

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a

  Alt 4. Dez 2008, 21:27
Hallo.

Attach und Detach werden nun ausgeführt, nachdem ich DLLProc gesetzt habe.

Seitdem ich auf pView <> nil prüfe, stürzt Internet-Explorer nicht mehr ab.

Das Problem ist aber, dass pView = nil wird. Das ist jetzt natürlich ziemlich problematisch und auch das Schreiben in die Logdatei schlägt beim Aufruf von InternetExplorer mit dem RunTime Error 5 (File inaccessable) ab. Was kann ich tun?

Zusätzliche Frage: Wie ist es möglich, den DLL-Teilprozess zu terminieren, wenn pView doch mal nil werden sollte?

Der DLL-Code sieht nun so aus:

Delphi-Quellcode:
procedure Log(N: string); // debug
var
  f: TextFile;
begin
  AssignFile(f, 'c:\meinlog.txt');
  Append(f);
  WriteLn(f, N);
  CloseFile(f);
end;

procedure DllMain(Reason: DWORD);
begin
  case Reason of
    DLL_PROCESS_ATTACH:
      begin
        hMapping := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, MappingGUID);
        pView := MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);

Log('Attach');
        if pView <> nil then
          TargetHandle := PCardinal(pView)^; // ToDo: Wenn nil, sollte DLL terminiert werden
if pView = nil then
log('Fehler 1');
      end;
    DLL_PROCESS_DETACH:
      begin
Log('Detach');
        if pView <> nil then
          UnmapViewOfFile(pView);
if pView = nil then
log('Fehler 2');
        CloseHandle(hMapping);
      end;
  end;
end;

begin
  WM_ANYKEYPRESSED := RegisterWindowMessage('WM_ANYKEYPRESSED');
  WM_LMB_KEY_CONFIRM := RegisterWindowMessage('WM_LMB_KEY_CONFIRM');
  WM_RMB_KEY_CONFIRM := RegisterWindowMessage('WM_RMB_KEY_CONFIRM');

  DllProc := @DllMain;
  DllProc(DLL_PROCESS_ATTACH);
end.
Nachtrag! Ignoriert man diesen Fehler, wird trotz des pView=nil das Tastaturereignis (WH_KEYBOARD_LL SendMessage) an die Host-Applikation (TargetHandle) weitergegeben. Das Maus-Ereignis (WH_MOUSE SendMessageTimeOut) wird aber nicht weitergegeben, die Maustaste kann also nicht durch die Host-Applikation gesperrt werden! Seltsamerweiße funktioniert das ähnliche Programm MTANWT einwandfrei mit Internet Explorer. Was ist das Geheimnis?

Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#8

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a

  Alt 4. Dez 2008, 21:54
Um die DLL in der Initialisierung abzuwürgen, reicht es, ExitCode auf einen Wert ungleich Null zu setzen.
Was du tun kannst, um das Problem zu beheben? Setze beim Erstellen des File Mappings die Rechte, sodass alle Benutzer Lesezugriff haben. Es ist übrigens auch nicht nötig, in der DLL Schreibzugriff zu verlangen.
Eine andere Frage: Warum hältst du Handle und View des Mappings so lange offen? Du kannst diese Ressourcen direkt nach dem Lesen von TargetHandle wieder freigeben. Dann brauchst du auch keine DllProc.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#9

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a

  Alt 4. Dez 2008, 22:07
Hallo.

Danke für den Hinweis. Ich habe jetzt auf die DLL-Proc verzichtet und habe nun folgenden Code:

Delphi-Quellcode:
begin
  WM_ANYKEYPRESSED := RegisterWindowMessage('WM_ANYKEYPRESSED');
  WM_LMB_KEY_CONFIRM := RegisterWindowMessage('WM_LMB_KEY_CONFIRM');
  WM_RMB_KEY_CONFIRM := RegisterWindowMessage('WM_RMB_KEY_CONFIRM');

  hMapping := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, MappingGUID);
  pView := MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);

  if pView <> nil then
  begin
    TargetHandle := PCardinal(pView)^;

    UnmapViewOfFile(pView);
    CloseHandle(hMapping);
  end
  else
  begin
    ExitCode := 1;
  end;
end.
Das mit dem Schreibzugriff verstehe ich nicht ganz.

Die Host-APP legt die MemMap an mittels FILE_MAP_WRITE und schreibt das eigene WindowHandle hinein:

Delphi-Quellcode:
hMapping := CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, 4, MappingGUID);
pView := MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, 0);

PCardinal(pView)^ := Handle;
Die DLL öffnet die MemMap mit FILE_MAP_READ und liest das Handle.

Dann habe ich doch in der DLL keinen Fehler gemacht, oder?

Und bezüglich des Exit-Code ungleich Null: Wird die DLL dann automatisch entladen, wenn in der Initialisierung der ExitCode gesetzt wurde? Die Host-Applikation müsste dann doch trotzdem die DLL-Export-Funktion InstallHooks() aufrufen, was ja bedeutet, dass die DLL trotzdem arbeitet, obwohl ein Fehler festgestellt wurde.

PS: Internet Explorer läuft nun in eine Endlosschleife.

Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#10

Re: Tastatur/Maus-Hook: Internet Explorer stürzt wegen DLL a

  Alt 4. Dez 2008, 22:18
Wenn du eine DLL mit LoadLibrary lädst und die DllProc dieser DLL false zurückgibt (in Delphi wird das in System.pas über ExitCode geregelt), gibt LoadLibrary nil zurück. Wie sich das bei Hook-Dlls verhält (bedenke, dass jede Applikation ihre eigene DLL-Instanz hat!), weiß ich nicht, ich vermute aber mal, dass Windows dort pragmatisch vorgeht und die DLL nur in diesen Prozess nicht lädt.

Bezüglich der Rechte: Ausschlaggebend sind die angegebenen Rechte bei OpenFileMapping. Du solltest dir in deinem Hauptprogramm Security Attributes erstellen, die allen Benutzern Lese-Zugriff erlaubt, und diesen dann als Parameter für CreateFileMapping angeben. Eine solche Struktur lässt sich sehr elegant mit der JWSCL erzeugen; direkt über die API ist es etwas schwieriger.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:38 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