Servus
Ich habe hier ein praktisches Beispiel für den Einsatz eines Keyloggers:
Meine Firma stellt unter anderem Software für Handscanner und Tastaturscanner her. Bei einem unserer Kunden gab es unlängst Probleme mit den Tastaturscanner, die über einen ThinClient am System angebunden sind.
Unter bestimmten Voraussetzungen wurde der gescannte Code unterschiedlich interpretiert. So wurde beispielsweise statt {WH10} wurde [wh10] zurückgegeben.
Durch Zufall haben wir das nun reproduzieren können. Wenn unter Windows XP über Remote Desktop gescannt wurde, wirkte es sich unmittelbar auf das "Ergebnis" des Scannen aus, ob man RDP im Fullscreen oder im Fenstermodus laufen ließ.
Soweit so gut, jetzt muss herausgefunden werden, warum das unterschiedlich interpretiert wird. Unsere Systemverwaltung hatte mich gebeten, einen KeyLogger zu schreiben, der die Dateneingabe aufzeichnet. Zu diesem Zweck habe ich mir das hiesige "Tutorial" zu Gemüte geführt, bin da aber auf einige Probleme gestoßen:
Ich muss nicht nur die "eingegeben" Zeichen speichern, sondern auch den tatsächlichen Scanncode, sowie den Status von NumLock, CapsLock, Shift, Ctrl und Alt und soweit es möglich ist, den Namen der für die Eingabe gültigen Regionalen Settings (Language Code).
Da ich im "Lese-Programm" nicht auf diese Werte zugreifen kann (zumindest hab ich es nicht zum laufen bekommen), habe ich diese Funktionalität in die DLL gepackt. Allerdings gelingt es mir dort auch nicht, dass ich alle Tasten "abfange". Die Windowstasten sowie Pause- und die Kontextmenü- Taste kann ich gar nicht abfangen. Einige Zeichen scheinen inzwischen willkürlich verloren zu gehen, andere werden falsch interpretiert (z.B. AltGr).
Desweiteren: Wie komme ich an den Namen des "Eingabetastatur- Layouts"? Gibt es eine einfachere Art, den Status von Shift, Capslock etc. abzufragen? Da ich diese Informationen nicht komplett per Message verschicken konnte, speichere ich die geloggten Werte in eine Datei (C:\KBHook.log) und öffne diese in meiner "Lese Anwendung"...
Weswegen ich MapVirtualKeyEx zweimal aufrufe liegt daran, dass bestimmte Tasten ein falsches Ergebnis zurückgaben (z.B. F9 -> p)
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139:
| function KeyboardProc(nCode: Integer; wParam: LongWord; lParam: LongWord): LongWord; stdcall; var LastKey0: Char; LastKey2: Char; KeyState: TKeyboardState; LogFile: TextFile; Text: String; Line: String; MappedKey0: Cardinal; MappedKey2: Cardinal; AsciiKey0: Cardinal; AsciiKey2: Cardinal; begin Result:=CallNextHookEx(hHook,nCode,wParam,lParam); if nCode<0 then Exit else begin KeyboardLayout:=GetKeyboardLayout(0); GetKeyboardState(KeyState); MappedKey0 := MapVirtualKeyEx(wParam, 0, KeyboardLayout); MappedKey2 := MapVirtualKeyEx(wParam, 2, KeyboardLayout); AsciiKey0 := ToAsciiEx(wParam, MappedKey0, KeyState, @LastKey0, 0, KeyboardLayout); AsciiKey2 := ToAsciiEx(wParam, MappedKey2, KeyState, @LastKey2, 0, KeyboardLayout);
if (MappedKey0 > 0) then begin if (AsciiKey0 > 0) and (MappedKey2 > 0) and (AsciiKey2 > 0) and (not (wParam in [VK_RETURN, VK_PAUSE, VK_ESCAPE, VK_CANCEL, VK_BACK])) then begin Key := Ord(LastKey0); Text := LastKey0; end else begin case wParam of VK_LBUTTON: Text := '<LBUTTON>'; VK_RBUTTON: Text := '<RBUTTON>'; VK_CANCEL: Text := '<CANCEL>'; VK_MBUTTON: Text := '<MBUTTON>'; VK_BACK: Text := '<BACKSPACE>'; VK_TAB: Text := '<TAB>'; VK_CLEAR: Text := '<CLEAR>'; VK_RETURN: Text := '<RETURN>'; VK_SHIFT: Text := '<SHIFT>'; VK_CONTROL: Text := '<CTRL>'; VK_MENU: Text := '<ALT>'; VK_PAUSE: Text := '<PAUSE>'; VK_CAPITAL: Text := '<CAPSLOCK>'; VK_CONVERT: Text := '<CONVERT>'; VK_NONCONVERT: Text := '<NONCONVERT>'; VK_ACCEPT: Text := '<ACCEPT>'; VK_MODECHANGE: Text := '<MODECHANGE>'; VK_ESCAPE: Text := '<ESCAPE>'; VK_PRIOR: Text := '<PRIOR>'; VK_NEXT: Text := '<NEXT>'; VK_END: Text := '<END>'; VK_HOME: Text := '<HOME>'; VK_LEFT: Text := '<LEFT>'; VK_UP: Text := '<UP>'; VK_RIGHT: Text := '<RIGHT>'; VK_DOWN: Text := '<DOWN>'; VK_SELECT: Text := '<SELECT>'; VK_PRINT: Text := '<PRINT>'; VK_EXECUTE: Text := '<EXECUTE>'; VK_SNAPSHOT: Text := '<SNAPSHOT>'; VK_INSERT: Text := '<INSERT>'; VK_DELETE: Text := '<DELETE>'; VK_F1: Text := '<F1>'; VK_F2: Text := '<F2>'; VK_F3: Text := '<F3>'; VK_F4: Text := '<F4>'; VK_F5: Text := '<F5>'; VK_F6: Text := '<F6>'; VK_F7: Text := '<F7>'; VK_F8: Text := '<F8>'; VK_F9: Text := '<F9>'; VK_F10: Text := '<F10>'; VK_F11: Text := '<F11>'; VK_F12: Text := '<F12>'; VK_F13: Text := '<F13>'; VK_F14: Text := '<F14>'; VK_F15: Text := '<F15>'; VK_F16: Text := '<F16>'; VK_F17: Text := '<F17>'; VK_F18: Text := '<F18>'; VK_F19: Text := '<F19>'; VK_F20: Text := '<F20>'; VK_F21: Text := '<F21>'; VK_F22: Text := '<F22>'; VK_F23: Text := '<F23>'; VK_F24: Text := '<F24>'; VK_NUMLOCK: Text := '<NUMLOCK>'; VK_SCROLL: Text := '<SCROLLLOCK>'; end; Key := Ord(LastKey0); end; end else begin if wParam = VK_RETURN then Text := '<RETURN>' else Text := Chr(wParam); Key := wParam; end;
if (lParam and $80000000)=0 then if not (wParam in [16,17,18]) or GetShiftKeys then begin AssignFile(LogFile, 'C:\KBHook.log'); if FileExists('C:\KBHook.log') then Append(LogFile) else Rewrite(LogFile);
Line := 'Text:' + QuotedStr(Text) + ' : '; if wParam <> 0 then Line := Line + 'wParam: ' + Chr(wParam) + ' (' + IntToStr(wParam) + ') ' else Line := Line + 'wParam: <0> (0) '; if MappedKey0 <> 0 then Line := Line + 'MappedKey: ' + Chr(MappedKey0) + ' (' + IntToStr(MappedKey0) + ') ' else Line := Line + 'MappedKey: <0> (0) '; if LastKey0 <> #0 then Line := Line + 'AsciiKey: ' + LastKey0 + ' (' + IntToStr(Ord(LastKey0)) + ') ' else Line := Line + 'AsciiKey: <0> (0) ';
Line := Line + ' --> Caps: ' + BoolToStr(KeyState[VK_CAPITAL] = 1) + ', Scroll: ' + BoolToStr(KeyState[VK_SCROLL] = 1) + ', Num: ' + BoolToStr(KeyState[VK_NUMLOCK] = 1) + ', Shift: ' + BoolToStr(GetKeyState(VK_SHIFT) < 0) + ', Ctrl: ' + BoolToStr(GetKeyState(VK_CONTROL) < 0) + ', Alt: ' + BoolToStr(GetKeyState(VK_MENU) < 0);
Writeln(LogFile, Line); Flush(LogFile); CloseFile(LogFile); PostMessage(hwndBuffer^,WM_KEYBOARD_HOOK,Key,GetActiveWindow); end; end; end; |
Vielen Dank für die Hilfe!
C.