Bytes von Funktion
-
Hallo,
ich möchte aus Testzwecken eine Funktion in einem Programm(Testprogramm ohne wirklichen Sinn) hooken. Wenn der Prozessor output() aufruft, trifft er auf einen Jump zu check(), diesem folgt er und führt statt output() nun check() aus. Allerdings ist output() ist nicht mehr zu gebrauchen, da hier einfach 5 Bytes überschrieben wurden, ohne sie zu speichern, was bei API-Funktionen(dort soll es später angewandt werden) wohl schwer zu verkraften sein wird. Also habe ich einen Code geschrieben(kein wirklich toller Code, zum Teil auch nicht von mir ;)), der die ersten Bytes von output() speichern sollte, um sie dann später wieder zu verwenden. Meine Frage ist nun wie ich herrausfinde wie viele Bytes ich speichern muss um output() nicht zu zerreisen ( unsigned bytes_to_save im Code).Mein Code:
#include <iostream> #include <windows.h> using namespace std; void output(int ); void check(int ); unsigned sprungoffset(unsigned ,unsigned ); void hook_function(unsigned ,unsigned ,unsigned ,unsigned ,DWORD ); void new_adress(int ); int main(void) { hook_function((unsigned)&output, 6, (unsigned)&new_adress, (unsigned)&check, GetCurrentProcessId()); output(4); output(5); system("PAUSE"); return 0; } void output(int i) { if(i == 5) cout << "5 - DAS war wohl nichts!\n"; else cout << i << " ist eine gueltige Zahl!\n"; } void check(int i) { if (i != 5) new_adress(i); } unsigned sprungoffset(unsigned absprung, unsigned ziel) { ... } void hook_function(unsigned source_function, unsigned bytes_to_save, unsigned new_adress, unsigned instead_call, DWORD process_id) { ... for(int i = 0; i < bytes_to_save; i++) { //Liest von der SourceFunktion ein Byte nach "byte" ReadProcessMemory(hproc, (LPCVOID)source_function, &byte, sizeof(byte), &rw); //Schreibt das Byte an die neue Adresse und inkrementiert sie WriteProcessMemory(hproc, (LPVOID)new_adress++, &byte, sizeof(byte), &rw); //Schreibt den NOP-Opcode in Byte byte = 0x90; //Schreibt das NOP an die Source-Funktion und inkrementiert die Adresse WriteProcessMemory(hproc, (LPVOID)source_function++, &byte, sizeof(byte), &rw); } ... } void new_adress(int i) { __asm{NOP}; __asm{NOP}; __asm{NOP}; ... }
-
Du musst einen Disassembler implementieren, die die Bytefolgen decodiert und somit die Länge ermittelt.
-
Danke erstmal für die Antwort. Habe grade mal nach Disassambler gegooglet und mir ist aufgefallen, das es alles vom Projetk unabhänige Programme sind. Gibt es noch eine andere Möglichkeit herrauszubekommen wie gorß bytes_to_save sein muss? Bin grad beim googeln auf Folgendes gestoßen:
Dazu lädt man das Programm in den Debugger (z.B. Olly-Debugger) und geht zu der Funktion, die gehookt werden soll (die Adresse kann man sich im Zweifelsfalle ausgeben lassen: cout << (unsigned)&funktion << endl;). Interessant ist der Anfang der Funktion:
00401412 /$ 55 PUSH EBP
00401413 |. 89E5 MOV EBP,ESP
00401415 |. 83EC 08 SUB ESP,8Nur versteh ich nicht ganz wie das funktionieren soll.
Laut Foreneintrag soll man hier erkenenn das man bei den Opcodes sieht, dass x 6 sein muss, da wir ja mindestens 5 Bytes brauchen (ein Jump ist so lang), aber 83EC 08 nicht zerreisen dürfen!
-
Ja, sag ich doch: Du musst einen Disassembler schreiben... OllyDbg macht ja genau das... es disassembelt die ersten Bytes und kann dann die Länge der Befehler ermitteln...
Die "logik" ist hier halt der Benutzer, der die Ausgaben von OllyDg "liest"

-
Der einfachheit halber, kannst Du den OllyDbg Disassembler mit SOurce-Code runterladen und bei Dir einbinden
http://www.ollydbg.de/
http://www.ollydbg.de/disasm.zip
-
Danke

-
bei den meisten stdcall-funktionen klappt das mit den ersten 5 bytes.
bei cdel sieht es etwas anders aus, d.h. du kommst um das disassemblern
wirklich nicht herum (habs auch versuch...)ich empfehle dir da "distorm" (google)
morgen (heute :D) kann ich mal meinen hook-code raussuchen, er ermöglicht
es, die alte funktion zu speichern und aufzurufen.
-
-
Ja, detours macht genau das und geht sogar für x64... ist aber nicht so leicht kommerziell einsetzbar...
