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/)
-   -   Hook.dll und programm liefern kein ergebnis (https://www.delphipraxis.net/99095-hook-dll-und-programm-liefern-kein-ergebnis.html)

Chaosente 6. Sep 2007 18:28


Hook.dll und programm liefern kein ergebnis
 
hi also ich wollte mal nen kleinen keylogger programmieren mit dem hintergrund, bestimmte befehle einfach so eintippen zu können egal wo, soweit bin ich aber noch lange nicht. Denn irgendwie klappt das versenden von der dll zum programm nciht...

hier mein code..

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

const
WM_KeyLogMessage = WM_USER + 23;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Memo1: TMemo;
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
    procedure OnMyMessage(var Msg: TMessage); message WM_KeyLogMessage;
  public
    { Public-Deklarationen }
  end;


  TInstallHook = function(Hwnd: THandle): Boolean; stdcall;
  TUninstallHook = function: Boolean; stdcall;



var
  Form1: TForm1;
  InstallHook: TInstallHook;
  UninstallHook: TUninstallHook;
  lib: Cardinal;

implementation

{$R *.dfm}

procedure TForm1.OnMyMessage(var Msg:TMessage);
begin
memo1.Lines.Add(inttostr(msg.lparam));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
lib := LoadLibrary('keyboardhook.dll');
  if lib <> INVALID_HANDLE_VALUE then begin
    InstallHook := GetProcAddress(lib, 'InstallHook');
    UnInstallHook := GetProcAddress(lib, 'UninstallHook');
  end; // else ERROR
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
freelibrary(lib);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
installhook(self.Handle);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
uninstallhook;
end;

end.
und die dll
Delphi-Quellcode:
library Keyboardhook;

uses
  Windows,
  Messages;

var
  HookHandle: Cardinal = 0;
  WindowHandle: Cardinal = 0;
  WM_KeyLogMessage: WM_USER + 23;

function KeyboardHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM):
 LRESULT; stdcall;
begin
//es ist ebenfalls möglich die Bearbeitung an eine Bedingung zu knüpfen
//it's possible to call CallNextHookEx conditional only.
  Result := CallNextHookEx(HookHandle, nCode, wParam, lParam);
  case nCode < 0 of
    TRUE: exit; //wenn code kleiner 0 wird nix gemacht
                //if code smaller 0 nothing has to be done
    FALSE:
      begin
       sendmessage(HookHandle, WM_KeyLogMessage, wParam, lParam);
//Hier kann jetzt alles bearbeitet werden
//Here one can work with the parameters
      end;
  end;
end;

function InstallHook(Hwnd: Cardinal): Boolean; stdcall;
begin
  Result := False;
  if HookHandle = 0 then begin
//Erstmal Hook installieren
//First install the hook
    HookHandle := SetWindowsHookEx(WH_KEYBOARD, @KeyboardHookProc,
    HInstance, 0);
//Uebergebenes Fensterhandle sichern
//Save the given window handle
    WindowHandle := Hwnd;
    Result := TRUE;
  end;
end;

function UninstallHook: Boolean; stdcall;
begin
//Hook aus der Hookchain entfernen
//Uninstall hook from hook chain
  Result := UnhookWindowsHookEx(HookHandle);
  HookHandle := 0;
end;

exports
//Installations- und Deinstallationsroutine exportieren
//Export the installation and deinstallation routine
  InstallHook,
  UninstallHook;
end.
Vllt kennst sich ja jemand besser aus damit als ich und sieht sofort was ich falsch mache. denn eigentlich sollte im memo immer die gedrückte taste erscheine... danke schonmal

stoxx 6. Sep 2007 18:44

Re: Hook.dll und programm liefern kein ergebnis
 
windowhandle ist bei einem globelen Hook immer Null .. mit MMF's arbeiten

Chaosente 6. Sep 2007 21:00

Re: Hook.dll und programm liefern kein ergebnis
 
Tut mir leid ich versteh nur bahnhof! kann mir jemand erklären was das heißen soll?

DGL-luke 6. Sep 2007 21:04

Re: Hook.dll und programm liefern kein ergebnis
 
Die DLL wird in jeden laufenden prozess geladen. Und zwar jeweils einzeln. Das heißt, in jeder ihrer Instanzen (außer in der ovn deinem eigenen programm), wird WindowHandle auf 0 stehen.

Das heißt, du musst dir eine andere Möglichkeit suchen, um mit deinem Hauptprogramm zu kommunizieren. Zum Beispiel Memory Mapped Files.

