'gefälschte' Tastatur/Maus-Nachrichten erkennen
-
Bin schon länger am überlegen wie man 'gefälschte' Tastatur/Maus-Nachrichten erkennen kann.
So weit ich es weis wird, wenn man zB die Maus bewegt, vom Maustreiber eine Nachricht erzeugt und in die System-Message-Queue eingereiht.
Diese Nachricht kann aber auch von einer Anwendung an eine andere Anwendung geschickt werden und wird dann entweder in deren Thread-Message-Queue eingereiht oder direkt an deren WndProc geschickt.Meine Idee ist es den Timestamp einer Nachricht in der SMQ mit der Nachricht der Empfänger-Anwendung abzugleichen. (Meiner Meinung nach die einzige Möglichkeit eine Nachricht einigermaßen zu identifizieren).
Muss ich mich in dem Fall mit dem WDK auseinandersetzen oder gibt es Alternative wie zB den Speicherbereich der SMQ auslesen oder irgendwelche Funktionen der WinApi?
-
Was willst Du vergleichen?
Ich verstehe es nicht?
Was für eine System Message Queue meinst Du?Über die UI kannst Du IMHO in keiner Weise feststellen, ob eine Nachricht mit SendInput versendet wurde oder über die Maus/Tastatur kam.
Das ist ja auch der Sinn von SendInput.Wenn SendMessage/PostMessage verwendet wird, ist das evtl. möglich weil der Status in GetAsyncKeyState nicht wiedergespiegelt ist. D.h. man bekommt einen WM_LBUTTONDOWN aber GetAsyncKeyState sagt was anderes.
Aber wie gesagt: Wenn SendInput verwendet wird, ist solch eine Nachricht nicht von einer "echten" Maus/Tastatur Nachrichtzu unterscheiden.
-
In die System-Message-Queue (SMQ) werden Nachrichten eingereiht, welche von Input-Geräte-Treiber (zB Maus, Tastatur) erzeugt wurden und werden dann an die jeweilige Thread-Queue weitergeleitet.http://msdn.microsoft.com/en-us/library/ms644927%28v=VS.85%29.aspx
Ich habe mir vor ein paar Monaten ein Programm geschrieben, welches alle Nachrichten des Firefox Dialogfenster "Sicherheits-Ausnahmeregel hinzufügen" zur Bestätigung von nicht-vertrauenswürdigen Zertifikaten per Hook filtert/abfängt und beim Eintreffen einer WM_LBUTTONUP/DOWN Nachricht auf den 'Abbrechen' Button vorher noch eine WM_LBUTTONUP/DOWN Nachricht auf den 'Ok' Button schickt. Sprich: Habe die Funktion der zwei Buttons vertauscht.
(Beispiel eines bewusst nicht-vertrauenswürdigen Zertifikats zum Experimentieren https://test.syssec.at)Eine Anwendung kann leider nicht erkennen wer der Absender einer Nachricht war (Hat der Benutzer per Mausklick eine Nachricht erzeugt oder hat eine andere Anwendung die nötigen Nachrichten geschickt?)
Und genau das will ich herausfinden. Da eben in der MSG-Struct auch ein Timestamp mitgeschickt wird, dachte ich mir - vergleiche den Timestamp der Nachricht, welche sich in der SMQ befindet, mit dem Timestamp der Nachricht, welche ich per Hook an eine Anwendung gefiltert habe. Im Prinzip ist der Timestamp der einzige Anhaltspunkt um den Ursprung einer Nachricht zu ermitteln (es kann ja nur ein Prozess die CPU zu einem Zeitpunkt benutzen)
Ein anderer Gedanke war: Ich überwache die "E/A-Bytes Lesen" von csrss.exe, welche sich um 24 Bytes erhöhen, wenn eine Nachricht vom Treiber erzeugt wurde, jedoch nicht per SendInput oder ähnliches. Problem an dem ist, dass ich mit der Methode zwar feststellen kann, dass eine 'gefälsche' User-Input-Nachricht geschickt wurde, aber diese keiner Anwendung zuteilen.
-
-
@Martina Richter:
Dann erleuchte uns doch mit Deiner Weisheit, damit mein begrenzter Horizont eine Erweiertung findet...
-
BTW: Sollte der "Dumme Angreifer" SendMessage verwenden kannst Du natürlich InSendMessage(Ex) verwenden um zu kontrollieren ob die Nachricht evtl. aus einem anderen Prozess/Thread kam.
Sollte PostMessage verwendet werden oder SendInput nützt dies wieder nichts,
-
Vielleicht liest es ja noch jemand:
Mittels SetWindowsHookEx koennte ein Low-Level Keyboard (oder Mouse) Hook installiert werden. Der Hook Funktion wird als lParam ein KBDLLHOOKSTRUCT (bzw. im Fall eines Mouse Hooks ein MSLLHOOKSTRUCT) uebergeben. Das 'flags' Feld hat das 'LLKHF_INJECTED' (bzw. LLMHF_INJECTED) flag gesetzt, falls der Event kuenstlich, also z.B. ueber SendInput(), generiert wurde.
Falls das Flag gesetzt ist koenntest du dir den Timestamp des Events (bekommt man ueber das 'time' Feld des gleichen structs) in einer Liste merken. Spaeter kannst du dann die Liste benutzen um zu testen, ob ein gegebener Event (der durch seinen timestamp identifiziert wird) kuenstlich ist oder nicht.