AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi D3D9 Hook bzw. als "proxy.dll"

D3D9 Hook bzw. als "proxy.dll"

Ein Thema von GOOFY009 · begonnen am 24. Okt 2009 · letzter Beitrag vom 21. Nov 2009
Antwort Antwort
Seite 1 von 3  1 23   
GOOFY009

Registriert seit: 24. Okt 2009
20 Beiträge
 
#1

D3D9 Hook bzw. als "proxy.dll"

  Alt 24. Okt 2009, 14:58
Hallo Leute,

ich versuche gerade die Proxy.dll von Michael Koch (Link ) nach Delphi zu portieren, da ich im Netzt nichts brauchbares in Delphi gefunden habe.

Leider sind meine Kentnisse in C++ eher "bescheiden" (eigentlich gegen NULL). Was mich aber nicht abhalten soll es dennoch irgendwie zu schaffen .

Zu Beginn würde es mir schon einmal reichen, die Originalfunktion aus der im SystemDir liegenden d3d9.dll zu laden und an das aufrufende Programm zurück zu geben.

Das Laden der Function stellt dabei kein Problem da.... nur wenn ich die Funktion
oDirect3D9_Create := GetProcAddress(gl_hOriginalDll, 'Direct3DCreate9'); aufrufe (Rückgabe ist ein Pointer) und dann mit
Delphi-Quellcode:
ppIDirect3D9_orig := IDirect3D9(oDirect3D9_Create(SDKVersion));
result := ppIDirect3D9_orig;
zurück geben will, habe ich ein Problem.

ppIDirect3D9_orig wird mir als Pointer(xxxxx) of IDirect3D9 angezeigt und damit kommt es zum Absturz des Programms/der Dll.

Ich habe auch hier schon im Forum gesucht und habe dabei diesen Beitrag gefunden, welcher mir aber nicht wirklich geholfen hat.

Wenn also jemmand eine Idee hätte oder vieleicht sogar vor dem gleichen Problem stand und mir helfen könnte
würde ich mich über entsprechene Hilfe/Tips sehr freuen.

Zum Abschluß noch der Code der DLL :
Delphi-Quellcode:
library d3d9;

uses
  Windows,
  SysUtils,
  Classes,
  Direct3D9,
  d3dx9,
  my_IDirect3DDevice9 in 'my_IDirect3DDevice9.pas',
  my_IDirect3D9 in 'my_IDirect3D9.pas',
  tools in 'tools.pas',
  global_var in 'global_var.pas';

type
  TDirect3DCreate9 = function(SDKVersion: LongWord): Pointer; stdcall;

var
  oDirect3D9_Create : TDirect3DCreate9 = nil;
  ppIDirect3D9_orig : IDirect3D9;

{$R *.res}


function Direct3DCreate9(SDKVersion: LongWord): IDirect3D9;
begin
  if gl_hOriginalDll = 0 then LoadOriginalDLL;

  oDirect3D9_Create := GetProcAddress(gl_hOriginalDll, 'Direct3DCreate9');

  ppIDirect3D9_orig := IDirect3D9(oDirect3D9_Create(SDKVersion));

  result := ppIDirect3D9_orig;

end;

procedure InitInstance;
begin
  gl_hOriginalDll := 0;
end;

procedure ExitInstance;
begin
  if gl_hOriginalDll <> 0 then begin
    FreeLibrary(gl_hOriginalDll);
    gl_hOriginalDll := 0;
  end;
end;

procedure DLLEntryPoint(reason : Integer);
begin
  case reason of
    DLL_PROCESS_DETACH :
      begin
        ExitInstance;
      end;
    DLL_PROCESS_ATTACH :
      begin
        InitInstance;
      end;
    DLL_THREAD_DETACH : exit;
    DLL_THREAD_ATTACH : exit;
  end;
end;

exports

Direct3DCreate9;

begin
  DLLProc := @DLLEntryPoint;
  DLLEntryPoint(DLL_PROCESS_ATTACH);

end.
Bei der ersten Quelle gibt es auch den Quellcode in C++ wenn benötigt.


CU
GOOFY
  Mit Zitat antworten Zitat
brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#2

Re: D3D9 Hook bzw. als "proxy.dll"

  Alt 24. Okt 2009, 18:07
Wenn du einen Wrapper schreibst, muss die deine Exportierte Funktion genauso aufgebaut sein, wie die, die du importierst.

Heißt also:

Delphi-Quellcode:
type
  TDirect3DCreate9 = function(SDKVersion: LongWord): IDirect3D9; stdcall;
var
  OrigDirect3DCreate9: TDirect3DCreate9;

function Direct3DCreate9(SDKVersion: LongWord): IDirect3D9; stdcall;
begin
  Result := OrigDirect3DCreate9(...);
  // eventl. Result zwischenspeichern und weiterverarbeiten
end;
Und in ProcessAttach solltest dann schon mit GetProcAddress die origianle funktion holen
  Mit Zitat antworten Zitat
GOOFY009

Registriert seit: 24. Okt 2009
20 Beiträge
 
#3

Re: D3D9 Hook bzw. als "proxy.dll"

  Alt 25. Okt 2009, 15:49
Hi!

Danke für den Hinweis. Der Fehler hatte sich wohl durchs viele "Herumprobieren" eingeschlichen.
Hier der nun funktionierende Code:

Delphi-Quellcode:
library d3d9;

uses
  Windows,
  SysUtils,
  Classes,
  DirectCreate in 'DirectCreate.pas';

{$R *.res}

exports

Direct3DCreate9;

procedure DLLEntryPoint(reason : Integer);
begin
  case reason of
    DLL_PROCESS_DETACH :
      begin
        ExitInstance;
      end;
    DLL_PROCESS_ATTACH :
      begin
        InitInstance;
      end;
    DLL_THREAD_DETACH : exit;
    DLL_THREAD_ATTACH : exit;
  end;
end;

begin
  DLLProc := @DLLEntryPoint;
  DLLEntryPoint(DLL_PROCESS_ATTACH);
end.
Delphi-Quellcode:
unit DirectCreate;

interface

uses
  Windows,
  SysUtils,
  Classes,
  ShareMem,
  Direct3D9,
  d3dx9;

var
  gl_hOriginalDll : THandle;

  Direct3DCreate9original: function(SDKVersion: cardinal): Pointer; stdcall;
  function Direct3DCreate9(SDKVersion: cardinal): Pointer; stdcall;

  procedure LoadOriginalDLL;
  procedure InitInstance;
  procedure ExitInstance;

implementation

function Direct3DCreate9(SDKVersion: LongWord): Pointer;
begin
  if gl_hOriginalDll = 0 then LoadOriginalDLL;
  @Direct3DCreate9original := GetProcAddress(gl_hOriginalDll, 'Direct3DCreate9');;
  result := Direct3DCreate9original(SDKVersion);
end;

procedure LoadOriginalDLL;
var
  SystemPath: array[0..MAX_PATH] of char;
  SysDir : String;
begin
  GetSystemDirectory(SystemPath, SizeOf(SystemPath));
  SysDir := SystemPath+'\d3d9.dll';
  gl_hOriginalDll := LoadLibrary(PChar(SysDir));
end;

procedure InitInstance;
begin
  gl_hOriginalDll := 0;
end;

procedure ExitInstance;
begin
  if gl_hOriginalDll <> 0 then begin
    FreeLibrary(gl_hOriginalDll);
    gl_hOriginalDll := 0;
  end;
end;

end.
Das funktioniert nun soweit. Jetzt müsste ich noch heraus bekommen, wie man das IDirect3D9 überschreibt um Zugriff auf die einzellnen Funktionen zu bekommen. Das Aufrufende Programm bekomm ja einen Pointer(xxxxx) of IDirect3D9 zurück ?!

Der C++ Aufruf sieht so aus :
Code:
   // Create my IDirect3D8 object and store pointer to original object there.
   // note: the object will delete itself once Ref count is zero (similar to COM objects)
   gl_pmyIDirect3D9 = new myIDirect3D9(pIDirect3D9_orig);
   
   // Return pointer to hooking Object instead of "real one"
   return (gl_pmyIDirect3D9);
