Direct3DCreate9 mit Detours hooken

Ja, ich weiß, dass es darüber viele Tutorials gibt (naja, eher eins in vielen Ausführungen), das Problem aber ist, dass sie einfach nicht funktionieren :(

Ich will einfach die Funktion Direct3DCreate9 systemweit hooken (detours 1.5)
Bislang habe ich das mit CreateProcess und FlashWindowEx sehr erfolgreich geschafft. Aber wenn ich das selbe mit Direct3DCreate9 versuche, passiert einfach garnichts :(
Dabei mache ich einfach nur folgendes:

DETOUR_TRAMPOLINE(IDirect3D9* WINAPI Real_Direct3DCreate9(UINT SDKVersion), Direct3DCreate9);


IDirect3D9* WINAPI Mine_Direct3DCreate9(UINT SDKVersion)
{
PlaySound(TEXT("SystemStart"), NULL, SND_ASYNC);
return Real_Direct3DCreate9(SDKVersion);
}

Das gleiche funktioniert bei FlashWindowEx allerdings - hier aber nicht.
Und natürlich habe ich nicht vergessen, die Funktion zu hooken.
Es muss an der Funktion selber liegen.
Natürlich habe ich auch ein Programm geschrieben, dass die Funktion einsetzt - an dem ich also ausprobieren kann, ob's funktioniert.

Aber warum geht das mit dieser Funktion nicht?
 
Soweit ich mich erinnere benutzt Direct3D sogenannte COM-Objekte. Ich weiß zwar wenig darüber bescheid (ist heute normalerweise auch nicht nötig), aber ich vermute das es daran liegt.
 
Zeig doch mal, wie du dein Testprogramm aufgebaut hast und wie du hookst.
Injezierst du bei deinem Testprogramm eine Dll und hookst dann darin?
Oder schreibst du die Routine zum Hooken direkt in das Testprogramm befor du Direct3DCreate9 aufrufst?
 
Nein, das Programm, in dem ich mit Detours die Funktion hooke, ist nur 'ne DLL. Die "installiere" ich dann mittels eines weiteren Programmes, wodurch dann sowas wie
Code:
DetourFunctionWithTrampoline((PBYTE)Real_Direct3DCreate9, (PBYTE)Mine_Direct3DCreate9);
ausgeführt wird.

Das Programm, womit ich das Teste, kommt direkt aus 'nem DirectX-Tutorial. ( http://www.directxtutorial.com/Tutorial9/B-Direct3DBasics/dx9B1.aspx > fast ganz unten über dem Finalen Screenshot "Show Code" )
Natürlich teste ich das auch mit anderen Programmen, bei denen ich mir dann aber nicht hunderprozentig sicher bin, dass diese Funktion ausgeführt wird.

Der Tipp mit dem COM ist schonmal gut, das alleine wird mich aber befürchte ich mal noch nicht sonderlich weiterbringen...

Hoffentlich hat jemand bald noch eine Idee.

Danke.
 
Vielleicht gibt es ja Probleme mit der PlaySound Funktion ,versuche mal statt dessen eine MessageBox auszugeben oder so.

Kann man denn überhaupt mit Detours systemweit hooken ?
Braucht man da nicht eher SetWindowsHookEx ?
 
Direct3D9Create ist eine ganz normale expotierte Funktion. Die hat noch nichts mit COM Objects zu tun. Sie liefert aber einen Interface Pointer zu einem COM-Object zurück.

Ich denke du bist einfach zu spät.
Du musst ja direkt nach dem Start des Beispiel-Direct3D-Programms sofort deine DLL injezieren, die die Funktion dann hookt.

Versuch doch mal deinen Detour direkt in das Beispielprogramm zu verbauen. So kannst du erstmal testen ob die Methode prinzipiell funktioniert.

Dann kann man weitersehen, wie du zum Beispiel schnell genug sein kannst um deinen Hook zu installieren.

Zum Beispiel:
- CreateProcess mit CREATE_SUSPENDED
- LoadLibraryExW hooken, prozess resumen und da auf die Direct3D Dll warten.
- Direkt nach dem Laden der DLL Direct3DCreate9 hooken und LoadLibraryExW hook entfernen
- Nach dem Aufruf von Direct3DCreate9 den interface pointer zum COM Object speichern und hook entfernen
 
An der PlaySound-Funktion liegt es definitiv nicht, da es ja bei FlashWindowEx funktioniert. Außerdem versuche ich bereits, eine Messagebox auszugeben, aber es kommt halt einfach keine.
Man kann natürlich mit Detours systemweit hooken, ich hatte ja bereits geschrieben, dass es mit FlashWindowEx und CreateProcess mit _exakt gleichem_ Aufbau funktioniert, nur eben nicht mit Direct3D9Create9.

Ich hab jetzt den Detour ins Beispielprogramm gebaut und gesehen, dass es prinzipiell wohl funktioniert.
Ich hab's auch mit dem Launcher aus dem CheatEngine-Tutorial versucht, aber 'ne MessageBox kommt nicht - für mich hat der Launcher daher kläglich verzagt.
Auf http://board.florian-quinkertz.de/phpbb/viewtopic.php?p=2651&sid= hat der Admin einen funktionierenden Clock-Overlay verfasst ( Direktlink für Nichtregistrierte ), dieser besteht aus einem Launcher, der offenbar wartet, bis das entsprechende Programm gestartet wurde und einer DLL, die wohl den Hook enthält.
Ich hab jetzt mal versucht, einfach die DLL durch meine eigene auszutauschen, da der Launcher ja die dann injecten würde. Leider passiert dann einfach garnichts...

Bei dem Beispiel
- CreateProcess mit CREATE_SUSPENDED
- LoadLibraryExW hooken, prozess resumen und da auf die Direct3D Dll warten.
- Direkt nach dem Laden der DLL Direct3DCreate9 hooken und LoadLibraryExW hook entfernen
- Nach dem Aufruf von Direct3DCreate9 den interface pointer zum COM Object speichern und hook entfernen
weiß ich ehrlichgesagt nicht, wie ich das hinkriegen soll "auf die Direct3D Dll warten"...
Ich würde annehmen, dazu bräuchte ich dann schon Interprozesskommunikation, und das kann ich garnicht bzw nur sehr primitiv (mit SendMessage und WriteProcessMemory...)
Es wäre echt toll, wenn ich irgendwie irgendwo endlich mal ein funktionierendes Beispiel mit Source finden könnte.
Oder ich zumindest noch weitere Tipps kriegen könnte...?
 
Ich habe mal eben die Sample.exe kompiliert und meinen eigenen Loader daran ausprobiert. Die Sample.exe ist einfach VIEL ZU SCHNELL. ;)
Da muss man anders herangehen.


Original von Xantoo
weiß ich ehrlichgesagt nicht, wie ich das hinkriegen soll "auf die Direct3D Dll warten"...
Ich würde annehmen, dazu bräuchte ich dann schon Interprozesskommunikation, und das kann ich garnicht bzw nur sehr primitiv (mit SendMessage und WriteProcessMemory...)
Es wäre echt toll, wenn ich irgendwie irgendwo endlich mal ein funktionierendes Beispiel mit Source finden könnte.
Oder ich zumindest noch weitere Tipps kriegen könnte...?

Nein. Du bist doch mit deiner DLL dann schon in dem Prozessraum. Da brauchst du keine extra IPC Techniken.
Du hookst LoadLibraryExW genauso wie du Direct3DCreate9 gehookt hast und zwar während der Prozess noch suspended ist. Nach dem Hook resumest du den Prozess und in deinem Callback von LoadLibraryExW guckst du nach ob die Direct3D Dll "d3d9.dll" als Parameter übergeben wird.
Wenn ja, dann lädst du sie kurz selbst (indem du die OriginalFunktion aufrufst) und direkt danach hookst du Direct3DCreate9, dann erst kehrst du von deinem Callback zurück.

EDIT: Noch einfacher: Anstatt aud die DLL zu warten, lädst du sie einfach selber vorher! xD
Also musst du nur folgendes tun:

- CreateProcessA mit CREATE_SUSPENDED
- Deine Dll injezieren und "d3d9.dll" laden + Funktion hooken
- Prozess resumen

Hab es eben ausprobiert. Klappt wunderbar. :)
Wenn du nicht weiterkommst, kann ich dir die Testprojekte geben.
 
