![]() |
Tastendruck im Hintergrund registrieren und Loggen
Moin moin liebe DPler,
ich habe folgendes Problem: und zwar haben wir in der Firma USB Panels auf denen die F1 bis F24 Tasten (also alle Funktionstasten)ausgelagert sind. Nun haben wir vor kurzem festgestellt das es hin und wieder mal einzelne Tasten nicht funktionieren. Um einen möglichen Fehler zu finden bzw. auszuschließen soll jetzt also ein Keylogger her, der im Hintergrund läuft und alle Tastendrücke (der F Tasten) mit Zeit mit loggt. Soweit so gut. Grundsätzlich habe ic hdas auch aber ich habe noch dasProblem: das meien Anwendung dazu im Vordergrund sein muss, damit sie auf den Tastendruck reagiert... und ich konnte noch keine Lösung dafür finden Hat da jemand einen Tipp oder Ratschlag? Danke! |
Re: Tastendruck im Hintergrund registrieren und Loggen
Wie kann man mit einem Keylogger nicht funktionierende Tasten loggen?
|
Re: Tastendruck im Hintergrund registrieren und Loggen
Hallo
Ein Keyboard Hook könnte eine Lösung sein. |
Re: Tastendruck im Hintergrund registrieren und Loggen
Ein Keylogger/Keyhook kann in der Hinsicht nützlich sein bzw. helfen da immer vier tasten zu einander gehören und wenn dann eine Taste mehrfach gerückt wird, bzw. die "Reihenfolge" durcheinander kommt dann hat man zumindest schon mal einen Anhaltspunkt. ZUmal das ganze noch mit einem Counter verbunden wird.
edit: ganz doofe Frage: Worin besteht der Unterschied zwischen einem Keylogger und eineme Keyhook? |
Re: Tastendruck im Hintergrund registrieren und Loggen
Zitat:
Mit einem Hook kannst du die Tasten global abfangen. |
Re: Tastendruck im Hintergrund registrieren und Loggen
Oder anders gesagt: der Hook ist das wie, und der Logger das was
|
Re: Tastendruck im Hintergrund registrieren und Loggen
ah gut....
Danke für die Tipps... werd mir dann wohl mal das Hook Tutorial vom DelphiTreff anschauen |
Re: Tastendruck im Hintergrund registrieren und Loggen
So nachem ich mich jetzt schon etwas mit Hooks auseinandergesetzt habe, jetzt doch noch mal eine Frage:
Ich habe folgende Funktion, die aufgerufen wird, was ich jetzt noch nicht so ganz gerafft habe sind die folgenden Punkte: 1. Wieso wird die gedrückte Taste viermal eingetragen, bzw. warum wird bei Funktionstasten nicht F1 etc angezeigt, sondern z, w, etc.? und 2. wie kann ich daraus jetzt ein Logfile mit Datum und Uhrzeit machen? (Mein Versuch mit
Delphi-Quellcode:
ist kläglich an eiskaltem schweigen gescheitert...)
WriteLog(Inttostr(lParam));
Delphi-Quellcode:
Besten Dank im voraus!!
function KeyboardHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var sizewritten, hFile: LongWord; begin Result := CallNextHookEx(HookHandle, nCode, wParam, lParam); case nCode < 0 of TRUE: exit; FALSE: begin hFile := CreateFile('C:\LogFile.log', GENERIC_WRITE or GENERIC_READ, 0, nil, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if hFile <> INVALID_HANDLE_VALUE then try SetFilePointer(hFile, 0, nil, FILE_END); //WriteFile(hFile, lParam, sizeof(lParam), sizewritten, nil); WriteFile(hFile, wParam, sizeof(wParam), sizewritten, nil); finally CloseHandle(hFile); end; end; end; end; |
Re: Tastendruck im Hintergrund registrieren und Loggen
Hallo T.E., ich hoffe nicht, dass ich mal das Teil in einer Signatur eines Virenscanners finden werde!!
Delphi-Quellcode:
lg. Astatfunction KeyboardHookProc(code: Integer; wparam: WPARAM; lParam: LPARAM): LResult; stdcall; var LastKey: Char; KeyState: TKeyboardState; KeyboardLayout: HKL; Key: Word; begin Result := CallNextHookEx(HookHandle, Code, wParam, lParam); if Code < 0 then Exit else begin KeyboardLayout := GetKeyboardLayout(0); GetKeyboardState(KeyState); if ToAsciiEx(wParam, MapVirtualKeyEx(wParam, 2, KeyboardLayout), KeyState, @LastKey, 0, KeyboardLayout) > 0 then Key := Ord(LastKey) else Key := wParam; if (lParam and $80000000) = 0 then if not (wParam in [16, 17, 18]) then PostMessage(_hwndTarget, WM_USER + 8888, Key, GetActiveWindow); end; end; //-- WndProc der Empfänger Application procedure TForm1.WndProc(var message: TMessage); var sStr: String; begin if message.Msg = WM_USER + 8888 then begin // KeyHook Nachricht case message.wParam of VK_BACK : sStr := 'VK_BACK'; VK_TAB : sStr := 'VK_TAB'; VK_CLEAR : sStr := 'VK_CLEAR'; VK_RETURN : sStr := 'VK_RETURN'; VK_SHIFT : sStr := 'VK_SHIFT'; VK_CONTROL : sStr := 'VK_CONTROL'; VK_MENU : sStr := 'VK_MENU'; VK_PAUSE : sStr := 'VK_PAUSE'; VK_CAPITAL : sStr := 'VK_CAPITAL'; VK_NUMLOCK : sStr := 'VK_NUMLOCK'; else sStr := string(Chr(message.wParam)); end; WriterLog(time + sStr); end; inherited WndProc(message); end; |
Re: Tastendruck im Hintergrund registrieren und Loggen
Muss ein globaler Keyboard-Hook nicht in einer DLL liegen?
|
Re: Tastendruck im Hintergrund registrieren und Loggen
Zitat:
|
Re: Tastendruck im Hintergrund registrieren und Loggen
Zitat:
Zitat:
|
Re: Tastendruck im Hintergrund registrieren und Loggen
Hallo,
weil ich mich heute mit einem Kollegen über Hotkeys unterhalten habe, möcht ich mal schnell diesen ![]() Man könnte ja die F-Tasten hotkeyen und bräuchte nicht im Vordergrund sein. |
Re: Tastendruck im Hintergrund registrieren und Loggen
Soo.... ich bin heute wieder dazu gekommen mit dem Tool weiterzumachen, allerdings gibt es dabei ein paar Fragen die sich aufgetan haben.
1. TForm.WndProc in der Server Anwendung ja folgendermaßen aufgerufen:
Delphi-Quellcode:
wird von Delphi mit einer Warnung beehrt:
procedure TForm1.WndProc(var message: TMessage);
Zitat:
2. Was mir mehr Kopfzerbrechen bereitet: Ich habe die Prozedur KeyboardHookProc in der DLL stehen und exportiere um Sie in der Serveranwendung aufrufen zu können. Seit ich diesen Schritt vollführt habe, wird die Anwendung kurz gestartet und gleich wieder beendet... Warum? Ich habe so weit ich weiß keinen Code in der Anwendung, der diese Beendet ohne, das nicht wenigstens der Button schließen oder halt das Kreuz verwendet wird. Kann mir dazu jemand was sagen, oder muss ic hdoch erst mal den gesamten Code posten? Besten Dank im voraus!! |
Re: Tastendruck im Hintergrund registrieren und Loggen
Hast du F1 benutzt und geschaut was dir damit gesagt wird?
|
Re: Tastendruck im Hintergrund registrieren und Loggen
Jop dort wurde als mögliche Lösung dieses Problems das umbenennen vorgeschlagen.
Aber hier mal die vorgeschlagenen Lösungsmöglichkeiten: Zitat:
|
Re: Tastendruck im Hintergrund registrieren und Loggen
Moin ...,
ich hatte das Bsp. von Astat auch gestestet - vorwiegend aber um das mal mit ner MMf zu testen - und es lief bei mir mit
Delphi-Quellcode:
override
|
Re: Tastendruck im Hintergrund registrieren und Loggen
Okay das ist doch schon mal gut zu wissen ;)
Aber nun zu der anderen Frage: Zitat:
Hat auch hierzu jemand einen Geistesblitz? |
Re: Tastendruck im Hintergrund registrieren und Loggen
So jetzt bin ich schon mal einen kleinen Schritt weiter:
und zwar scheint das Problem darin zu liegen, das mein Programm damit nicht klarkommt, das ich die Funktion aus der DLL Exportiere und dann in der Server App aufrufe: Export aus der DLL sieht folgendermaßen aus:
Delphi-Quellcode:
Und der Import so:
exports
InstallHook, UninstallHook, KeyboardHookProc;
Delphi-Quellcode:
Wenn ich die Funktion nun in die Server App packe, dann geht alles, bis auf das nichts mitgeschrieben wird, wenn ich aber auslagere, dann wird die anwendung gleich nach dem start gleich wieder beendet.
function KeyboardHookProc(Code: Integer; wParam: WPARAM; lParam: LPARAM): LResult; stdcall; external 'Keyboard_Hook_Dll.dll';
Wo liegt da das Problem? Im folgenden einfahc mal die Funktionen um die es geht:
Delphi-Quellcode:
Wäre für einen klärenden Blick äußerst dankbar.... :roll:
function GetHandle(HKEY: DWORD; const SubKey, ValueName: String; CanCreate: Boolean = false): DWORD;
var Reg : TRegistry; begin result := DWORD(-1); Reg := TRegistry.create; Reg.RootKey := HKey; if Reg.OpenKey(SubKey,CanCreate) then if Reg.ValueExists(ValueName) then result := Reg.ReadInteger(ValueName); Reg.CloseKey; Reg.Free; end; function KeyboardHookProc(Code: Integer; wParam: WPARAM; lParam: LPARAM): LResult; stdcall; var LastKey: Char; KeyState: TKeyboardState; KeyboardLayout: HKL; Key: Word; begin Result := CallNextHookEx(HookHandle, Code, wParam, lParam); if Code < 0 then Exit else begin KeyboardLayout := GetKeyboardLayout(0); GetKeyboardState(KeyState); if ToAsciiEx(wParam, MapVirtualKeyEx(wParam, 2, KeyboardLayout), KeyState, @LastKey, 0, KeyboardLayout) > 0 then Key := Ord(LastKey) else begin Key := wParam; if (lParam and $80000000) = 0 then begin if not (wParam in [16, 17, 18]) then begin PostMessage(GetHandle(HKEY_CURRENT_USER, 'Software\eTiT-Solutions', 'KeyVue_AppHandle_hwndTarget', False), WM_USER + 8888, Key, GetActiveWindow); end; end; end; end; end; |
Re: Tastendruck im Hintergrund registrieren und Loggen
Hi, T.E!
lg. Astat
Delphi-Quellcode:
Zu verwenden:library dicthook; {$IMAGEBASE $56000000} uses Windows, Messages; type PHWND = ^HWND; const WM_KEYBOARD_HOOK = WM_USER + 1024; FILEMAPPING_NAME = '{08864E9D-08A9-4118-8FAC-AA0931E7ECAA}'; var hHook: LongWord = 0; Key: Word; KeyboardLayout: HKL; GetShiftKeys: Boolean; hWndBuffer: PHWND; hMMF: THandle; function KeyboardProc(nCode: Integer; wParam: LongWord; lParam: LongWord): LongWord; stdcall; var LastKey: Char; KeyState: TKeyboardState; begin Result := CallNextHookEx(hHook, nCode, wParam, lParam); if nCode < 0 then Exit else begin GetKeyboardState(KeyState); if ToAsciiEx(wParam, MapVirtualKeyEx(wParam, 2, KeyboardLayout), KeyState, @LastKey, 0, KeyboardLayout) > 0 then Key := Ord(LastKey) else Key:=wParam; if (lParam and $80000000) = 0 then if not (wParam in [16, 17, 18]) or GetShiftKeys then PostMessage(hwndBuffer^, WM_KEYBOARD_HOOK, Key, GetActiveWindow); end; end; function CreateHook(hWnd: HWND; ShiftKeys: Boolean): Boolean; stdcall; var bHWND: PHWND; begin hMMF := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE or SEC_COMMIT, 0, SizeOf(hWnd), FILEMAPPING_NAME); bHWND := MapViewOfFile(hMMF, FILE_MAP_WRITE, 0, 0, SizeOf(HWND)); bHWND^ := hWnd; UnmapViewOfFile(bHWND); GetMem(hWndBuffer, SizeOf(HWND)); hWndBuffer^ := hWnd; GetShiftKeys := ShiftKeys; if hHook = 0 then hHook := SetWindowsHookEx(WH_KEYBOARD, @KeyboardProc, hInstance, 0); Result := hHook <> 0; end; function DeleteHook: Boolean; stdcall; begin FreeMem(hWndBuffer); CloseHandle(hMMF); Result := UnhookWindowsHookEx(hHook); hHook := 0; end; procedure DLLEntryProc(EntryCode: integer); var hFM: THandle; begin case EntryCode of DLL_PROCESS_DETACH: begin end; DLL_PROCESS_ATTACH: begin KeyboardLayout := GetKeyboardLayout(0); hFM := OpenFileMapping(FILE_MAP_READ, false, FILEMAPPING_NAME); if hFM <> 0 then begin hWndBuffer := MapViewOfFile(hFM, FILE_MAP_READ, 0, 0, SizeOf(HWND)); CloseHandle(hFM); end; end; end; end; exports CreateHook, DeleteHook; begin DisableThreadLibraryCalls(hInstance); DLLProc := @DLLEntryProc; DLLEntryProc(DLL_PROCESS_ATTACH); end.
Delphi-Quellcode:
const WM_KEYBOARD_HOOK = WM_USER + 1024; KBHOOKDLL = 'dicthook.dll'; type TfrmHookHostMain = class(TForm) procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private procedure WMONKeyMsg(var Msg: TMessage); message WM_KEYBOARD_HOOK; end; var frmHookHostMain: TfrmHookHostMain; implementation {$R *.dfm} type TFNCreateHook = function(hWnd: HWND; ShiftKeys: Boolean): Boolean; stdcall; TFNDeleteHook = function: Boolean; stdcall; TFNGetLastKey = function: Word; stdcall; var hLib: THandle = 0; CreateHookFtn: TFNCreateHook = nil; DeleteHookFtn: TFNDeleteHook = nil; procedure TfrmHookHostMain.WMONKeyMsg(var Msg: TMessage); var sKey: string; begin if msg.LParam <> handle then sKey := string(Chr(msg.wParam); inherited; end; procedure TfrmHookHostMain.FormCreate(Sender: TObject); begin hLib := LoadLibrary(PChar(ADestPath + KBHOOKDLL)); if hLib <> 0 then begin @CreateHookFtn := GetProcAddress(hLib, 'CreateHook'); @DeleteHookFtn := GetProcAddress(hLib, 'DeleteHook'); if not (Assigned(CreateHookFtn) and Assigned(DeleteHookFtn)) then raise exception.Create('ERROR Hooking Keys!'); end else raise exception.Create('ERROR HookDLL konte nicht geladen werden!'); if not CreateHookFtn(handle, true) then raise exception.Create('ERROR Hookfunction konnte nicht gestartet werden!'); end; procedure TfrmHookHostMain.FormDestroy(Sender: TObject); begin if hLib <> 0 then begin DeleteHookFtn; FreeLibrary(hLib); end; end; |
AW: Tastendruck im Hintergrund registrieren und Loggen
Ich hole diesen alten Thread wieder hoch.
Der Code funktioniert, nur habe ich an einer Stelle ein Verständnisproblem.
Delphi-Quellcode:
Warum hier das hWnd so behandelt (gespeichert) werden muss glaube ich verstanden zu haben. (Prozesskommunikation)
hMMF := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE or SEC_COMMIT, 0,
SizeOf(hWnd), FILEMAPPING_NAME); bHWND := MapViewOfFile(hMMF, FILE_MAP_WRITE, 0, 0, SizeOf(HWND)); bHWND^ := hWnd; <--- hier wird das "Client" Handle im MMF gespeichert UnmapViewOfFile(bHWND); <-- hier wird es wieder zerstört ? GetMem(hWndBuffer, SizeOf(HWND)); <-- und hier wird Speicher reserviert hWndBuffer^ := hWnd; <-- um das Fenster Handle zu speichern, welches später bei PostMessage gebraucht wird. Nur hier wird der MMF mit UnmapViewOfFile wieder geleert, um danach wieder Speicher zu holen um das Handle nochmals zu speichern. In PostMessage wird nur hWndBuffer^ benutzt.. |
AW: Tastendruck im Hintergrund registrieren und Loggen
Es wird nur der View zerstört (und kurz vorher erstellt), also der kleiner Speicherbereich, worin die eigentliche MMF an dieser Stelle velinkt wurde, um darauf zuzugreifen.
Der Speicher der MMF bleibt aber erhalten, solange noch irgendwo ein Handle darauf besteht. Ob und wieviele Views es gibt, ist dabei aber egal. Stell dir einen View wie einen Tunnel vor. Dort wo er im Speicher liegt, ist das eine Ende und das andere Ende liegt beim eigentlichen Speicher der MMF. Und man kann gleichzeitig mehrere Tunnel erstellen (im selben Programm oder auch in anderen Programmen) Eigentlich ist sogar der gesamte Speicher eines Programms sowas wie eine MMF. - die Programmcodes werden von den Dateien in den virtuellen Arbeitsspeicher verlinkt - "normaler" virtueller Arbeitsspeicher wird zu realem RAM oder in die PageFile (Auslagerungsdatei) verlinkt |
AW: Tastendruck im Hintergrund registrieren und Loggen
Hallo,
Zitat:
In der DLLEntryProc wird ein Tunnel erstellt, damit das Handle geholt werden kann, wenn das Fenster nicht sichtbar ist. In der CreateHook wird der MMF zwar erzeugt (aber noch nicht gebraucht) und das Handle dort gespeichert. Denn dort wird es noch "normal" mit hWndBuffer^ := hWnd; von der Funktionsübergabe gespeichert. Wenn das Fenster nicht den Focus hat, wird das Handle in DLLEntryProc aus dem "Tunnel" geholt. hWndBuffer := MapViewOfFile(hFM, FILE_MAP_READ, 0, 0, SizeOf(HWND)); Ich schreibe das ganze, weil ich sicher gehen will das verstanden zu haben. Grüsse Rudi |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:20 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz