Announcement

Collapse
No announcement yet.

verdammt mausereignisse von fremden Programmen abfangen ! ? natürlich

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • verdammt mausereignisse von fremden Programmen abfangen ! ? natürlich

    hi ich bin Moses

    ich durchstöbere das forum und finde lauter fragen im 'WIN32 API' bereich

    Wie fange ich mausereignisse von anderen Programmen ab ? (...!?...)

    und die Antwort

    Mit Hilfe der API f. Hook ! (...!?...)

    Irgend wie glaube ich keiner weiss das so genau kann das sein
    ich suche auch die Antwort dafür
    aber irgenwie ??????

    íhr was zum Thema:
    Dazu installiert man mit der Funktion SetWindowsHookEx einen Windows-Hook, den man nach Benutzung UnhookWindowsHookEx mit wieder freigibt. In der c't 5/99 war ein Artikel. der das Komma am Ziffernblock abfängt und den dann in einen Punkt umwandelt. Das ganze war in einer DLL mit zwei Funktionen implementiert, die Heino Tiedemann nach Delphi übersetzt hat.

    Im Hauptprogramm muß nun noch z.B. im OnCreate des Hauptformulars die DLL importiert werden und der Hook aktiviert werden, beim Beenden des Programms wird der Hook wieder deaktiviert und die DLL wird aus dem Speicher gekickt:

    type
    TMainForm = class(TForm)
    [..]
    private
    { Private-Deklarationen }
    Success: Boolean;
    {Handle der DLL}
    hDLL: HINST;
    {Handle auf die DLL-Funktion 'DLLInit'}
    InitProc : procedure (hDLL: HINST; install: BOOL); stdcall;
    [..]

    procedure TMainForm.FormCreate(Sender: TObject);
    begin
    //DLL Einbinden
    hDLL := LoadLibrary('PunktDLL.dll');
    if hDLL = 0 then
    begin
    MessageBox(0,'PunktDLL.dll nicht gefunden',
    'kritischer Fehler',MB_OK or MB_ICONSTOP);
    Success := FALSE;
    //Wird Im OnDestroy abgefragt
    Application.Terminate
    end
    else begin
    Success := TRUE;
    //Funktion aus DLL laden
    InitProc := GetProcAddress(hDLL,'DLLInit');
    //Funktion aus DLL aufrufen; TRUE schaltet den Hook ein
    InitProc(hDLL,TRUE)
    end
    end;

    procedure TMainForm.FormDestroy(Sender: TObject);
    begin
    //DLL Freigeben
    If Success then
    //Funktion aus DLL aufrufen; FALSE schaltet den Hook aus
    InitProc(hDLL,FALSE);
    if hDLL <> 0 then FreeLibrary(hDLL);
    end;

    ---------------------------------------------------------------------------
    library PunktDLL;

    (****************************
    * Punkt (Hook-DLL) *
    * Übersetzt aus c't 5/99 *
    * von Heino Tiedemann *
    ****************************)
    uses
    SysUtils,
    Classes,
    windows,
    Messages;

    var
    MyHook: HHOOK; {Handle auf Die Hook Funktion}

    {*********************
    * Hook Funktion *
    * (Callback) *
    **********************}
    Function PunktHook(code: Integer; // hook code
    HwParam: WPARAM; // virtual-key code
    HlParam: LPARAM // keystroke-message information
    ): LRESULT; Stdcall;
    var Scancode : LPARAM;
    myWnd : HWND;
    begin
    if Code = HC_ACTION then
    begin
    if HwParam=VK_DECIMAL then
    begin
    scancode := OemKeyscan(Ord('.')) shl 16; //Scanncode vom punkt ermitteln
    HlParam := hLParam and $FF00FFFF; //durchmaskieren aus einem
    HlParam := HlParam or scancode; //Komma einen Punkt machen
    hwParam := 190;

    MyWnd := GetFocus(); //HensterHandle besorgen
    if MyWnd=0 then //Etwa eine Dosbox
    MyWnd := GetForegroundWindow();//dann geht Diese Methode

    if (hlParam and $8000000) = 0 then
    postMessage(myWnd,WM_KeyDown,hwParam,hlParam);
    if (hlParam and $8000000) = $8000000 then
    postMessage(myWnd,WM_KeyUp,hwParam,hlParam);

    Result := 1;
    end else
    Result := CallNextHookEx(myHook,code,HwParam,HlParam);
    end else
    Result := CallNextHookEx(myHook,code,HwParam,HlParam);
    end;

    {************************************
    * Initialisierung der HOOK-Fuktion *
    *************************************}
    procedure DLLInit(hDLL: HINST; install: BOOL); stdcall
    begin
    if install = TRUE
    then
    //Hook setzen; mit callbackfunktion "PunktHook"
    myHook := SetWindowsHookEx(WH_KEYBOARD,PunktHook,hDLL,0)
    e

  • #2
    Hi

    Obige Routine funktioniert ganz gut, eigentliches Problem: sie kann nur eine ganz definierte Aufgabe erledigen. Will man mehr, also während der Laufzeit des Hooks diesem Parameter zur De/Aktivierung oder Konfiguration übergeben, wird es kompliziert. Das liegt daran das im grunde ein Hook nur für einen einzigsten prozess gültig ist. Um nun einen Systemweiten Hook zu installieren lädt Windows diese Hook-DLL in jeden Prozessbereich aller laufenden Prozesse, bzw. aller Prozesse die auch z.B. das keyboard nutzen. Prozesse die einen bestimmten Hook/Feature nicht nutzen, greifen auch nicht auf die Hook-DLL zurück. Nun, da die Hook-DLL nun in mehreren prozessen installiert wurde nutzt die Hook-DLL intern für jeden prozess ein EIGENES datensegment, eine Actvierungs/deactivierungs Funktion oder Konfigurationsfunktion der Hook-DLL würde somit NUR die Einstellungen des aktuellen aufrufenden prozesses modifizieren. Lösung: shared datensegmente, unter C,C++ sind diese schon integriert in den Compiler, d.h. alle C Compiler unterstützen das pragma "shared" und somit können Variablen/Konstanten der Hook-DLL für ALLE prozesse gültig sein. Mit delphi muß dieses simuliert werden indem man die selbe Methode der C Compiler nutzt: "Memory Mapped Files".
    ABER das reicht noch nicht: gerade beim keyboardhook ist es wichtig bestimmte prozesse AKTIV auszufilteren z.B. die Shell, da sonst durch die schlechte Implementierung dieser MS-Shell das System abstürtzt oder z.B. der Mausehook wird von der Shell mit Strafpunkten belegt, hooks Du Dich nicht korrekt rein wird der Explorer nicht mehr mit der Maus bedienbar und beim Schließen eines Explorer fensters kackt dieses komplett ab ! usw. usw.

    Wohlgemerkt, Microsoft sagt: ALLE Hookfunktionalität IST Debuggingfunktionalität und sollte IN fertigen Anwendungen NICHT verwendet werden. Zudem nach Aussage von MS unterliegt genau dieser Bereich des Betriebssystemes enormen Unterschieden/Veränderungen. Grundsätzlich heist das, Finger weg Microsoft will der einzigste legale Nutzer dieser Funktionen bleiben.

    Gruß Hage

    Comment


    • #3
      Ach nochwas: Der Explorer stürtzt NICHT ab weil der Hook NICHT richtig implementiert wurde, sondern der Explorer ! Ich habe mich lange und sinnloserweise damit beschäftigt, bis ich es wirklich gut und richtig zum laufen gebracht hatte. Allerdings traten immer wieder Probleme auf. Fazit: eine globale Hook_DLL sollte beim Windowsstart geladen werden UND NIEMEHR deaktiviert/entladen werden, ansonsten stürzen einige programme wie Explorer/WinWord/Excel etc. die aktiv auch hooken ab !!

      Übrigens in deiner Methode wird BEWUSST PostMessage() benutzt, gerade weil mit einer sofortigen, notwendigen Reaktion mit SendMessage() es zu Abstürzen kommt. PostMessage() verhindert aber im Grunde online, ohne zeitverzug die Keys zu ändern, heist PostMessage() sendet den Key zur aufrufenden Anwednung, diese modifiziert diesen, der eigentliche Hook ist aber schon längst wieder verlassen worden und somit der originale, unmodifiziert Key vom gehookten Prozess verarbeitet wurden !! PostMessage() nutzt also garnichts. Desweiteren wird mit GetFocus() das aktive fenster ermittelt, funktioniert aber aus einem Systemhook NICHT ! da GetFocus(), getKeyState() oder z.B. auch GetKeyboardState() IMMER Threadbezogen korrekt arbeiten.
      Desweiteren werden vom System bestimmte API-Funktionen für Hooks gesperrt, liefen also keine Werte zurück usw. usw.

      Gruß Hagen

      PS: es gibt also doch welche die wissen wie's geht, das ist auch unbedingt nötig falls ein Systemhook richtig funktionieren soll

      Comment

      Working...
      X