Okay, ich komme nicht weiter :(
Ich hab' nämlich leider fast keine Ahnung, wie ich denn die DLL jetzt auch noch in den Prozess injecte. Die Mehr-oder-weniger-asm-Variante hier aus dem Wiki ist mir zu anfällig gegen Antivirensoftware und DetourCreateProcessWithDll() funktioniert ja leider nicht so, wie's soll. Ich hab das eigentlich immer mit

Code:
BOOL APIENTRY DllMain( HANDLE hinstDLL, DWORD  fdwReason, LPVOID lpvReserved )
{
	g_hInst = hinstDLL;
	switch (fdwReason)
	{
		case DLL_PROCESS_ATTACH:
			Intercept();
			break;
		case DLL_THREAD_ATTACH:
			break;
		case DLL_THREAD_DETACH:
			break;
		case DLL_PROCESS_DETACH:
				UnIntercept();
			break;
    }
    return TRUE;
}

LRESULT CALLBACK MyShellProc (int nCode, WPARAM wParam, LPARAM lParam)
{
	return ::CallNextHookEx( g_hHook, nCode, wParam, lParam );
}

void InstallHook()
{
	if(g_hHook == NULL)
		g_hHook = ::SetWindowsHookEx( WH_SHELL , MyShellProc ,(HINSTANCE)g_hInst, 0);
}

void UninstallHook()
{
	if(::UnhookWindowsHookEx( g_hHook ))
		g_hHook = NULL;
}
gemacht...

Es wäre echt total toll, wenn du mir die Testprojekte geben würdest. ^_^
Irgendwas habe ich da noch nicht korrekt verstanden und das dumme ist - ich weiß nicht was :S
 
Eins nach dem anderen. ;)
Hast du es denn jetzt schon geschafft, wenigstens die sample.exe zu hooken so wie ich vorschlug?
Meine Testprojekte setzen nur das um.

