Einzelnen Beitrag anzeigen

blackdrake

Registriert seit: 21. 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, 20: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