WinApi hooking führt zum "Buffer Overrun!", hilfe!
-
Bist Du Dir überhaupt im klaren, daß Du von Deinem Prozess aus NIEMALS in den Adressraum eines anderen Prozesses einsehen kannst?
ReadProcessMemory

-
Sicher.
Aber ich möchte nicht mit Detours arbeiten, sondern irgendwo sehen das ich das auch alleine schafe und nicht mit schon fertigen Funktionen aus libs.
Sicher ist mir auch klar das der Process abrauchen wird wenn ich da Bytes überschreibe und die nun mal nicht mehr für das Prgramm auffindbar sind. Ich hab mir da ja auch schon ein paar gedanken gemacht wie ich das umgehen kann und bin zu dieser Idee gekommen, so wie ich es ja auch schon in einigen Tutorials gesehen habe.(Alles Process intern!)
*(1) Ich suche mir die Funktion die ich hooken will (MessageBoxA) aus der user32.dll und besorge mir deren Addresse
(2) Ich suche die Adresse meiner Funktion
(3) Da es meistens long jumps sind um auf Funktionen um zuleiten, werden 5Bytes benötigt, also schau ich im OllyDbg ob ich evtl. Bytes auseinander reiße oder nicht ( War nicht der Fall )
(4) Ich allociere in meiner Anwendung genug Speicher um: 1. den Sprung zu meiner Funktion im speicher / 2. die x zu sichernden Bytes / 3. den Sprung zurück zur original funktion zu machen bzw dahinter, zu speichern. Das macht am Ende 15Bytes die zu allocieren sind: 5 Sprung zur Funktion + 5 zu sichern + 5 Sprung zurück.
(5) Ich rechne alle Sprung weiten aus hin und zurück und schreibe dann alles so der reihe nach in den Speicher
(6) Nun schreibe ich von der zu hookenden Funktion ein Sprung zu diesen Speicher der alles beinhalten (4)*
Ich habe mir das alles mal Stück für Stück im Debugger angeschaut und festgestellt, das er exakt die 15Bytes sichert aber nachdem er den Jump zu meiner Funktion macht und diese ausgeführt hat springt er gleich zur Orignalen Funktion zurück ohne das er die anderen gesicherten Bytes ausführt die ihn da ja nun fehlen.
Wieso ist das so?
Gruß Tobi.
-
Wenn Du JPs verwendest wundert mich dasin keiner Weise!
-
wieso?
-
Weil Du einen Call nicht durch einen Jump ersetzen kannst...
Wie sieht den exakt, der Code im Assembler aus, den Du ersetzt?
Und wie exakt ersetzt du ihn?
-
Hier noch mal ein Bild hoffe es ist alles zu sehen.
http://www.pictureupload.de/originals/pictures/120308174835_Unbenannt.JPGDoch mir ich gerade da fehlt noch ein Jmp zurück, doch das ist im moment nicht das Problem.
-
was sind eigentlich hooks ??????

-
Einmal hier