Chaosente 6. Sep 2007 21:45

Re: Hook.dll und programm liefern kein ergebnis
 
Okay das war ein tipfehler, ich hab HookHandle reingeschrieben, obwohl da WIndowHandle stehen sollte, jetzt kommt auch was an, allerdings sehr merkwürdige zahlen und immer gleich vier davon, was hat das zu bedeuten, bzw wie find ich raus welche buchstaben damit gemient sind?

Chaosente 6. Sep 2007 22:04

Re: Hook.dll und programm liefern kein ergebnis
 
also mittlerweile weis ich was hier bei mir ankommt es sind die ascii werte der tasten, aber immer viermal das 3mal zu viel

DGL-luke 6. Sep 2007 22:09

Re: Hook.dll und programm liefern kein ergebnis
 
Also erstensmal sieht das (wegen der Kommentare) aus wie 1 zu 1 kopiert. Du wirst dich ein wenig mehr in die Materie vertiefen müssen.

Zweitens hast du ganz sicher Probleme, dein Hauptprogramm zu finden. Da gibts mehrere Möglichkeiten, das zu lösen. MMF wurde bereits erwähnt.

Drittens sagt dir die MSDN Library einiges: http://msdn2.microsoft.com/en-us/library/ms644984.aspx

ASCII-Codes dürften das mitnichten sein. Bzw. noch einiges mehr.

Viertens werden Doppelposts hier nicht gern gesehen. DU kannst dein Posts editieren.

Chaosente 6. Sep 2007 22:17

Re: Hook.dll und programm liefern kein ergebnis
 
Also das meiste von oben hat sich erledigt, die buchstaben kommem also an werden auch umgewandelt.. nur werden sie mehr als einmal gesendet...

DGL-luke 6. Sep 2007 22:20

Re: Hook.dll und programm liefern kein ergebnis
 
Hm... da kann ich dir leider nicht helfen. Hast du mal ne Demo, um das zu reproduzieren?

Chaosente 6. Sep 2007 22:27

Re: Hook.dll und programm liefern kein ergebnis
 
ja klar kein problem, also hier mal der code der unit...
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

const
  WM_KeyLogMessage = WM_USER + 23;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Memo1: TMemo;
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
    procedure OnKeyLogMessage(var Msg:Tmessage); message WM_KeyLogMessage;
  public
    { Public-Deklarationen }
  end;


  TInstallHook = function(Hwnd: THandle): Boolean; stdcall;
  TUninstallHook = function: Boolean; stdcall;

var
  Form1: TForm1;
  InstallHook: TInstallHook;
  UninstallHook: TUninstallHook;
  lib: Cardinal;

implementation

{$R *.dfm}

procedure TForm1.OnKeyLogMessage(var msg:Tmessage);
begin
memo1.Lines.Add(chr(msg.wparam));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
lib := LoadLibrary('keyboardhook.dll');
  if lib <> INVALID_HANDLE_VALUE then begin
    InstallHook := GetProcAddress(lib, 'InstallHook');
    UnInstallHook := GetProcAddress(lib, 'UninstallHook');
  end; // else ERROR
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
freelibrary(lib);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
installhook(self.Handle);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
uninstallhook;
end;

end.
.dll
Delphi-Quellcode:
library Keyboardhook;

uses
  Windows,
  Messages;

const
  WM_KeyLogMessage = WM_USER + 23;

var
  HookHandle: Cardinal = 0;
  WindowHandle: Cardinal = 0;


function KeyboardHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM):
 LRESULT; stdcall;
begin
//es ist ebenfalls möglich die Bearbeitung an eine Bedingung zu knüpfen
//it's possible to call CallNextHookEx conditional only.
  Result := CallNextHookEx(HookHandle, nCode, wParam, lParam);
  case nCode < 0 of
    TRUE: exit; //wenn code kleiner 0 wird nix gemacht
                //if code smaller 0 nothing has to be done
    FALSE:
      begin
       sendmessage(WindowHandle, WM_KeyLogMessage,wparam,lparam);
//Hier kann jetzt alles bearbeitet werden
//Here one can work with the parameters
      end;
  end;
end;

function InstallHook(Hwnd: Cardinal): Boolean; stdcall;
begin
  Result := False;
  if HookHandle = 0 then begin
//Erstmal Hook installieren
//First install the hook
    HookHandle := SetWindowsHookEx(WH_KEYBOARD, @KeyboardHookProc,
    HInstance, 0);
//Uebergebenes Fensterhandle sichern
//Save the given window handle
    WindowHandle := Hwnd;
    Result := TRUE;
  end;
end;

function UninstallHook: Boolean; stdcall;
begin
//Hook aus der Hookchain entfernen
//Uninstall hook from hook chain
  Result := UnhookWindowsHookEx(HookHandle);
  HookHandle := 0;
end;

exports
//Installations- und Deinstallationsroutine exportieren
//Export the installation and deinstallation routine
  InstallHook,
  UninstallHook;
end.
geht das so? oder wie meintest du das mit der demo? mitlerweile kommen öfter auch mal noch mehr buchstaben an.... ganz merkwürdig
vllt findest du ja was

DGL-luke 6. Sep 2007 23:17

Re: Hook.dll und programm liefern kein ergebnis
 
aaalso...

wie erwartet:

aktiviere ich ein anderes fenster, funktioniert der hook schon nicht mehr. er ist im moment also auf deinen prozess beschränkt, in dem dein fensterhandle bekannt ist.

Mehrere Tastendrücke schickt er, weil er für das drücken der taste, während die taste gedrückt ist, und vor und nach dem loslassen jeweils einmal die hookproc aufruft. oder so ähnlich.

Ich hab aus der Hookproc mal folgendes gemacht:

Delphi-Quellcode:
function KeyboardHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM):
LRESULT; stdcall;
begin
//es ist ebenfalls möglich die Bearbeitung an eine Bedingung zu knüpfen
//it's possible to call CallNextHookEx conditional only.
  Result := CallNextHookEx(HookHandle, nCode, wParam, lParam);
  case nCode < 0 of
    TRUE: exit; //wenn code kleiner 0 wird nix gemacht
                //if code smaller 0 nothing has to be done
    FALSE:
      begin
       if (lparam shr 30) = 0 then
         sendmessage(WindowHandle, WM_KeyLogMessage,wparam,lparam);
//Hier kann jetzt alles bearbeitet werden
//Here one can work with the parameters
      end;
  end;
end;
Damit kommen nur noch zwei an.
Deine kleine Hausaufgabe: Sag mir, warum das so ist.
Tipp: per "shr 30" schiebe ich alle bits außer 30 und 31 aus dem integer, d.h. nur 30 und 31 bleiben als MSB oder LSB übrig (wie endian das ganze ist, will ich jetzt nicht nachlesen)

Olli 7. Sep 2007 03:56

Re: Hook.dll und programm liefern kein ergebnis
 
Argh, ich muß das Hook-Tut wirklich dringend überarbeiten. Gibt's hier jemanden der sich ein paar Lorbeeren als Coautor verdienen will?

SirThornberry 7. Sep 2007 06:17

Re: Hook.dll und programm liefern kein ergebnis
 
ich finde du solltest das tutorial NICHT überarbeiten. Denn ansonsten wird wirklich nur kopiert und niemand bemüht sich in die Materie einzusteigen.
So wie es jetzt ist geht es im Ansatz und wer mehr machen will muss sich genauer damit auseinander setzen um es ordentlich hinn zu bekommen.
Wenn du ein fertiges Copy-Paste-Tutorial wird einfach nur kopiert (ohne zu verstehen) und der quelltext drum herum hat dann in etwa das gleiche Niveau. Resulatat wäre das ständig Programme wegen Script-Kiddi-Hooks abstürzen..

stoxx 7. Sep 2007 06:31

Re: Hook.dll und programm liefern kein ergebnis
 
Zitat:

Zitat von Chaosente
Tut mir leid ich versteh nur bahnhof! kann mir jemand erklären was das heißen soll?


es bedeutet einfach, dass Deine Variable WindowHandle keine globale Variable darstellt, wie Du fälschlicherweise angenommen hast.
Du brauchst also einen zentralen Ort, wo Du die Variable abspeichern kannst.
Es müssen Dich also genau dieselben Fragen beschäftigen, als wenn zwei programme daten austauschen wollen.
Grund ist eben, die DLL wird von jedem Process geladen. Es existieren also genau so viele Variablen, wie auch die DLL geladen wurde...


Delphi-Quellcode:
var
  HookHandle: Cardinal = 0;
  WindowHandle: Cardinal = 0;

http://assarbad.net/stuff/tutorials/...k_tutorial.pdf

da steht eigentlich alles drin ..

DGL-luke 7. Sep 2007 10:23

