[C++]Detour - Register Adressen

08/08/2010 06:21 Elektrochemie#1
Hallo,
und zwar möchte ich für ein Spiel einen Packet Logger schreiben.
Jedenfalls hab ich nun ein Problem.

Die Werte werden vor dem Aufruf in's Register geschrieben. (ganz normal eben)
Dann greift meine Funktion per detour ein und überschreibt natürlich jetzt wieder den kompletten Register.
Jetzt springt die Funktion wieder zur Ur-Funktion, allerdings mit den falschen Werten im Register. (D.h. -> Crash).

So, jetzt hab ich versucht bevor meine Funktion aufgerufen wird per inline asm die Register Werte in eine Codecave zu schreiben und nach dem meine Funktion ausgeführt wurde (also vor dem jump zur Ur-Funktion) das ganze wieder per inline asm reinzuschreiben.

Gibt es keine einfacherere Lösung? (Die Werte haben keinen Basepointer, schon versucht... :/ )
Vorallem crasht der Scheiss und klappt noch nicht so ganz :D :( (Register Werte bringens zum crashen - habs schon im debugger angeschaut)

Totaler Käse...
08/08/2010 13:39 ms​#2
Am Anfang des Detours:

pushad
pushfd

Und am Ende:

popfd
popad

Das sichert die Register und Flags auf dem Stack und lädt sie am Ende wieder zurück.
08/08/2010 13:39 Akorn#3
Push die register am anfahng deiner funktion auf den stack und Am ende deiner funktion holst du sie wieder runter.
08/08/2010 16:50 Elektrochemie#4
Hmm irgendwie will es nicht klappen...

Hier mal den Anfang meiner Funktion:

Code:
005A34D4  /$  55            PUSH EBP
005A34D5  |.  8BEC          MOV EBP,ESP
005A34D7  |.  83C4 F8       ADD ESP,-8
005A34DA  |.  53            PUSH EBX
005A34DB  |.  56            PUSH ESI
005A34DC  |.  57            PUSH EDI
005A34DD  |.  33C9          XOR ECX,ECX
005A34DF  |.  894D F8       MOV DWORD PTR SS:[LOCAL.2],ECX
005A34E2  |.  8955 FC       MOV DWORD PTR SS:[LOCAL.1],EDX
005A34E5  |.  8BD8          MOV EBX,EAX
005A34E7  |.  8B45 FC       MOV EAX,DWORD PTR SS:[LOCAL.1]
005A34EA  |.  E8 3D1CE6FF   CALL 0040512C
Dann hier mein detour Aufruf

Code:
DetourFunc( ( BYTE* )0x005A34D4, ( BYTE* )&MyFunction, 14);
(14 bytes bis nach dem ersten MOV?)

Und noch die Detour Func

Code:
bool DetourFunc( BYTE* oldFunc, BYTE* newFunc, DWORD len )
{
	BYTE* newMem4base = NULL;
	DWORD dwOld;

	newMem4base = ( BYTE* )malloc( 5+len );

	if( newMem4base == NULL )
		return false;

	for( DWORD i = 0; i < ( len+5 ); i++ )
		newMem4base[i] = 0x90;

	VirtualProtect( oldFunc, len, PAGE_READWRITE, &dwOld );

	memcpy( newMem4base, oldFunc, len );

	//pushad
	oldFunc[0] = 0x60;

	//pushfd
	oldFunc[1] = 0x9C;

	//call
	oldFunc[2] = 0xE8;
	*( DWORD* )( oldFunc+0x03 ) = DWORD( newFunc-oldFunc-5 );

	//popfd
	oldFunc[7] = 0x9D;

	//popad
	oldFunc[8] = 0x61;
	//jump
	oldFunc[9] = 0xE9;
	*( DWORD* )( oldFunc+0x0A ) = DWORD( newMem4base-( oldFunc+0x5 )-5 );
	newMem4base += len;
	newMem4base[0] = 0xE9;
	*( DWORD* )( newMem4base+0x01 ) = DWORD( ( oldFunc+10 )-newMem4base-5 );

	for( DWORD i = 14; i <len; i++ )
		oldFunc[i] = 0x90;

	return true;
}
So, das Problem is nun er ersetzt die ersten 14 bytes dann durch

pushad
pushfd
<CALL Meine Funktion>
popfd
popad
<JMP Ur Funktion>

Soweit so gut. Nur ist der Call und der JMP leider totaler Mist.
Sieht zufällig jemand warum? :confused:
08/08/2010 17:26 MrSm!th#5
Problem ist nur bei pushad und popad, dass man dann nicht mehr richtig auf die parameter zugreifen kann, wenn es sich nicht gerade um ne __stdcall Funktion handelt
08/08/2010 20:07 SmackJew#6
Was soll das denn werden wenn's fertig ist? Du schreibst das pushad etc. in die Funktion die du detouren willst. Auch verstehe ich dein Problem nicht ganz, wenn du in deine Funktion callst/jumpst verändern sich die Register überhaupt nicht (von der Return Adresse auf dem Stack beim Call mal abgesehen).

Wie soll dein Detour denn Register überschreiben?
08/08/2010 21:30 wurstbrot123#7
Mach den detour ganz normal das heisst, einfach nur ein
Jump zu deiner Funktion. In deiner Funktion machst du dann als
erstes pushad und pushfd. Wenn du dann fertig bist,
popfd und popad und dann der Sprung zurück.
08/10/2010 21:56 Elektrochemie#8
Quote:
Originally Posted by wurstbrot123 View Post
Mach den detour ganz normal das heisst, einfach nur ein
Jump zu deiner Funktion. In deiner Funktion machst du dann als
erstes pushad und pushfd. Wenn du dann fertig bist,
popfd und popad und dann der Sprung zurück.
Das funktioniert.
Aber sobald ich irgendetwas richtung c++ in meine funktion mach, funktionierts nichtmehr.
08/10/2010 22:27 SmackJew#9
Leute, wenn ihr auch nur in irgendeiner Form Hilfe erwartet, postet Code. Keiner kann hier hellsehen.
08/10/2010 23:01 ms​#10
Quote:
Originally Posted by Elektrochemie View Post
Das funktioniert.
Aber sobald ich irgendetwas richtung c++ in meine funktion mach, funktionierts nichtmehr.
Das dürfte daran liegen, dass pushad und pushfd wie Smith schon gesagt hat den Stack "durcheinanderbringen", also dass die Parameter sich nicht da im Stack befinden wo sie erwartet werden. Außerdem solltest du ESP in EBP laden, damit lokale Variablen benutzt werden können.
08/11/2010 07:13 wurstbrot123#11
Desweiteren würde ich dir empfehlen bei solchen Problemen einen Debugger
wie Olly zu benutzen und das ganze einfach mal zu steppen um zu sehen was da falsch läuft.
08/11/2010 21:55 jM3#12
You could also use something like this: [Only registered and activated users can see links. Click Here To Register...]