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/)
-   -   Delphi HILFE! Noch einmal der Tastaturhook (https://www.delphipraxis.net/150984-hilfe-noch-einmal-der-tastaturhook.html)

idefix2 2. Mai 2010 12:05


HILFE! Noch einmal der Tastaturhook
 
Hallo,

Jetzt habe ich die diversen Hindernisse bei der Programmierung meines Tastaturhooks umschifft, und das Ding tut in meinem Testprogramm, was ich mir vorgestellt habe. Aber im Moment scheitere ich daran, aus dem lokalen Hook einen globalen zu machen, und ich habe keine Idee, was da falsch sein könnte.

Ich habe:
Die eigentliche Hookunit aus dem Testprogramm entfernt und in eine DLL ausgelagert.
Im Testprogramm an die Stelle der Hookunit eine Loadhook Unit gesetzt, die die DLL lädt und SetWindowsHookEx als ThreadId den Wert 0 und als HInstance die DLL-Handle übergibt.

Der Hook funktioniert einwandfrei, solange ich in dem Testprogramm Eingaben mache, mit dem ich die DLL geladen habe. Sobald ich eine Tastaureingabe in einem anderen Programm mache, wird mein Hook deaktiviert und bleibt dann auch inaktiv, wenn ich in mein Programm zurückkehre. Wenn ich in ein anderes Programm wechsle und dort nur die Maus verwende, passiert nichts, dann ist meine Hookroutine in meinem Testprogramm weiterhin aktiv, sobald es wieder den Focus bekommt.

So lade ich meine DLL:
Delphi-Quellcode:
unit LoadCapsLock;

interface
procedure loaddll;
procedure unloaddll;

implementation

uses windows, dialogs;

var
LibHandle: THandle;  
HookHandle: Cardinal;

inst: procedure (UseHookHandle: HHook); stdcall; // Initialisierung
uninst: procedure; stdcall; // Aufräumen

procedure error (const s: string); inline;
begin
MessageDlg (s, mtError, [mbOK], 0);
end;

procedure loaddll;
begin
LibHandle:=LoadLibrary('capslock.dll');
if LibHandle=0 then begin error ('Library not loaded'); exit end;

inst := GetProcAddress(LibHandle,'AfterInstall');
uninst := GetProcAddress(LibHandle,'AfterUninstall');

if HookHandle <> 0
then begin Error ('Hook ist bereits installiert'); exit end;

HookHandle := SetWindowsHookEx(WH_KEYBOARD,
                               GetProcAddress(LibHandle, 'KeyboardHookProc'),
                               LibHandle, 0);

if HookHandle = 0
then begin Error ('Hook Installation fehlgeschlagen'); exit end;

inst (HookHandle); // Initialisierung in der DLL
end;

...

Astat 3. Mai 2010 09:30

Re: HILFE! Noch einmal der Tastaturhook
 
Zitat:

Zitat von idefix2
..und ich habe keine Idee, was da falsch sein könnte.

Ohne Worte.

http://www.delphipraxis.net/internal...t.php?t=172835

Thread #20

lg.

SirThornberry 3. Mai 2010 09:37

Re: HILFE! Noch einmal der Tastaturhook
 
In dem oben genannten Code kann ich auch keinen Fehler finden. Wenn du wirklich willst das du jemand hilft erschwere es den Leuten am besten nicht durch unformatierten Code. Halte dich an die Styleguides und eventuell siehst du dann auch selbst den Fehler wenn Einrückung etc. stimmt.

idefix2 3. Mai 2010 21:48

Re: HILFE! Noch einmal der Tastaturhook
 
@ASTAT
Danke für den Hinweis - Vorlagen, wie es gehen sollte, gibt es im Internet einige. Deinen Code habe ich jetzt auch ausprobiert, in fast unveränderter Form (ich habe am Anfang der Hookroutine ein beep eingebaut) hat er auch als globaler Hook funktioniert. Ein paar kleine Änderungen, jetzt geht wieder nichts, dabei habe ich bis jetzt eigentlich nur "toten Code", also Deklarationen von variablen und Unterprogrammen, die noch gar nicht aufgerufen werden, eingebaut - wenn ich jetzt eine einzige Taste drücke, fängt die Hookroutine zu beepen an und hört nicht mehr auf.

Naja, zumindest habe ich einen Ansatz, mit dem ich weitersuchen kann. Das frustrierende ist, dass mein Hookprogramm eigentlich schon fertig war, als lokaler Hook hat es einwandfrei funktioniert, aber nach der Übersiedlung in die DLL funktioniert es eben immer noch nur lokal.

@SirThornberry
Über die Frage, wie Code formatiert gehört, lassen sich Religionskriege führen. Ich halte mich seit 30 Jahren strikt an meine Styleguides und stufe meinen Code als sicher nicht weniger übersichtlich ein als die meisten Quellcodes, die z.B. hier in der Delphi Praxis oder sonstwo zu finden sind. Delphi ist für mich ziemlich neu, Pascal nicht.

hoika 3. Mai 2010 22:37

Re: HILFE! Noch einmal der Tastaturhook
 
Hallo,

Also.
Du möchtest, dass wir dir helfen,
und entschuldige, der Code ist einfach schwer lesbar.

Was hälst du von folgendem ?

Delphi-Quellcode:
procedure loaddll;
begin
  LibHandle:=LoadLibrary('capslock.dll');
  if LibHandle=0 then
  begin
    error ('Library not loaded');
    exit
  end;

  inst := GetProcAddress(LibHandle,'AfterInstall');
  uninst := GetProcAddress(LibHandle,'AfterUninstall');

  if HookHandle <> 0 then
  begin
    Error ('Hook ist bereits installiert');
    exit
  end;

  HookHandle := SetWindowsHookEx(WH_KEYBOARD,
                  GetProcAddress(LibHandle, 'KeyboardHookProc'),
                  LibHandle, 0);

  if HookHandle = 0 then
  begin
    Error ('Hook Installation fehlgeschlagen');
    exit
  end;

  inst (HookHandle); // Initialisierung in der DLL
end;

Wenn dir die Formatierungs-"Hinweise" nicht gefallen.
OK

Wundere dich dann aber nicht, wenn keiner über deinen Code
"drüberschaut".

Mir hatte dein Code gereicht, nicht näher hinzusehen.
Nun ja, aber trotzdem.

Was mich eh wundert, ist, dass du hier nicht als Admin "elevated" bist.

Globale Hooks kann ein nomaler User nicht setzen.


Ausserdem fehlt zumindestes der Pdeuso-Code für KeyboardHookProc.


Heiko

Delphi-Laie 3. Mai 2010 22:47

Re: HILFE! Noch einmal der Tastaturhook
 
Daß der Hook nur lokal und nicht global funktioniert, wundert mich nicht. Auch die Installation des Hooks muß in eine DLL ausgelagert werden (oder irre ich mich?).

Sehr gut beschrieben ist das alles in Assarbads Hooktutorial. Letzlich sind es 3 Funktionen, die mit dem Hook zu tun haben: Installation, Deinstallation und die eigentliche Hookfunktion. Ich hielt mich genau an seine Vorlage und konnte den globalen Hook erfolgreich installieren. Jegliche Experimente, so z.B. DLL und Exe vereinigen oder auch den Hook in das Hostprogramm zu integrieren, führten zum Verlust der Globalität oder gar zur völligen Dysfunktion des Hooks.

idefix2 4. Mai 2010 16:06

Re: HILFE! Noch einmal der Tastaturhook
 
Ich habe jetzt den Fehler eingegrenzt, und bin auf ein ganz überraschendes Ergebnis gekommen.

Ich habe meine Hookprozedur schrittweise von einer ganz leeren Prozedur weg aufgebaut. Zur Kontrolle, ob mein Hook noch da ist, macht er jedesmal ein beep, wenn er aufgerufen wird. Damit habe ich überprüft, dass das Laden der DLL und die Installation des Hooks wirklich funktioniert.

Sobald ich in meiner Hook-Prozedur einen Timer aktiviere (der gar nichts tut), verabschiedet sich der Hook, wenn er über eine nicht lokale Taste aktiviert wird:

ALSO:
Solange ich Timer1.enabled auskommentiere, habe ich einen globalen Hook, der einwandfrei funktioniert, ich kann auch Tastaturereignisse in die Tatstaurqueue absetzen, die dort richtig ankommen, egal ob ich der Fokus in meinem Testprogramm oder in einem ganz anderen Programm liegt.

Sobald ich diese Programmzeile mitkompiliere, funktioniert der Hook noch immer einwandfrei, wenn ich Tastatureingaben in das Fenster des Testprogramms mache, das die DLL geladen hat. Wenn ich aber eine einzige Tastatureingabe in ein Fenster ausserhalb dieses Programms mache, gibt es für diese Taste noch einmal einen letzten Beep, der mir sagt, die Hookroutine wird aufgerufen. Weitere Tastatureingaben, egal ob in das Fenster meines Testprogrammes oder in ein anderes, produzieren kein Geräusch mehr, d.h. meine Hookroutine ist fortan nicht mehr in der Hook-Kette drinnen.
Wenn das passiert ist, schlägt nachher auch UnhookWindowsHookEx fehl!

In der Prozedur Timer1Timer ist der einzige Befehl: timer1.enabled := false, der Timer tut also im Moment gar nichts. Ist irgend etwas über eine Inkompatibilität zwichen der delphi Timerkomponente und globalen Hooks bekannt?

Delphi-Laie 4. Mai 2010 16:36

Re: HILFE! Noch einmal der Tastaturhook
 
Durchaus möglich, daß meine gestrige Vermutung doch nicht stimmte, also daß man den Hook auch direkt in der Hostanwendung starten und beenden kann (ohne entsprechende DLL-Funktionen aufzurufen). Ich werde das selbst noch ausprobieren.

Warum Du/Sie einen Timer verwendest/verwenden, ist mir insofern nicht ganz klar, weil Hooks ja dafür eingeschaltet werden, auf bestimmte Systemereignisse (hier Tastaur-) zu reagieren.

Über Inkompatibilitäten mit Timern ist mir nichts bekannt, aber es gibt ja auch andere als die von Borland & Co. gelieferten. So ist z.B. in der Komponente „CoolTrayIcon“ ein anderer enthalten, der über eine andere Vererbung (Elternklassen) generiert wird und ressourcenschonender als ersterer sein soll. Vielleicht damit mal probieren?!

idefix2 4. Mai 2010 17:27

Re: HILFE! Noch einmal der Tastaturhook
 
Du :-D

Der Hook selbst muss auf jeden Fall in eine DLL ausgelagert sein, sonst funktioniert er nur als lokaler Hook. Ich habe auf Grund Deines gestrigen Postings als erstes den Aufruf von setwindowshookex auch in die DLL übersiedelt, ich glaube jetzt aber eigentlich nicht mehr, dass das sein muss - werd ich jedenfalls auch noch ausprobieren. Ich wollte ursprünglich alles Hook-spezifische in eine eigene Unit auslagern, damit ich es als lokaler Hook bequem testen und dann, wenn es fertig ist, ohne Änderung des Codes in eine DLL übersiedeln kann. Weil die Parameter von setwindowshookex zwischen lokalem und globalem Hook differieren, hab ich diesen Aufruf eben nicht in der Hook-Unit, sondern im aufrufendem Programm gemacht.

Einen Timer brauche ich, weil ich die Shift-Lock Taste entschärfen will, sie nervt in zweierlei Hinsicht: erstens schaltet sie auch die Zifferntasten und manche (nicht alle!) Sonderzeichentasten um, was wirklich kein Mensch braucht, auch wenn man einmal in Grossbuchstaben schreiben will. Zweitens, und dazu brauche ich den Timer, will ich Shift Lock deaktivieren, wenn die Taste beim Schreiben irrtümlich zeitnah mit einer anderen Taste gedrückt wird - jetzt hab ich 300 ms eingestellt. Die Umschaltung soll nur aktiviert werden, wenn vor und nach dem Drücken der Umschalttaste 300ms lang keine andere Taste kommt.

Danke für den Hinweis auf Cooltrayicon. Bevor ich mir einen Timer mit API Aufrufen selbst bastle, werde ich mir die Komponente anschauen.

P.S.: Wird eine DLL eigentlich automatisch entladen, wenn das Programm, das sie lädt, geschlossen wird, ohne FreeLibrary aufzurufen? Weil eigentlich brauch ich das Hauptprogramm nach dem Laden der DLL nimmer, aber der Hook soll wirksam bleiben, bis der PC abgeschaltet wird.

Delphi-Laie 4. Mai 2010 18:29

Re: HILFE! Noch einmal der Tastaturhook
 
Zitat:

Zitat von idefix2
P.S.: Wird eine DLL eigentlich automatisch entladen, wenn das Programm, das sie lädt, geschlossen wird, ohne FreeLibrary aufzurufen? Weil eigentlich brauch ich das Hauptprogramm nach dem Laden der DLL nimmer, aber der Hook soll wirksam bleiben, bis der PC abgeschaltet wird.

Diesmal bin ich mir sicher: Ja, und zwar ab Windows 2000!

Es geisterte sogar bis vor einiger Zeit im Internet und sogar in Computerzeitschriften (!) der „Geheimtip“, mit dem Registryeintrag „AlwaysUnLoadDLL“ (soweit ich mich entsinne, hieß er so) dieses automatische Entladen in jedem Falle sicherzustellen. Jedoch schrieb Mikroweich selbst, daß das seit Windows 2000 immer automatisch erfolgt und ab dann mithin überflüssig ist. Eine sauberere (und abwärtskompatible) Programmierung, das Entladen in das Programm explizit aufzunehmen, ist es aber allemal.

Edit: Auch ohne automatische Entladung könnte dieses Ansinnen aussichtslos sein, denn DLLs dürften, soweit ich weiß, nie ohne Hostprogramm funktionieren. Ist aber nur eine Vermutung meinerseits.

Edit2: Mit LoadLibrary mache ich gar nicht erst rum, das ist wohl der dynamischer Aufruf? Damit bin ich noch nie erfolgreich gewesen. Ich definiere einfach das Ziel der Funktionen in der Implementation (eben eine DLL), und damit bin ich erfolgreich und zufrieden. Wie gesagt, ab Windows 2000 wird das erfolglos sein, die DLL allein vor sich hinwerkeln zu lassen, und ältere Betriebsprogramme sind ziemlich selten geworden.

idefix2 4. Mai 2010 20:28

Re: HILFE! Noch einmal der Tastaturhook
 
Naja, Loadlibrary macht schon Sinn, weil dann kannst Du die DLL als Resource ins exe-File packen und brauchst nur eine Datei zu installieren. Kommt dann dran, wenn die DLL selbst funktioniert.

Riesenfrust: Ich habe den SimpleTimer ausprobiert, an und für sich eine feine Komponente: Statt über 500KB mit TTimer wiegt meine DLL mit SimpleTimer nur mehr ca 120KB. Aber sie stürzt genauso ab, und nachdem ich mir die Implementierung angeschaut habe, brauche ich gar nicht erst selbst einen Timer zu basteln, das Problem dürfte der Timper-API Aufruf selbst sein, der das ganze zum Absturz bringt. Ich versteh nur nicht, woran es liegt, es muß doch im Prinzip in DLLs möglich sein, einen Timer zu setzen. Anscheinend geht es aber nicht von in einer globalen Hookroutine aus, verstehen tu ich das überhaupt nicht.

Werde mich jetzt also noch mit IPC beschäftigen müssen und meine zwei Timer ins Hauptprogramm übersiedeln. Zumindest erübrigt sich damit die (ohnehin schon negativ beantwortete) Frage, ob ich das Hauptprogramm entladen und die DLL trotzdem in Betrieb bleiben kann, weil so brauch ich das exe File auf jeden Fall weiter. Und fad wird mir dabei auch nicht.

AArgghh!!!


Edit: Ich habe jetzt doch eine einfachere Möglichkeit gefunden. Innerhalb der DLL kann man nämlich sehr wohl einen Timer verwenden, nur in der Hook Routine selbst darf ich offenbar keinen starten. Damit wird es nur wenig komplizierter als geplant, ich brauche zumindest keine IPC zwischen DLL und EXE zu bauen.

Delphi-Laie 5. Mai 2010 10:53

Re: HILFE! Noch einmal der Tastaturhook
 
Zitat:

Zitat von idefix2
Naja, Loadlibrary macht schon Sinn, weil dann kannst Du die DLL als Resource ins exe-File packen und brauchst nur eine Datei zu installieren. Kommt dann dran, wenn die DLL selbst funktioniert.

Das ist ja interessant! Womit tust Du das? Als Ressource? Das sind doch *.res-Dateien?!

Nachdem ich meine DLL erfolgreich injizierte und die Hooks mithin erfolgreich installierte, wurde ich auf ein Programm aufmerksam, daß diese Vereinigung anbietet: PEBundle! Nun, tatsächlich läuft auch das Konglomerat beider (natürlich eine Exe), also es startet, doch die DLL kann sich aus diesem Korsett nicht lösen und mithin nicht woanders injiziert werden - die Hooks funktionieren nicht woanders, also global. Ob der Hook im eigenen Programm funktioniert, weiß ich jetzt nicht (ich probierte damals auch reichlich mit Pieptönen), zumal das eigene Programm mit dem Hook nichts anfangen kann. Aber in anderen Programmen funktionierte das definitiv nicht.

Nun schreibst Du aber, daß Du es global doch hinbekommen hättest. Wie vereinigst Du Exe-Datei und DLL erfolgreich?

Edit: Mir schwant gerade, warum der Hook doch nicht global ist: Die DLL wird doch nur vom Hostprogramm geladen, wie soll die sich denn in andere Prozesse injizieren?! Also, ich installierte den/die Hook(s) über die DLL (Aufruf der in der Hook-DLL enthaltenen Hookinstallationsfunktion natürlich über das Hostprogramm), und damit war die DLL automatisch injiziert, der Hook installiert. Aber so ganz schlau werde ich aus Deinen Ausführungen nicht: Ist der Hook nun global oder nicht? Es ist nicht schwer, beide Deiner Aussagen in dieser Diskussion zu finden.

idefix2 5. Mai 2010 19:43

Re: HILFE! Noch einmal der Tastaturhook
 
Also - Die DLL kann in die Exe als Ressource eingebunden werden. Zur Laufzeit entpackt die Exe erst einmal die DLL irgenwohin (z.B. nach \TEMP), und lädt sie von dort, als wär die DLL immer schon dort gelegen. Der Vorteil ist, dass man, wenn man das Programm unter die Leute bringen will, nur eine einzige Datei verteilen muss. Zu dem Thema, in Verbindung mit Keyboard Hooks, gibt es ein sehr klares Tutorial: http://www.delphi-treff.de/tutorials...-hooks/page/5/

Hab das jetzt zurückgestellt, weil ich meinen Hook erst einmal funktionsfähig haben muss, und dass ist extrem mühsam, weil lokal funktioniert er, als globaler Hook nur teilweise, d. h. er ist zwar jetzt in die globale KeyboardHook Kette eingebunden und piepst bei jedem Tastendruck, tut aber trotzdem nicht das, was er als lokaler Hook macht - wenn ich eine Eingabe in die EXE mache, tut er jetzt genau, was er soll, bei einer Eingabe in ein anderes Programm piepst er zwar auch, also ist er da, er macht aber Mist.

Und wie ich die DLL debugge, ist mir auch noch nicht klar, der Debugger der Delphi IDE wird mir da ja vermutlich nicht sehr viel helfen. Dazu ist das ganze zeitkritisch, d.h. das Programm verhält sich im Debugger, wenn es bei einem Breakpoint stehengeblieben ist, sowieso anders als wenn es in Echtzeit abläuft. Es wird mir wahrscheinlich nichts übrigbleiben, als doch eine IPC zwichen EXE und DLL einzurichten, damit ich Testausgaben in einem Fenster der EXE ausgeben kann.

Delphi-Laie 5. Mai 2010 21:17

Re: HILFE! Noch einmal der Tastaturhook
 
Zitat:

Zitat von idefix2
Also - Die DLL kann in die Exe als Ressource eingebunden werden. Zur Laufzeit entpackt die Exe erst einmal die DLL irgenwohin (z.B. nach \TEMP), und lädt sie von dort, als wär die DLL immer schon dort gelegen. Der Vorteil ist, dass man, wenn man das Programm unter die Leute bringen will, nur eine einzige Datei verteilen muss.

Das kenne ich. Das Programm „PEBundle“ kann so etwas, soweit ich mich entsinne, auch. Allerdings war, wie schon gesagt, diese Vereinigung, sofern sie die DLL nicht kreißte/gebar, nicht in der Lage, sich in andere Prozesse zu injizieren bzw. dorthinein injiziert zu werden.

Zitat:

Zitat von idefix2
Zu dem Thema, in Verbindung mit Keyboard Hooks, gibt es ein sehr klares Tutorial: http://www.delphi-treff.de/tutorials...-hooks/page/5/

Das kenne ich auch, es ist Assarbads Anleitung und geradezu Pflichtlektüre für alle Hookexperimente/-projekte unter Delphi. Allerdings ist es dort anders: Er ruft - egal, ob statisch oder dynamisch - auch für die Hookeinschaltung DLL-Funktionen auf. Probiere doch einmal, auch diese Funktionen in die DLL zu verbannen! Dann müßte die Chance, es global zu installieren, größer sein?!

idefix2 6. Mai 2010 00:18

Re: HILFE! Noch einmal der Tastaturhook
 
Ich habe gleich nach dem Lesen Deines ersten Posts die Hookinstallation SetWindowsHookEx in die DLL übersiedelt. Mein problem ist jetzt auch nicht mehr, dass mein Hook nicht global ist. Er ist global, und er meldet sich immer, egal in welches Programm ich eine tastatureingabe mache. Aber wenn mein Testprogramm den Focus hat, macht die Hookroutine alles wie sie soll, und sobald die Tastatureingaben in ein anderes programm gehen, macht sie manche Sachen nicht mehr, das ist aber ganz normaler Delphi Code - ich blicke da noch nicht ganz durch, vielleicht schauen die Tastaturnachrichten (= Parameter der HookProc) anders aus als wenn sie von der eigenen EXE kommen. Um das festzustellen, muss ich aber erst einmal eine IPC einrichten, damit ich sehe, was in der DLL genau passiert, und nachdem ich das auch noch nie gemacht habe, muss ich mich da erst einlesen.

Nebenbei: In einer globalen HookProc selbst kann man offenbar wirklich keinen Timer starten, wenn man das versucht, passieren die seltsamsten Dinge - und zwar nur, wenn die Tastaturereignisse an ein fremdes Fenster adressiert sind. Das war der eigentliche Grund, warum meine ersten Versuche völlig danebengegangen sind. Wenn man es weiss, ist es kein Problem, weil in der DLL funktionieren Timer - ausserhalb der HookProc - sehr wohl.

Zitat:

Allerdings war, wie schon gesagt, diese Vereinigung, sofern sie die DLL nicht kreißte/gebahr, nicht in der Lage, sich in andere Prozesse zu injizieren
Die DDL wird ja zur Laufzeit erst einmal aus der EXE in eine ganz normale DLL Datei extrahiert. Danach wird diese DLL Datei genauso geladen, als wäre sie nie Teil der EXE gewesen. Beim Laden der DLL kann für das Betriebssytem kein Unterschied mehr gegenüber einer DLL, die von vorneherein separat war, zu erkennen sein.

Delphi-Laie 6. Mai 2010 11:09

Re: HILFE! Noch einmal der Tastaturhook
 
So ganz verstehe ich Dich leider immer noch nicht.

Brachte mein Vorschlag, den Hook innerhalb der DLL zu starten, Dir nun einen spürbaren Fortschritt oder doch nicht?

Eines mußt Du auch bedenken (ich bezahlte diesbezüglich auch Lehrgeld): Bei DLL-Injektionen werden etliche Kopien dieser DLL an andere Prozesse erstellt. Globale Daten, die z.B. zum Injektionszeitraum vorlagen, existieren aber nur in der ursprünglichen DLL, in den Kopien sind diese Makulatur bzw. Schall und Rauch.

Es müssen also, um sicherzustellen, daß jede injizierte Kopie die richtigen Daten erhält, diese Daten zur Laufzeit dort hineingebracht werden, bzw. die DLL muß sich diese DLL beschaffen. Ich tat das mit externen Dateien. Nicht die eleganteste Lösung (im Vergleich mit der Interprozeßkommunikation), hat aber den Vorteil, daß man in der Menge der Daten flexibel bleibt.

Zusammengefaßt: Hookprogrammierung ist ekelhaft, aber eine durchaus bewältigbare Herausforderung. Wenn man es geschafft hat, freut man sich umso mehr.

Edit: Mir ist zudem immer noch nicht klar, wozu ein Timer der DLL gut sein soll, weil (Tastatur-)Hookprogrammierung genau wie vieles andere Außen(!)-Ereignisprogrammierung ist.

idefix2 6. Mai 2010 20:00

Re: HILFE! Noch einmal der Tastaturhook
 
Ich kann im Moment noch nicht sagen, ob die Übersiedlung der Hookinstallation in die DLL notwendig war, oder ob es anders auch geht. Ich werde das noch austesten, wenn meine DLL funktioniert. Der Status ist derzeit der: Mein Hook ist global, tut aber nur lokal genau was ich erwarte (d.h. wenn das Tastaturerignis an die EXE geht, die die DLL geladen hat), er tut nur teilweise das, was er tun soll, wenn das Tastaturereignis an ein anderes Programm geht. Warum das so ist, bin ich erst beim Erkunden.

Den Timer brauche ich (und er funktioniert sogar in der DLL, ich habe nur das Programm etwas umbauen müssen, weil ich in der Hookroutine selbst keinen Timer starten kann), weil ich sicherstellen will, dass ShiftLock wirkungslos bleibt, wenn 300 ms vorher bis 300ms nach dem Drücken der Shiftlock Taste eine andere Taste gedrückt wird - jetzt, während ich das schreibe, kommt mir gerade, dass ich das gleiche auch ohne Timer mit Hilfe von Timestamps überprüfen könnte (vorausgesetzt, die Funktion "now" liefert die aktuelle Zeit mit ausreichender Genauigkeit, das müsste ich mir noch anschauen).

Und gibt es dann nicht noch eine Systemfunktion, die die Anzahl der Ticks seit dem Starten des PC liefert? Ich glaube, dass ich da irgendwo am Rande einmal etwas gelesen haben. Irgendwie sollte man damit feststellen können, wie lange der PC schon in Betrieb ist.

Zitat:

Bei DLL-Injektionen werden etliche Kopien dieser DLL an andere Prozesse erstellt.
Ich verstehe nicht ganz, was Du meinst. Wenn mehrere Prozesse eine DLL laden und verwenden, dann gibt es im Speicher ein Exemplar der DLL, das mit separaten Datenbereichen für jede Instanz, die sie geladen hat, arbeitet. Aber in dem Fall eines globalen Hooks wird ja nur ein DLL Prozess gestartet, und der bekommt dann alle Ereignisse mit, egal an welchen Prozess das Ereignisse geschickt werden.

Delphi-Laie 6. Mai 2010 20:18

Re: HILFE! Noch einmal der Tastaturhook
 
Zitat:

Zitat von idefix2
Zitat:

Bei DLL-Injektionen werden etliche Kopien dieser DLL an andere Prozesse erstellt.
Ich verstehe nicht ganz, was Du meinst. Wenn mehrere Prozesse eine DLL laden und verwenden, dann gibt es im Speicher ein Exemplar der DLL, das mit separaten Datenbereichen für jede Instanz, die sie geladen hat, arbeitet. Aber in dem Fall eines globalen Hooks wird ja nur ein DLL Prozess gestartet, und der bekommt dann alle Ereignisse mit, egal an welchen Prozess das Ereignisse geschickt werden.

So ganz genau weiß ich es leider nicht, die echten Experten (außer Dir?!) halten sich ja in dieser Diskussion auffällig zurück. Ob nun nur eine DLL „mit separaten Datenbereichen“ oder x-mal die Kopie derselben DLL verwendet wird, läuft letztlich - vom Speicherverbrauch abgesehen - auf dasselbe hinaus, weil der Programmcode ja identisch sein muß.

In meinem Programm „Prozesse“ (auch hier im Forum zu finden) läßt sich über die Spalte „Module“ (dahinter steckt ein Modulschnappschuß) recht gut verfolgen, daß eine Hook-DLL in mehr als einem Prozeß als Modul existiert und damit wohl insgesamt auch mehrere Male (?) im Speicher vorhanden ist. In welche Prozesse sich die DLL einklinkt und in welche nicht, konnte ich allerdings noch kein System erkennen.

Delphi-Laie 13. Mai 2010 12:07

Re: HILFE! Noch einmal der Tastaturhook
 
Hallo idefix2!

Kürzlich bemerkte ich ein Phänomen, das ich vorher noch nie hatte: Mein Hookprogramm (das leider nie den Charakter einer Studie bzw. eines Experimentes ganz verließ) stürzte in der 64-Bit-Version (mit Lazarus erstellt) ab. Dennoch bemerkte ich später noch die Wirkung der Hookauslösung, also waren immer die immer noch funktionierende Kopien der DLL immer noch in einzelne Prozesse injiziert. Die automatische DLL-Entladung versagte also in diesem Falle. Zudem war es das erste und bisher einzige Mal, daß eine DLL wirklich ohne Exe-Datei funktionierte, also als allein ausführbarer und auch ausführender Code im Speicher lag. Sicher, die Situation, die dahin führte, war irregulär....

idefix2 16. Mai 2010 16:54

Re: HILFE! Noch einmal der Tastaturhook
 
Ehrlich gesagt vertraue ich dem 64 Bit Windows nicht. Ich hatte bei mir kurz ein Windows7 64Bit in Betrieb, habe es nach diversen obskuren Problemen wieder rausgeworfen und wieder die 32 Bit Version aufgesetzt. Die läuft halbwegs stabil. 3/4 GB Speicher stecken jetzt eben ungenutzt in meinem Rechner, 32Bit Windows kann ja nur 3,25 GB adressieren, dafür funktioniert er jetzt einigermassen.

Im Grossen und Ganzen habe ich meinen Hook jetzt fertig, was leider nicht ordentlich funktioniert ist das Zusammenspiel mit der Dektopintegration einer virtullen XP Maschine. Da kommen gelegentlich keine Tasten an, dann muss ich das HookHauptprogramm beenden, damit in der VM die Tastatur überhaupt funktioniert. Sonst läuft es jetzt, die Probleme mit der VM werde ich wahrscheinlich nicht lösen können, da dürfte einiges bei der Desktopintegration unsauber programmiert sein.


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