Wenn du jetzt noch systemweit hooken möchtest und auch jeden neuen erstellen Prozess abfangen möchtest, musst du so vorgehen:

In deinem Loader:
- Jeden Prozess durchgehen und deine DLL injezieren.

In der DLL:
- CreateProcessA und W hooken (oder nur CreateProcessInternalW)
- d3d9.dll laden mit LoadLibrary
- Direct3DCreate9 hooken

Im Callback von dem CreateProcess-Hook:
- bei den Creation-Flags CREATE_SUSPENDED hinzufügen (falls dieser Flag schon vorhanden ist, es so belassen und den Prozess später NICHT selbst resumen)
- Die DLL in den neu erstellten Prozess injezieren (welche wiederum hookt usw.)
- Den Prozess resumen -> ResumeThread(pi.hThread)

Ein Nachteil, wenn man das so macht: Egal ob die Anwendung Direct3D benutzt oder nicht -> Die d3d9.dll wird in jedem Fall geladen und alles gehookt.
Zum optimieren könnte man sich nun Kriterien überlegen, wann man es besser sein lässt, oder man macht es dann wirklich so, dass man LoadLibrary hookt und schaut ob der Prozess irgendwann d3d9.dll laden möchte.
 
Das mit dem Systemweit würde ich ja noch hinkriegen. Aber wenigstens die sample.exe zu hooken -> schaffe ich nicht :(
Irgendwie krieg' ich's nicht hin, die DLL zu injezieren, weil ich nicht weiß, wie ich das machen soll?
 
Hier [1] das Testprojekt.
Credits sind unvollständig. Denke mal da wird keiner böse sein.
Jedenfalls wäre da allgemein gamedeception.net zu nennen. :P

Inhalt
1.) Der Loader geschrieben in FASM. (hab es umgreschrieben, vorher hat es periodisch auf den Prozess gewartet wie übliche Loader)
-> startet die Sample.exe suspended und injeziert dann die DLL, danach resume

2.) Relativity: Die DLL (mein gekürztes Projekt-Skelett für Cheats :P)
-> darin findest du den Hook für Direct3DCreate9 + Debug-Ausgabe

3.) Die kompilierte Sample.exe


[1] xxx
 
Okay, vielen Dank, damit kann ich schonmal mehr anfangen.
Allerdings wundere ich mich noch über eine Sache:
In der Loader\waiter\Relativity wird das ganze ja so ähnlich wie bei wiki.hackerboard.de/index.php/DLL-Injektion gemacht. Allerdings braucht man nach meinem Verständnis dieses Artikels das DebugPrivilege, um mit OpenProcess auf den Prozess zugreifen zu können.
Und das finde ich sehr merkwürdig :/
Kann mich jemand aufklären?
 
