[C++]DirectDraw Hooking

04/15/2012 16:42 qu4rry#1
Hallo liebe Community,

bin gerade dabei ein etwas älteres Spiel was DirectDraw (dx7) benutzt zu Hooken..Da ich mich mit DirectDraw nicht gut auskenne und nicht wie bei dx9 wüsste wie ich an eine EndScene käme versuche ich die Blt Funktion zu detouren und dort das BackSurface abzugreifen, welches schließlich auf das FrontSurface gezeichnet werden müsste.. (falls ich Unrecht habe bitte korrigieren)

Um nun an die Blt Methode zu gelangen, besorg ich mir zunächst das DirectDraw7-Interface.
Anschließend über die CreateSurface Methode das DirectDrawSurface7-Interface und damit auch die Blt Funktion (hier):

Code:
HRESULT WINAPI hkCreateSurface(LPDIRECTDRAW7 poi, PVOID self, IUnknown**  directDrawSurface, IUnknown FAR * unkOuter)
{
	add_log("Create Surface Methode wurde aufgerufen"); 
	
	HRESULT result = pCreateSurface(poi, self, directDrawSurface, unkOuter);	

	IUnknown* dxSurfaceInterface;

	if ( !result ) 
	{ 

		if (!SetCooperativeLevelNext || !CreateDevice7Next) 
		{ 
			if (!(*directDrawSurface)->QueryInterface(IID_IDirectDrawSurface7, (PVOID*) &dxSurfaceInterface)) 
			{ 
				int i = 5;
				add_log("BltFunction( %i InterfaceMethod) : %x",i,GetInterfaceMethod(dxSurfaceInterface, i)); 
				
				pBlt = (Blt_t) DetourFunc((PBYTE)GetInterfaceMethod(dxSurfaceInterface, i), (PBYTE)hkBlt, 10);

				dxSurfaceInterface->Release(); 
			} 
		} 
	}

	add_log("Got out of here!"); 
	
	return result;
}
Klappt alles wunderbar bis hierhin.
GetInterfaceMethod(dxSurfaceInterface, i)
gibt mir auch nen wunderschönen Pointer auf die vermeintliche Blt-Function, allerdings stürzt das Spiel beim Aufrufen der originalen Blt-Function ab und wirft mir ne Access-Violation vor die Füße. :/

Verwundert mich ziemlich, da ich im Prinzip genau wie bei der CreateSurface-Methode vorgegangen bin..

Hier nochmal ein paar Code-Schnippsel zur Blt-Function:
Code:
HRESULT WINAPI hkBlt(LPDIRECTDRAWSURFACE7 lpdds, LPRECT recta,IUnknown** lpdd, LPRECT rectb,DWORD dw, LPDDBLTFX lpddtfx)
{
	add_log("Blt in");
	HRESULT result = pBlt(lpdds, recta, lpdd, rectb, dw, lpddtfx);
	add_log("Blt out");
	
	return result;
}
und oben:
Code:
//BLT
typedef HRESULT ( WINAPI *Blt_t)(LPDIRECTDRAWSURFACE7, LPRECT ,IUnknown** , LPRECT ,DWORD , LPDDBLTFX);
Blt_t pBlt;

HRESULT WINAPI hkBlt(LPDIRECTDRAWSURFACE7 lpdds, LPRECT recta,IUnknown** lpdd, LPRECT rectb,DWORD dw, LPDDBLTFX lpddtfx);
Würde mich freuen wenn jemand mir helfen könnte, oder Ideen hat.
Byteanzahl die beim detouren gesaved werden sollte stimmen.
Liege ich vielleicht Falsch bei der Annahme, dass die Blt-Methode sich an Stelle 5 im Interface befindet? Laut "DDraw.h" müsste ich richtig liegen..

Vielen Dank im Voraus,
Qu4rry
04/15/2012 17:01 Tyrar#2
grundsätzlich sehe ich da keinen fehler.
die 3 möglichkeiten die ich da in betracht ziehe sind:

1) falscher vtable index
2) funktion wird falsch gehookt (was ich nicht glaube)
3) parameter fail?

was vtable hooks angeht, verweise ich gerne auf [Only registered and activated users can see links. Click Here To Register...] methode -> der funktions pointer wird direkt in der vtable umgeschrieben, wodurch nur ein pointer zur alten funktion zu speichern ist (werden also garantiert keine instructions zerhackt)

allerdings hab ich bisher nicht viel mit dx7 gemacht
04/16/2012 02:02 qu4rry#3
1) Vtable index muss wie gesagt laut header richtig sein..
2) glaube ich auch nicht.. sonst dürften die anderen Funktionen eigtl auch nicht Funktionieren..
3) würde ich auch am ehesten denken, aber ich weiß einfach nicht was falsch sein könnte.. habe auch schon verschiedenes ausprobiert..

Was mir merkwürdig erscheint dass sich mir kein gewohnter Vtable offenbart wenn ich die xrefs zurückverfolge sondern dies:
[Only registered and activated users can see links. Click Here To Register...]
Beschäftige mich noch nicht lange mit dem Thema.. ist das richtig? wenn ich auf die dword Adresse klicke sieht das ganze schon eher aus wie ein vtable aber immernoch nich so wie ich es aus den Tutorials kenne.. liegt das daran dass ich eine Objekt::Methode hooke?
04/16/2012 02:13 Dr. Coxxy#4
seh jetzt so auch nichts, hab mit directdraw aber auch noch nix gemacht.
versuch mal mit nem statischen offset zur exported function.
DirectDrawCreate ist bei mir @ 0x7102859D, Blt @ 0x7106B0E1, offset ist also +0x42B44.

holst dir mit GetProcAddress die adresse von DirectDrawCreate, addierst 0x42B44 rauf und hast die adresse von Blt.
ist dann aber dll spezifisch, wenn jemand ne andere dll version hat gehts bei ihm nicht, aber die funktion wird ja im code referenziert, solltest also nen pattern machen können - extra für die funktion...
04/16/2012 02:37 qu4rry#5
Wenn ich mit deinem Offset die Adresse berechne stürzt er direkt ab.. IDA sagt dass er erst gar nicht an die berechnete Adresse springen kann.. Merkwürdig.

Darf ich fragen wie du mal eben an deine Blt Adresse gekommen bist? Wenn ich im IDA bei den Funktionen suche findet der nichts.. deswegen bin ich ja erst den oben beschriebenen Umweg gegangen.. :/
04/16/2012 02:42 Dr. Coxxy#6
ida->functions->string search...
[Only registered and activated users can see links. Click Here To Register...]
hab ich aber schon mehrmals gehört, dass bei anderen nicht die funktionsnamen gezeigt werden, weiß ehrlich gesagt nicht, woran das liegt.
ka. woher der die bei mir holt.

EDIT:
hier haste nochn screen von der funktion, kannst ja mal selber in ida/olly gucken ob du die so findest:
[Only registered and activated users can see links. Click Here To Register...]

EDIT2:
Quote:
Wenn ich mit deinem Offset die Adresse berechne stürzt er direkt ab.. IDA sagt dass er erst gar nicht an die berechnete Adresse springen kann.. Merkwürdig.
nimm mal olly und machs direkt in der exe.
04/16/2012 02:56 qu4rry#7
Mensch das ist echt merkwürdig.. Vorallem dass er mit deinem Offset bei mir nichts anfangen will..

Edit: K. Mach ich ;)

Die Funktion ist gleich. (was mich beruhigt =) ) Lediglich der letzte compare und jump Befehl fehlt bei mir.
Vielleicht haben wir unterschiedliche Versionen.. wie ich sehe hast du auch Vista. Ich hab XP.. das würde dann auch das mit dem Offset erklären.

Er lädt ja auch ständig Informationen aus ner DataBase.. Meine Theorie wäre, dass er für deine dll Version einfach mehr Informationen in der Database hat.. Aber wayne.

Zudem hab ich mal STRG + F5 gedrückt spuckt jetzt auf einmal mehr Parameterinformationen aus was mir auch bestätigt dass ich die Blt Methode erwischt habe..
Sieht jetzt so aus :O
[Only registered and activated users can see links. Click Here To Register...]
aber findet sich ja eigtl alles wieder von meinen Parametern her.. hilft mir also auch nicht weiter :/

Edit2: Nunja aber schonmal vielen dank Coxxy. Jetzt weiß ich wenigstens dass ich die richtige Adresse hab. Muss jetzt erstmal ne Mütze schlaf nehmen. Gn8
04/16/2012 05:17 Dr. Coxxy#8
wenn du die funktion jetzt hast, kannste dir doch den statischen offset selber ausrechnen.
einfach add der blt funktion - add der create funktion.
dann haste nen offset der bei dir gehen sollte.
(hab btw win7 64 bit. ;))

EDIT:
kannst ja auch mal in olly/ce gucken ob sich dein hook korrekt reinsetzt.
04/16/2012 06:27 Tyrar#9
ansonsten kann ich empfehlen zu debugging zwecken in der gehookten funktion ganz am anfang zu loggen, ob die überhaupt gecalled wird -> wenn nicht, dann ist der fehler garantiert der hook. so findet man das ganze meiner meinung nach leichter heraus als direkt mit olly drüber zu schauen, die parameter könnte man evtl. auch mit loggen um dann zu schauen, ob die pointer überhaupt valide sind
04/16/2012 12:07 qu4rry#10
Okay, ein Wunder. Es klappt. Mit dem eignen Offset ruft er erfolgreich die originale Funktion auf und verlässt diese wieder..
Aber Warum? :)

Nunja jedenfalls super vielen Dank an euch ;)