Re: Hook.dll und programm liefern kein ergebnis
 
Zitat:

Zitat von Olli
Argh, ich muß das Hook-Tut wirklich dringend überarbeiten. Gibt's hier jemanden der sich ein paar Lorbeeren als Coautor verdienen will?

*meld*

Reicht es, wenn ich schon meinen eigenen Keyboard-LL-Hook geschrieben hab (Ich bin sogar irgendwie an meinen Monitorprozess zurückgekommen. Muss ich mal schauen, ob ich die alten Sourcen noch find)?

@SirT: Die Überarbeitung von Tutorials ist nie schlecht.

Chaosente 7. Sep 2007 14:47

Re: Hook.dll und programm liefern kein ergebnis
 
Hab ich das richtig verstanden, das wenn ich in der dll, die daten einfach in eine datei schreiben würde sich keine probleme ergeben würde, aber wenn ich sie an mein fenster schicken möchte den umweg mit MMF gehen muss?

DP-Maintenance 7. Sep 2007 18:07

DP-Maintenance
 
Dieses Thema wurde von "Matze" von "Programmieren allgemein" nach "Windows API / MS.NET Framework API" verschoben.
Delphi-Frage

Olli 7. Sep 2007 18:43

Re: Hook.dll und programm liefern kein ergebnis
 
Zitat:

Zitat von Chaosente
Hab ich das richtig verstanden, das wenn ich in der dll, die daten einfach in eine datei schreiben würde sich keine probleme ergeben würde, aber wenn ich sie an mein fenster schicken möchte den umweg mit MMF gehen muss?

Kommt auf die Daten an.

Also, wenn du in der Hook/Callbackfunktion bist, laeuft dein Code ja im Kontext eines anderen Prozesses. Du musst also die Prozessgrenzen ueberwinden. Das geht zwar mit Nachrichten, aber die zu verschickenden Daten sind dann normalerweise auf 2x 32bit beschraenkt. Um also mehr Daten zu verschicken, bietet sich eindeutig MMF an.



@Luke: Wie kennst du dich mit LaTeX aus? Wenn garnicht, dann muessten wir die Zusammenarbeit einfach im unformatierten Textformat machen. Ich will sicherstellen, dass es PDF-Dateien mit Vektorgrafiken sind und als Grundlage zum Hooktut muss auch das DLL-Tut nochmal aufgefrischt werden. Bist du dabei? Code wuerde ich ohnehin sowohl fuer C als auch fuer C++ und eben Delphi schreiben wollen. Bei Delphi waerst du bis Oktober auf dich gestellt, da ich im Moment keine Installation und eben auch kein Installationsmedium habe und TurboDelphi kommt mir nicht auf die Platte.

stoxx 8. Sep 2007 13:40

Re: Hook.dll und programm liefern kein ergebnis
 
Zitat:

Zitat von Chaosente
Hab ich das richtig verstanden, das wenn ich in der dll, die daten einfach in eine datei schreiben würde sich keine probleme ergeben würde, aber wenn ich sie an mein fenster schicken möchte den umweg mit MMF gehen muss?

ja das ist richtig, in eine Datei (Text) könntest Du Deine zu loggenden Daten hineinschreiben.
Du könntest Dir auch Dein Handle in eine Text Datei speichern, theoretisch. und dann dort auslesen, damit Du weißt, wo Du mit Sendmessage Deine Daten hinschicken musst.
Würde aber niemand machen :-)

Memory-Mapped-Files würden Dir da aber auch noch nix nützen, (Sind ja Files) in den Memory gemappte Files eben..
aber Microsoft bietet Dir mit der Option

MemFile := CreateFileMapping($FFFFFFFF.nil ...) an, Deine Daten auch prozeß-übergreifend gemeinsam zu nutzen, womit der Datenbereich in der Auslagerungsdatei von Windows angelegt wird (bzw. irgendwo im Cache vorher :-)

Somit können die "vielen" Dll's von jedem Programm (Prozeß), was gehookt wird, auch Dein WindowHandle wieder lesen ...
und die DLL kann dann mit dem richtigen Handle eine Sendmessage verschicken

Mit MMF könntest Du wiederum eine noch größer Datenstruktur (Record) anlegen, und diese mit einer Funktion in der DLL "GetData(var Data: TMyData)" auslesen. Und mit Sendmessage teilst Du Deinem Programm nur mit, dass jetzt neue Daten da sind ...


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:21 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