Das SeDebugPrivelege muss man nur dann aktivieren, wenn man ein Handle mit PROCESS_ALL_ACCESS zu einem Prozess braucht, welches unter einem anderen NT User-Account läuft. Wenn sowohl der Loader als auch das Ziel-Programm mit den gleichen User Credentials laufen, dann gibt es keine Probleme.
 
Okay, dann hätte ich noch eine Frage/Problem:

Im HaBo-Wiki-DLL-Injection-Tutorial (Link oben) meint man wohl, man könne einfach zwei Funktionen threadstart und threadend definieren und dann daran die Größe ermitteln. Ich hab's mal ausprobiert und bin zu einem negativen Ergebnis für funcsize gekommen. Außerdem ändert sich die "Größe" durch nichts.

Geht es also nur, wenn ich inline-Assembler benutze? Oder was muss ich machen? So wie im HaBo-Wiki geht's jedenfalls nicht...

EDIT:

So, hab's hinbekommen, indem ich den Assemblercode 1:1 in C++ Code übersetzt habe. Anstelle den Speicher für ausführbaren Code im anderen Prozess zu sichern, wird ja in dem Relativity-Code direkt LoadLibrary ausgeführt. So geht's auf jeden Fall besser. Klappt soweit erstmal alles... - fast.
Mit PROCESS_ALL_ACCESS brauche ich das DebugPrivilege, damit OpenThread funktioniert. Und mit PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_VM_READ bekomme ich bei CreateRemoteThread als Errorcode nur Zugriff verweigert :/

EDIT2:

Ich glaube, ich hab's hingekriegt. Laut MSDN sollte ich
#define _WIN32_WINNT _WIN32_WINNT_WINXP
ganz oben hinzufügen. Habe ich gemacht und jetzt geht's. Vielen Dank, der Launcher funktioniert damit schonmal :)

EDIT3:

Allerdings noch ein Problem :(
Ich wollte jetzt die DLL machen, aber das ist wohl garnicht so einfach. Mit Detours 1.5 geht's schonmal garnicht, da passiert einfach so viel wie vorher, nämlich nichts.
Und mit diesem Relativity-SourceCode geht's auch nicht, ich kann den Source nämlich zwar sogar 1:1 übertragen, bekomme dann aber 'ne kryptische Fehlermeldung vom Linker:
Code:
1>uD3DHooks.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""public: unsigned char __thiscall Detour_c::RemoveDetour(void)" (?RemoveDetour@Detour_c@@QAEEXZ)".
1>uD3DHooks.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""public: unsigned long __thiscall Detour_c::SetupDetour(void)" (?SetupDetour@Detour_c@@QAEKXZ)".
1>uD3DHooks.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""public: __thiscall Detour_c::Detour_c(unsigned long,unsigned long)" (??0Detour_c@@QAE@KK@Z)".

Was hat das zu bedeuten?

EDIT 4:

Gerade noch die leuchtende Idee gehabt *puh* . Man muss offensichtlich auch die Detour.cpp usw dem Projekt hinzufügen, sonst werden sie nicht mitkompiliert und es gibt natürlich diesen Linker-Fehler...

EDIT 5:
So, Direct3DCreate9 habe ich erfolgreich gehookt. Leider geht CreateDevice noch nicht. Ich hab dazu mal einen neuen Thread gestartet, damit das hier jetzt nicht zu unübersichtlich wird. Ich hoffe, ich bekomme auch wieder so gute Antworten wie hier, denn ich hab echt keine Ahnung, warum das nicht geht wie ich das will...

EDIT 6:
Leider habe ich keine Antworten erhalten. Das Problem habe ich aber trotzdem noch halbwegs lösen können. Jetzt wollte ich das ganze mal mit Hook als Launcher machen, jedoch musste ich dabei leider zu folgender Erkenntnis gelangen:

Wenn z.B. der Explorer mein Programm aufruft, funktioniert der Hook meistens. Sobald mein Programm dann aber über CreateProcessA/W ein anderes Programm ausführt, wird der Hook dabei umgangen. Das ergibt für mich zwar keinen Sinn, aber so wie es aussieht werde ich auch keine Antworten erhalten, das Problem ist demnach unlösbar.

Schade ;(
 
Zurück
Oben