http://de.wikipedia.org/wiki/Captain_Hookund dann evtl. noch mal hier
http://msdn2.microsoft.com/en-us/library/ms644959.aspxGruß Tobi.
-
@ToBi: Was DU hier machst ist für mich ignorant und unfassbar.
Du versuchst mit den Mitteln eines Realschülers Mondraketen zu bauen!Genau das hatte ich geahnt, was Du hier gebastelt hast.
Warum glaubst Du, dass nach dem umbiegen und dem einfügen eines JPs hinter dem JP weitere Code ausgeführt wird?
Du machst einen JP in Deinen HOOK! Von dort einen JP (EINEN JP!!!!!) in Deinen Code. Wie soll er denn zurückkommen.
Das wäre eine Lösung:
- JP in deinen neuen Code block
- CALL in Deinen Code.
- ausführen der geischerten Bytes (auf vollständigen op-codeist zu achten. Nicht alle 5 Byte Kombinationen sind plausibel
- JP zurück hinter Deinen 1. JPPS: Ich werde Dir nicht mehr helfen...
-
Hae, aber das tue ich doch da oben( sprich im Bild ), ich mache einen Jump zu meiner Codestelle, ok und hier mach ich nen Jump, aber wenn ich nen Call drauß mache ist es doch genau wie in deiner Anleitung, bis auf das ich noch ein Sprung zurück zum Anfang machen muss.
-
WO springst Du da bitte zu 77D50510?
Und WO führst Du "move edi, edi", "push ebp" und "mov ebp,esp" aus?
-
Ok, ich habe das jetzt nach Martins Anleitung gemacht und es geht auch ohne abrauchen und so, ABER die MessageBoxA wird trotzdem ausgeführt. Ich hab mir das im Debugger angesehen und es sieht irgendwie so aus als ob sich die MessageBox in der Funktion selbst nochmal aufruft?
Hier mal der Ausschnitt aus dem Debugger:
77D5050B U>- E9 F0FABC88 JMP 00920000 77D50510 833D 1C04D777 00 CMP DWORD PTR DS:[77D7041C],0 77D50517 74 24 JE SHORT USER32.77D5053D 77D50519 64:A1 18000000 MOV EAX,DWORD PTR FS:[18] 77D5051F 6A 00 PUSH 0 77D50521 FF70 24 PUSH DWORD PTR DS:[EAX+24] 77D50524 68 F40AD777 PUSH USER32.77D70AF4 77D50529 FF15 1812D177 CALL DWORD PTR DS:[<&KERNEL32.InterlockedCompareExchange>] ; kernel32.InterlockedCompareExchange 77D5052F 85C0 TEST EAX,EAX 77D50531 75 0A JNZ SHORT USER32.77D5053D 77D50533 C705 F00AD777 01000000 MOV DWORD PTR DS:[77D70AF0],1 77D5053D 6A 00 PUSH 0 77D5053F FF75 14 PUSH DWORD PTR SS:[EBP+14] 77D50542 FF75 10 PUSH DWORD PTR SS:[EBP+10] 77D50545 FF75 0C PUSH DWORD PTR SS:[EBP+C] 77D50548 FF75 08 PUSH DWORD PTR SS:[EBP+8] 77D5054B E8 2D000000 CALL USER32.MessageBoxExA 77D50550 5D POP EBP ; DivertIT.00401273 77D50551 C2 1000 RETN 10 77D50554 90 NOP 77D50555 90 NOP 77D50556 90 NOP 77D50557 90 NOP 77D50558 90 NOP 77D50559 U> 8BFF MOV EDI,EDI 77D5055B 55 PUSH EBP 77D5055C 8BEC MOV EBP,ESP 77D5055E 6A FF PUSH -1 77D50560 FF75 18 PUSH DWORD PTR SS:[EBP+18] ; DivertIT.00401130 77D50563 FF75 14 PUSH DWORD PTR SS:[EBP+14] 77D50566 FF75 10 PUSH DWORD PTR SS:[EBP+10] 77D50569 FF75 0C PUSH DWORD PTR SS:[EBP+C] 77D5056C FF75 08 PUSH DWORD PTR SS:[EBP+8] 77D5056F E8 F1590100 CALL USER32.MessageBoxTimeoutW 77D50574 5D POP EBP ; DivertIT.00401273 77D50575 C2 1400 RETN 14 77D50578 90 NOP 77D50579 90 NOP 77D5057A 90 NOP 77D5057B 90 NOP 77D5057C 90 NOP 77D5057D U> 8BFF MOV EDI,EDI 77D5057F 55 PUSH EBP 77D50580 8BEC MOV EBP,ESP 77D50582 6A FF PUSH -1 77D50584 FF75 18 PUSH DWORD PTR SS:[EBP+18] ; DivertIT.00401130 77D50587 FF75 14 PUSH DWORD PTR SS:[EBP+14] 77D5058A FF75 10 PUSH DWORD PTR SS:[EBP+10] 77D5058D FF75 0C PUSH DWORD PTR SS:[EBP+C] 77D50590 FF75 08 PUSH DWORD PTR SS:[EBP+8] 77D50593 E8 505A0100 CALL USER32.MessageBoxTimeoutA 77D50598 5D POP EBP ; DivertIT.00401273 77D50599 C2 1400 RETN 14Also Zeile 1 ist der Sprung zu meiner Codestelle. dann nach lande ich zurück in Zeile 2, und dann wird noch mal MessageBoxA aufgerufen? Die stelle ist dann aber nich gehookt, das verstehe ich nicht ganz?
-
http://www.hackerboard.de/thread.php?threadid=36201&hilightuser=18020 << da hab ich detourhooking erklaert, dort befindet sich auch funktionierender Code
-
Hm, mein funktioniert ja jetzt auch, meine Funktion wird ausgeführt, aber die eigentlich gehookte MessageBoxA kommt trotzdem, weil sie sich in sich lebst noch einmal aufruft?
EDIT:
Ich habe mir mal dein code angesehen und eigentlicch machst du das selbe wie ich nur das ich statt alles mit _asm zu schreiben mit WriteProcessMemory() gearbeitet habe, dass ist doch eigentlich nicht weiter schlimm oder?
-
T0bi schrieb:
Also Zeile 1 ist der Sprung zu meiner Codestelle. dann nach lande ich zurück in Zeile 2, und dann wird noch mal MessageBoxA aufgerufen?
Nicht "noch mal" sondern "immer noch".
Die Funktion MessageBoxA ist simpel gesagt eine Adresse, die in Zeile 1 anfängt !!! (und bis incl. Zeile 19 geht).
-
Hm und wie koennte ich das nun "richtig" hooken? so das die MsgBox nicht kommt? Bzw. was mich noch interessiert, ist das bei allen Api Funktionen so?
EDIT:
Müsste ich evtl. dann für jeden Funktion die ich evtl. hooken will im Debugger schaun wie groß die ist? und dann x Bytes dahinter springen? bzw zum return der funktion?
-
T0bi schrieb:
Hm und wie koennte ich das nun "richtig" hooken? so das die MsgBox nicht kommt?
Ich bezweifle mal ob das überhaupt "richtig" ist. Ein Hook ist niemals richtig. Aber das ist nicht meine Sache sowas beurteilen zu müssen.
Du mußt Zeile -19- zu Zeile -2- "machen" und darfst dann aber den überschriebenen Code aus Zeile -1- nicht ! mehr ausführen.T0bi schrieb:
Müsste ich evtl. dann für jeden Funktion die ich evtl. hooken will im Debugger schaun wie groß die ist?
I.d.R. reicht es aus zu wissen, wieviele Parameter die Funktion hat. Details dazu gehören aber ins Assembler-Forum.
Finde mal raus, warum MessageBoxA ein "RETN 10 (hex)" am Ende hat.
-
kA ahnung wieso der return Wert 10 ist, evtl. ist es die definition fuer IDOK oder so?
-
Wenn Du die ursprüngliche Funktion nicht aufrufen willst, brauchst Du keinen Jump sondern einfach ein RETN 10 ganz am Anfang.
-
Ok.
Also RETN wird benutzt um eine Prozdure zu beenden das N steht für NEAR, weil die Prozedure ja auch nur ein paar Adressen weiter weg liegt und Wert hinter RETN ist ein optionaler stack Wert, was ich aber nicht ganz verstehe, soll das dann bedeuten er soll die obersten 14 Adressen return?Achja eine letzte Frage hätte ich da noch und zwar fange ich ja nun die MessageBoxA ab, in meiner eigenen Funktion möchte ih die Parameter auslesen und in eine Textdatei schreiben
int MyMessageBoxA( HWND hWnd, LPCTSTR szText, LPCTSTR szTitle, UINT uiState ) { std::ofstream secret; secret.open( "LastMessage.txt", std::ios::out ); secret << "Last read message:\n" << "Title : " /*<< szText*/ << "\n" << "Message: " << szTitle; secret.close( ); Beep( 1000, 500 ); return IDOK; }Den Wert aus szTitle kann ich wunderbar auslesen ohne probleme aber will ich den Wert von szText lesen, gibts nen Fehler:
Unhandled exception at 0x00404430 in DivertIT.exe: 0xC0000005: Access violation reading location 0x00000000.Versteh auch irgendwie nicht wieso er ander stelle 0x000000000 lesen will, ist der Pointer zu dem string nicht ok? Also im Speicher liegen beide Strings eigentlich neben einander, also das nicht etwa einer der beiden in einer geschützten speicherstelle liegt. Hm... wieso geht das nicht?