Einzelnen Beitrag anzeigen

Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#61

Re: Subclassing einer fremden Application, warum funzt das n

  Alt 17. Nov 2003, 10:23
Tja, das entfernen eines Subclassing ist nicht so einfach wie man denkt.
Zb. du hast mit obiger Methode ge-subclassed, und in gwl_WndProc steht unsere Windowproc drinnen. Nun Subclassed ein anderes Modul ebenfalls, dann gibt es keine Möglichkeit die eigene Subclass wieder zu entfernen. Denn dein Modul + das andere Modul + Windows selber kennen kein gemeinsammes Protokoll das es ermöglicht geordnet die Subclassings zu entfernen. Da ja nun dein Subclassing im Kontext des Window-Processes läuft wäre es am einfachsten, 1. einfach ein Flag Active in die HookData Struktur einzubauen. Statt also das Subclassing zu deinstallieren wird es nur deaktiviert. 2. ist es für die Kommunikation mit deinem Hook besser eine globale Windowsbotschaft mit RegisterWindowMessage() zu benutzen. Dein Hook reagiert auf diese Botschaft, und in wParam,lParam der Message können Steuerkommandos untergebracht werden. Über dieses Verfahren könntest du auch das Subclassing terminieren. Dabei hast du mehrere Dinge zu beachten. 1.) NIEMALS im Code der in PHookData kopiert wird auf irgendwelche Globale Variablen, Importe etc zugreifen. ALLES an daten und Zugriff MUSS in PHookData stehen. Informiere dich mal was es heist Protected Mode OS, Module und Prozesse und Mapping der Daten-/Codesegmente von Modulen in Prozessen. Dies MUSST du begriffen haben, dann weisst du auch warum Dein Zugriff auf eine globale Variable absolut falsch sein muss. Nungut, desweiteren ist ds Entfernen des Hooks möglich wenn mit GetWindowLong(gwl_WndProc) unsere Addresse auf unsere WndProc = Memory zurückgegeben wird. Sollte dies nicht der Fall sein kann NICHT deinstalliert werden. Ich würde sowieso nur eine Deaktivierung des Hooks benutzen. Angenommen GetWindowLong(gwl_WndProc) = Memory, dann könnte man deinstallieren, mit SetWindowLong(Memory.SaveWindowProc). Das Problem entsteht nun dabei WIE wir unseren Memory mit VirtualFree() freigeben müssen. 1.) ExitThread() ist absolut FALSCH, denn eine Windowsproc läuft nicht in dem Thread den wie benutzten um den Hook zu installieren. Mit ExitThread() beendest du meistens den Main-Thread des Ziel-Prozesses dem das Fenster gehört. 2.) Da unser Deinstallations-Code selber in Memory steht, also innerhalb von Memory ausgeführt wird kann man nicht einfach so VirtualFree(Eigerner_Code_In_Memory) aufrufen, logisch ok !? Denn nach dem VirtualFree() müssen wir Code ausführen der zum Aufrufer zurückkehrt, also mindestens ein RET und eventuell noch einige POP's. Deshalb nutzt man einen Trick. Man legt alle notwendigen Daten auf den Stack des aktuellen Threads, mit PUSH's und springt am Ende mit einem JMP Memory.VirtualFree zu VirtualFree() um das aktuelle "Codesegment" freizugeben. VirtualFree() würde nach Beendigung nur noch auf den Stack des Threads zugreifen und kann so gezielt und geordnet zum Aufrufer der Fensterprocedure zurückkehren.

Also nochmal in kurz die beste Vorgehensweise:
1.) mit RegisterWindowMessage() eine Steuermessage erzeugen
2.) in MyWndProc() diese Steuermessage abfangen und den entsprechende Kommandos reinbauen
3.) Kommando "IsInstalled" um ein Fenster auf unseren Hook zu checken
4.) Kommando "Deaktivate" um unseren wm_Close Hook zu deaktivieren
5.) Kommando "Aktivate" um wm_Close Hook zu aktivieren
6.) Kommand "Deinstall" um das Subclassing zu entfernen. Dabei solltest mit GetWindowLong(gwl_WndProc) == Memory überprüfen, wenn ja dann SetWindowLong(gwl_WndProc, memory) aufrufen, und danach EXAKT den ASM-Code der jetzt in wm_Destroy steht aufrufen.

Gruß Hagen
  Mit Zitat antworten Zitat