Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Heiko

Frischling

  • »Heiko« ist der Autor dieses Themas

Beiträge: 19

Wohnort: @home

  • Private Nachricht senden

1

20.04.2009, 18:18

IDirect3D9 C++ Hook Code...need help

Hallo erstmal....
Ich habe David S. schonmal angeschrieben, poste hier aber auch nochmal.....
Vielleicht kann mir jemand helfen.
Ich nutze eine 3D Engine basierend auf DX9.
Möchte mit der Zeit ein 2D Addon coden, problem ist aber der DX) hook.
Also möchte mich im IDirect3D9 einklicken, bzw. dieses "ausleihen"

Ich habe zwei codes, die diese funktionalität zwar bieten, aber eben nur einen pointer auf mein dx9 zeug bereitstellen.
Brauch aber, weils eine libraray werden soll, zwei befehel wie StartDraw und Enddraw, um dazwischen meine funktionen plazieren zu können.
Soll halt auch eine Engine werden....

Ich poste den code gern, wenn mir jemand helfen möchte.

2

20.04.2009, 19:28

Ich habe gerade einige Verständnisprobleme.

Hast du dir die 3D Engine selbst gecodet? Willst du mit der 3D Engine
ein 2D Addon coden oder eine komplett neue Engine für das 2D Addon
coden?

Wenn du so etwas wie StartDraw und EndDraw brauchst, dann solltest
du dir mal IDirect3DDevice9 anschauen, bzw.
IDirect3DDevice9::BeginScene
IDirect3DDevice9::EndScene

Für deine 2D Engine solltest du natürlich die z-Achse deaktivieren und so.
MfG Shiver!

„Ideen sind nur Ausgangspunkte. Um zu wissen, was man zeichnen will, muss man zu zeichnen anfangen.“ Pablo Picasso

Ibot Development - Mein Weg zum eigenen 2D RPG

Heiko

Frischling

  • »Heiko« ist der Autor dieses Themas

Beiträge: 19

Wohnort: @home

  • Private Nachricht senden

3

20.04.2009, 19:35

Okay ich erklärs kurz.
Ich nutze eine fremde 3D Engine.
Dafür möchte ich ein 2D Addon coden.

In der 3D Engine gibt es einen Befehl namens xGetDevice, welches einen Pointer auf IDirect3D9 Device zurückgibt.(falls mir das was nutzt)

Also müsste ich auf jeden Fall vor Endscene die Device hooken, um dann eben die funktionen meiner 2D Engine ausführen zu können.

Hoffe das war verständlich....

Sowas in der Art, aber eben als zwei funktionen, um meine eigenen Funktionen einbinden zu können, man soll das 2D Addon ebenso wie die 3D Engine mit verschiedenen Programmiersprachen nutzen können.

Hier mal ein code, eben sowas in der art....sollte ein StartDraw und ein EndDraw draus werden...
Vielleicht kann mir da jemand helfen....

(aufgabenstellung wäre beispielsweise ein Startdraw ein enddraw und ein Draw[irgendwas](als beispielfunktion))

so hier der code:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// 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 hier auch noch was in der art....

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/ 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);
}
[/cpp]

Gotbread

Alter Hase

Beiträge: 421

Beruf: Student (Etechnik) + Hiwi

  • Private Nachricht senden

4

20.04.2009, 23:58

dein detour code sieht ja ganz ok aus :D

um an die funktion zu kommen, musst du "einfach" die addresse von endscene holen:

(ungetestet)

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
IDirect3DDevice9 *dev = get_device_from_irgentwoher();
endscene_t endscene = reinterpret_cast<endscene_t>(&dev->EndScene);

endscene_t orig = detour(endscene, myendscene);

// in der hookfunc


// endscene bearbeiten

return orig(dev);


vielleicht hab ich aber auch nicht ganz verstanden was du willst :)
Mfg Goti
www.gotbread.bplaced.net
viele tolle spiele kostenlos, viele hardware-basteleien :)

"Es ist nicht undicht, es läuft über" - Homer Simpson

Anonymous

unregistriert

5

21.04.2009, 09:07

Ich hab das Detours von Microsoft Research nicht mehr vor augen, aber gab es da nicht mal ein "Members"-Beispiel?

Heiko

Frischling

  • »Heiko« ist der Autor dieses Themas

Beiträge: 19

Wohnort: @home

  • Private Nachricht senden

6

21.04.2009, 10:29

mir geht es darum, eine funktion zu hben, die sich die device holt.
und eine funktion, die sie wieder zurückgibt.

es darf nicht alles in einer einzigen funktion stehen.
da wenn man die engine nutzt, im quellcode es ungefähr so aussehen soll....

Quellcode

1
2
3
4
5
6
Init3D()
// 3d engine code
Init2D(getdevice von 3D engine) // start des hooks(es gibt einen Getdevice befehl in der 3d engine)
DrawRect(w,h,x,y)   //irgendeine draw funktion als bsp.
DeInit2D() Device zurück an 3D Engine geben
Flip() // 3D Engine render alles


daraus sollte man erkennen, daß ich mindestens zwei befehle brauche im einmal die device der 3d-engine.dll zu holen und eine um zurückzugeben.
Und die dll von mir enthält dann die dx9 funktionen, die ich da dann haben möchte....

Hoffe das war gut erklärt, und jemand weiß wie das ganze nun aussehen müsste.....

Und das GetDevice gibt es wirklich, also die dx9 device der 3D engine zu holen ist kein problem.

Helmut

5x Contest-Sieger

Beiträge: 692

Wohnort: Bielefeld

  • Private Nachricht senden

7

21.04.2009, 12:59

Also wenn ich deinen letzten Post richtig verstehe brauchst du garnichts zu hooken. Nimm einfach das Device von der 3D Engine, zeichne damit was zu willst und gut ist.

Wenn du darüber benachrichtigt werden willst, dass die 3D Engine EndScene aufruft, hast du prinzipiell 2 Möglichkeiten (falls die Engine sowas nicht gleich direkt unterstützt):
1: Du manipulierst die vtable vom Device so, dass deine Funktion aufgerufen wird. Wie das geht dürfte Google erklären können.
2: Du hookst Direct3DCreateDevice und lieferst dorft deine eigene Deviceimplementierung zuück, die dann wahrscheinlich für die meisten Methoden das originale Device aufruft. Setzt natürlich voraus, dass du dich in den Prozess hooken kannst, bevor er das Device erstellt.

Ciao
Sei stets geduldig gegenüber Leuten, die nicht mit dir übereinstimmen. Sie haben ein Recht auf ihren Standpunkt - trotz ihrer lächerlichen Meinung. (F. Hollaender)

Heiko

Frischling

  • »Heiko« ist der Autor dieses Themas

Beiträge: 19

Wohnort: @home

  • Private Nachricht senden

8

21.04.2009, 13:19

da haste eigentlich recht, stimmt.
kannst du mir sagen wie ich eigentlich das device für alle kommenden funktionen "mopsen" kann?

und mit dem endscene weiß ich eben auch nicht so recht.

wahrscheinlich hab ich mich von einer anderen 2d engine durcheinanderbringen lassen.

Dort gibt es nämlih folgende funktionen, die vor dem rendern benutzt werden können.
und zwar:

Init(GetDeviceDX9_der Engine_interne Befehl)
StartDraw()
EndDraw()
DeInit

Wobei nur Init(GetDeviceDX9_der Engine_interne Befehl), StartDraw und EndDraw wirklich nötig sind.

Also wie würde der code einer dll aussehen, welcher
eine Init funktion enthält(dort kann mit GeDevice der parameter angegeben werden)

Und gegebenfalls eben startdraw und enddraw....

Also ich möchte eine DLL bauen, welche sich in die device einklinkt, dort eigene dx9 befehle ausführen kann, und eben die device wieder zurückgibt.

Sorry, daß ich daß nich immer so einleuchtend erklären kann, ist aber auch nicht wirklich einfach....zu beschreiben.

Wir bekommen die device bzw. den pointer darauf, und nun muss man doch irgendwie das ganze für ein addon nehmen können.

(am rande muss ich sagen, daß ich den code noch konvertieren will, weil ich in C++ nicht so fit bin, zumindest bin ich noch am lernen)

9

21.04.2009, 18:06

Das mit dem Device ist nicht allzu schwierig.
Du brauchst halt eine Variable für das Device und lässt dir mit einer
Funktion das Device zurückgeben.

C-/C++-Quelltext

1
2
3
4
5
6
LPDIRECT3DDEVICE9 Device;

LPDIRECT3DDEVICE9 CDirect3D::GetDevice(void)
{
    return Device;
}
MfG Shiver!

„Ideen sind nur Ausgangspunkte. Um zu wissen, was man zeichnen will, muss man zu zeichnen anfangen.“ Pablo Picasso

Ibot Development - Mein Weg zum eigenen 2D RPG

Heiko

Frischling

  • »Heiko« ist der Autor dieses Themas

Beiträge: 19

Wohnort: @home

  • Private Nachricht senden

10

21.04.2009, 18:29

nein das getdevice bekomm ich von der 3d engine schon....(da gibts nen befehl xGetDevice)

ich will nur damit "zeichnen" können.
innerhalb meiner dll....(und verschiedene dx9 funktionen dazu bauen)

oder muss ich da nur jedesmal mein dx9 zeugs an die device schicken?

mehr nicht?!?
und irgendwann will die 3d engine ja wieder die device zurück, oder ist das unnötig?

Werbeanzeige