DX9 Hook-Aus einer Funktion zwei machen



  • Aus aktuellem Anlaß mußte ich den Topictitel und den Inhalt geringfügig ändern.
    Wollte keinen extra Thread aufmachen...(entschuldigt bitte den Pushpost unten)
    Und zwar, habe zwei codes gefunden, der erste den ich dann posten werde, scheint mir besser.
    Kurz gesagt ich nutze eine 3D Engine, will dort hooken, aber nicht nur einfach was zeichnen, sondern es soll später eine 2D Erweiterung zu der 3D Engine werden.
    Problem ist, dazu benötige ich zwei Funktionen ala "StartDraw()" und eine "EndDraw()", wobei zwischen beiden funktionen das IDirect3D9 Device bei meiner 2D Engine.dll liegt, da ich funktionen wie loadimage und drawimage etc. einbauen will.
    Auch ist es möglich den Pointer auf die Direct3D9 Device der 3D Engine zu bekommen(mit einem befehl in der 3D Engine).Falls das nützlich sein sollte.

    Hier die codes, wo ich nun zei funktionen in der DLL brauch wie oben beschrieben.
    Wäre nett, wenn sich das jemand anschauen könnte, und mir helfen kann.Muß auch nicht umsonst sein, wenns läuft.

    // dllmain.cpp : Defines the entry point for the DLL application.
    #include "stdafx.h"
    #include <winsock2.h>
    
    /*
    Fake export function
    */
    extern "C" __declspec(dllexport) void fakeexportfunction()
    {
    return ;
    }
    
    // Functions to be Hooked/Detoured
    
    IDirect3D9 * (WINAPI * Real_Direct3DCreate9)(UINT SDKVersion) = Direct3DCreate9;
    
    // Functions that replace Hooked/Detoured version
    
    IDirect3D9 * WINAPI Hook_Direct3DCreate9(UINT a0)
    {
    	Beep(1000, 1000);
    	IDirect3D9 * rv;
    	__try {
    		rv = Real_Direct3DCreate9(a0);
    	} __finally {
    		OutputDebugString(TEXT("Direct3DCreate9\n"));
    	}
    	OutputDebugString(TEXT("Direct3DCreate9\n"));
    	return rv;
    }
    
    BOOL APIENTRY DllMain( HMODULE hModule,
                           DWORD  ul_reason_for_call,
                           LPVOID lpReserved
    					 )
    {
    	LONG error;
    	switch (ul_reason_for_call)
    	{
    	case DLL_PROCESS_ATTACH:
    		DetourRestoreAfterWith();
    
    		DetourTransactionBegin();
    		DetourUpdateThread(GetCurrentThread());
    		DetourAttach(&(PVOID&)Real_Direct3DCreate9, Hook_Direct3DCreate9);
    
    		error = DetourTransactionCommit();
    
    		if (error == NO_ERROR)
    		OutputDebugString(TEXT("Attached Hooks\n"));
    		break;
    	case DLL_THREAD_ATTACH:
    		break;
    	case DLL_THREAD_DETACH:
    		break;
    	case DLL_PROCESS_DETACH:
    		DetourTransactionBegin();
    		DetourUpdateThread(GetCurrentThread());
    		DetourDetach(&(PVOID&)Real_Direct3DCreate9, Hook_Direct3DCreate9);
    
    		error = DetourTransactionCommit();
    
    		OutputDebugString(TEXT("Detached Hooks\n"));
    		break;
    	}
    	return TRUE;
    }
    

    und der zweite...

    / D3d hook 
    
    #include <windows.h>
    #include <cstdio>
    #include <d3d9.h>
    #include <d3dx9.h>
    
    typedef HRESULT(__stdcall* EndScene_t)(LPDIRECT3DDEVICE9); // typedef
    EndScene_t pEndScene;
    
    void InitHook();
    void *DetourFunc(BYTE *src, const BYTE *dst, const int len);
    
    HRESULT __stdcall hkEndScene(LPDIRECT3DDEVICE9 pDevice)  
    {
    	// das ist das entscheidende: Wenn normalerweise EndScene aufgerufen wird, wird diese Funktion von dem Programm aufgerufen
    	// hier kommen deine Sachen hin die man drawn mit pDevice.
    
    	// und dann noch zurück zum originalen EndScene, diese muss ja auch aufgerufen werden
    	return pEndScene(pDevice);
    }
    
    int WINAPI DllMain(HINSTANCE hInst,DWORD reason,LPVOID reserved)
    {
            switch(reason)
            {
            case DLL_PROCESS_ATTACH:
                    CreateThread(0, 0, (LPTHREAD_START_ROUTINE) InitHook, 0, 0, 0);
                    break;
            }
            return true;
    }
    
    void InitHook()
    {
            HMODULE hModule = NULL;
            while( !hModule )
            {
                    hModule = GetModuleHandleA( "d3d9.dll" ); // Handle zur DLL holen
                    Sleep( 100 ); // 100ms warten
            }
    
    		// 0x4FDD71B0 ist die Addresse für EndScene in d3d9.dll
    		pEndScene = ( EndScene_t )DetourFunc((PBYTE)  0x4FDD71B0,(PBYTE)hkEndScene, 5); // hier ist der hook
    }
    
    void *DetourFunc(BYTE *src, const BYTE *dst, const int len) // detour, muss man nicht wirklich verstehen. Der Code ersetzt das alte endScene durch unseres. Ist von gd
    {
    	BYTE *jmp = (BYTE*)malloc(len+5);
    	DWORD dwback;
    	VirtualProtect(src, len, PAGE_READWRITE, &dwback);
    	memcpy(jmp, src, len); jmp += len;
    		jmp[0] = 0xE9;
    	*(DWORD*)(jmp+1) = (DWORD)(src+len - jmp) - 5;
    	src[0] = 0xE9;
    	*(DWORD*)(src+1) = (DWORD)(dst - src) - 5;
    	VirtualProtect(src, len, dwback, &dwback);
    	return (jmp-len);
    }
    


  • Hook halt EndScene, such dazu mal was vielleicht findest was... du Codest eine DLL, welche EndScene hookt (such die Addresse am besten mit IDA) und injectest das ganze und in dieser DLL kannst du dann dein eigenes Zeug zeichnen (mit dem device aus EndScene).
    Ist bisschen leichter



  • theoretisch weiß ich ja wie es funktioniert, nur bin ich mit meinem c++ wissen noch nicht so weit, das umzusetzen.
    Ich würde gern etwas probieren....Daher meine Anfrage hier.
    Hab dir eine mail geschickt.



  • sorry, aber hab den ersten post editiert, suche jemanden auf honorarbasis, der mir das erledigt...



  • ehm du hast den 2. Code gefunden? Den Code hab ich dir genauso wie er da steht zugeschickt lol.



  • ich wollte es eigentlich nur erläutern, daß beide codes nicht von mir sind....
    sorry, daß war keine absicht.



  • Wofür brauchst du denn die Start Funktion? Du willst doch zeichnen, und vor'm Starten is' da nix mit zeichnen.



  • ähm eigentlich doch ganz easy.
    3D Engine startet directx9.
    Anbei bemerkt es ist eine dll.
    Und meine dll soll die device von der engine übernehmen können, und wieder zurückgeben können.
    also ein startdraw/init2d(wasauchimmer)



  • Was hat das Zeichnen mit Intialisierung zu tun?
    Und so ein Init2D gibt's nicht, und wenn, dann nur vom Autor selber.



  • Das Init2D oder auch StartDraw soll ja die funktion sein, die die device der 3d engine nimmt.

    und deinit2d oder enddraw solls wieder zurückgeben....
    das sollen ja die funktionen meiner dll mal werden, init2d oder startdraw waren nur beispiele....

    okay wie würdet irh es denn machen, wenn ihr einen pointer auf die device der 3d engine bekommen würdet.
    Und ihr funktionen diesbezüglich für eine 2d engine coden würdet?



  • wenn die 3d engine dir das device gibt, kannst du es einfach benutzen wie man es machen wuerde, wenn man die engine schreibt. ich versteh dein problem nicht. ein hook ist absolut nicht noetig wenn du, wie du sagst, von der engine das device hast.



  • kann mir jemand ein total simples beispiel geben, um was mit dx zu zeichnen....hab zwar nen dicken wälzer über dx9, aber das is echt komplex....

    einfach mal um zu testen...

    [edit]
    es gibt ja schon so ein addon für die 3d engine, diese hat befehle namens init, startdraw und enddraw....in einem anderen forum wurde mir dazu folgendes gesagt....

    Es sollte auf jeden Fall geprüft werden, ob nicht doch noch ein Release aufzurufen ist, sobald das Device nicht mehr benötigt wird. Ich würde zumindest von der xGetDevice-Funktion erwarten, dass sie den Referenzzähler der Device-Schnittstelle erhöht.

    So ein "Rahmen" ist nie verkehrt. Mit dessen Hilfe lassen sich ganz wunderbar z.B. Render-States am Anfang individualisieren und am Ende wieder auf vorherige Werte zurücksetzen.

    da steh ich grad aufm schlauch....



  • Was bitte hat das im Projekte Forum verloren? 😕



  • Gute Frage... Ich schau's mir noch etwas an und verschiebs dann nach rudpf oder so 🙂



  • in Spiele-/Grafikprogrammierung gibt es auch schon ein paar threads von ihm dazu.



  • nein eigentlich wollte ich, daß hier im projekte forum haben, weil mir jemand was machen sollte.....
    das das so OT wurde...naja sorry

    [edit] *und um wieder ins Forum hier zu passen:
    *
    Wer macht mir So eine Init(xGetDevice) Funktion, sowie etwaige "Rahmen" Funktionen, deren Notwendigkeit ich noch nicht vollends verstanden habe, also schon deren zweck, aber wovon aghängig ist, daß man sie brauch eben noch nicht.
    Desweiteren eine DX9 Funktion die irgendwas zeichnet, ein DrawDreieck oder so, würde ja reichen.Und falls nötig eben noch ein EnDInit, oder so...falls nötig.
    Das ganze gegen bezahlung, falls mir niemand einfach so helfen kann, oder möchte.
    Das ganze hat auch einen riesigen lernfaktor für mich persönlich, sonst hätte ich es schon sein gelassen.



  • itmagic schrieb:

    nein eigentlich wollte ich, daß hier im projekte forum haben, weil mir jemand was machen sollte.....

    Aaaaah *pling* 💡


Anmelden zum Antworten