Un die dazu gehörige Klasse (nur ein Teil sonst wird es zu lang):
Code:
// myIDirect3D9.cpp

#include "StdAfx.h"

myIDirect3D9::myIDirect3D9(IDirect3D9 *pOriginal)
{
    m_pIDirect3D9 = pOriginal;
}

myIDirect3D9::~myIDirect3D9(void)
{
}

HRESULT __stdcall myIDirect3D9::QueryInterface(REFIID riid, void** ppvObj)
{
    *ppvObj = NULL;

   // call this to increase AddRef at original object
   // and to check if such an interface is there

   HRESULT hRes = m_pIDirect3D9->QueryInterface(riid, ppvObj);

   if (hRes == NOERROR) // if OK, send our "fake" address
   {
      *ppvObj = this;
   }
   
   return hRes;
}

ULONG   __stdcall myIDirect3D9::AddRef(void)
{
    return(m_pIDirect3D9->AddRef());
}

ULONG   __stdcall myIDirect3D9::Release(void)
{
    extern myIDirect3D9* gl_pmyIDirect3D9;

   // call original routine
   ULONG count = m_pIDirect3D9->Release();
   
    // in case no further Ref is there, the Original Object has deleted itself
   // so do we here
   if (count == 0)
   {
      gl_pmyIDirect3D9 = NULL;
         delete(this);
   }

   return(count);
}

HRESULT __stdcall myIDirect3D9::RegisterSoftwareDevice(void* pInitializeFunction)
{
    return(m_pIDirect3D9->RegisterSoftwareDevice(pInitializeFunction));
}

UINT __stdcall myIDirect3D9::GetAdapterCount(void)
{
    return(m_pIDirect3D9->GetAdapterCount());
}
Wie bereits erwähnt... bin für jede Hilfe / Anregung offen...

CU
GOOFY
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: D3D9 Hook bzw. als "proxy.dll"

  Alt 25. Okt 2009, 16:10
Du schreibst selbst eine Klasse, die IDirect3D9 implementiert. AddRef und Release kannst du implementieren, indem du von TInterfacedObject ableitest, QueryInterface wahrscheinlich auch, und den Rest schreibst du entweder selbst oder delegierst an das ursprüngliche IDirect3D9. In deiner Direct3DCreate9-Funktion gibst du dann nicht mehr das ursprüngliche Interface zurück, sondern eine Instanz deiner eigenen Klasse, wobei du da wieder auf den RefCount aufpassen musst.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
GOOFY009

Registriert seit: 24. Okt 2009
20 Beiträge
 
#5

Re: D3D9 Hook bzw. als "proxy.dll"

  Alt 25. Okt 2009, 16:42
Danke für die schnelle Antwort !
Zitat von Apollonius:
Du schreibst selbst eine Klasse, die IDirect3D9 implementiert. AddRef und Release kannst du implementieren, indem du von TInterfacedObject ableitest, QueryInterface wahrscheinlich auch, und den Rest schreibst du entweder selbst oder delegierst an das ursprüngliche IDirect3D9.
Die Klasse habe ich schon geschrieben.

Zitat von Apollonius:
In deiner Direct3DCreate9-Funktion gibst du dann nicht mehr das ursprüngliche Interface zurück, sondern eine Instanz deiner eigenen Klasse, wobei du da wieder auf den RefCount aufpassen musst.
Wie stelle ich das an "..eine Instanz deiner eigenen Klasse" zurück zugeben ??? Die Direct3DCreate9-Funktion gibt ja einen Pointer (ohne erkennbare Zuweisung auf IDirect3D9) zurück.
result := Direct3DCreate9original(SDKVersion); Und was muss ich beim RefCount beachten ?


Fragen über Fragen...... und schon einmal Danke für jede weitere Hilfe.

CU
GOOFY
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#6

Re: D3D9 Hook bzw. als "proxy.dll"

  Alt 25. Okt 2009, 20:22
Ich schreibe das jetzt mal ohne Testen herunter. Deine Klasse dürfte ungefähr so aussehen:
Delphi-Quellcode:
TMyDirect3D9 = class(TInterfacedObject, IDirect3D9)
private
  fOrgDirect3D9: IDirect3D9;
public
  constructor Create(org: IDirect3D9);
  
  //Diese Prozedur einfach an fOrgDirect3D9.Direct3DProc1 weiterleiten
  procedure Direct3DProc1;
  procedure Direct3DProc2;
  //...
end;
Deine exportierte Funktion muss dann so aussehen:
Delphi-Quellcode:

var MyDirect3D9: IDirect3D9;

function Direct3DCreate9(SDKVersion: LongWord): Pointer;
begin
  if MyDirect3D9 = nil then
    MyDirect3D9 := TMyDirect3D9.Create(Direct3DCreate9original(SDKVersion));
  
  //Jetzt einmal den RefCount erhöhen
  MyDirect3D9._AddRef;
  return Pointer(MyDirect3D9);
end;
Dieses RefCount-Gemurkse ist nur deshalb notwendig, weil die Entwickler von Direct3D sich anscheinend nicht an COM-Regeln gehalten haben. Normalerweise gilt nämlich, dass man Interfaces nie als Rückgabewert, sondern nur als out-Parameter zurückgibt. Dann ergeben sich auch keine Probleme.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#7

Re: D3D9 Hook bzw. als "proxy.dll"

  Alt 25. Okt 2009, 22:10
Interfaces über einen Rückgaberwert zu liefern ist in Delphi ohne Probleme möglich und nichts problematisches, wenn man Delphi nicht austrickst. Dazu gehört, dass man nur mit dem Interface arbeitet und keine durch Create erzeugte Instanz besitzt. Zudem umgehen untypisierte Zeiger als Deckmantel für Interfaces die Referenzzählung (Wozu hier überhaupt?).

In C++ wird es eben nur mit OUT gemacht, weil jede COM Methode HRESULT zurückgeben muss; In Delphi gibt es dazu ja die Exceptions. Das sollte man bei der Interfacedeklaration berücksichtigen. Stichwort: safecall.
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
GOOFY009

Registriert seit: 24. Okt 2009
20 Beiträge
 
#8

Re: D3D9 Hook bzw. als "proxy.dll"

  Alt 26. Okt 2009, 22:22
@ Apollonius

So hatte ich mir das auch gedacht.... nur funktioniert das leider so nicht !

Wenn ich den Post von Dezipaitor richtig "deute", dann wiederspricht es dem was du (und auch ich) uns so vorgestellt hatten wie es funtionieren sollte ?!

@Dezipaitor

Mag sein das es heute schon etwas spät ist und der Arbeitstag lang war aber irgendwie hab ich deinen Post, trotz mehrfachen lesens, nicht verstanden

Vieleicht könntest Du mir mal etwas "einfacher" auf die Sprünge helfen (vieleicht mit einem Beispiel)?
Ansonsten werde ich am Mittwoch, wenn ich frei habe und etwas besser ausgeschlafen habe, mich noch mal dran setzten....

Auf jeden Fall mal Danke für eure Hilfe bisher....

CU GOOFY
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#9

Re: D3D9 Hook bzw. als "proxy.dll"

  Alt 26. Okt 2009, 22:36
Wenn du das Interface in einen Zeiger verwandelst, dann musst du selbst _AddRef benutzen, weil Delphi dann dies nicht mehr automatisch für dich übernimmt. Das ist völlig unabhängig, wie die Variable verwendet wird, ob per Result oder var- bzw. out-Parameter.
Wenn du den ResultZeiger durch den Interfacename ersetzt, dann solltest du kein _AddRef benötigen.
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
Benutzerbild von MisterNiceGuy
MisterNiceGuy

Registriert seit: 1. Jul 2003
Ort: Mannheim
919 Beiträge
 
Delphi 7 Personal
 
#10

Re: D3D9 Hook bzw. als "proxy.dll"

  Alt 27. Okt 2009, 14:19
OT: Ich find das Thema total spannend, hoffe du bekommst es hin
Jonas
Wenn mich jemand sucht, ich bin im Kühlschrank!

Informationen über das Duale Studium
www.jofre.de
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:23 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf