2

I have a pointer to IDirect3DDevice9 inteface with 119 methods (include 3 standart), implemented in d3d9.dll:

I need to get in my Delphi code offsets (in bytes) on methods EndScene() and Present() of the interface relative to the beginning of the library (DLL pointer).

var:
    g_pD3DDevice: IDirect3DDevice9;
    ProcAddr: Pointer;
    hD3D9: HMODULE;
    Present9 : DWORD;
    EndScene9: DWORD;

implemenation:
    hD3D9 := LoadLibrary('d3d9');
    ProcAddr := GetProcAddress(hD3D9, 'Direct3DCreate9');
    ...
    pD3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, TargetHandle, D3DCREATE_SOFTWARE_VERTEXPROCESSING, @D3DPP, g_pD3DDevice);

I guess, in the VMT the Present() method is number 17 (0-based), and EndScene() is 42, because it's written in the library header file.

But I think it is not good idea to calculate offsets like:

Present9 := DWORD(g_pD3DDevice) + (17 * 4) - DWORD(hD3D9);
EndScene9 := DWORD(g_pD3DDevice) + (42 * 4) - DWORD(hD3D9);

I'm making a hook injector for Direct3D by loading the DLL into the foreign process. I want to know what offset the Present () method has in the process, to make interception

Tell please, what is best practices how to realize the solution?

UDP 30/04/2017:

I have found one more solution described in docwiki.embarcadero.com:

function GetPresentMethodPointer(const IntRef: IInterface): Pointer; assembler;
asm
  mov eax, [IntRef] 
  add eax, vmtoffset IDirect3DDevice9.Present
  mov eax, [eax]
end;
Pax Beach
  • 2,059
  • 1
  • 20
  • 27
  • What's wrong with GetProcAddress() ? – Marco Apr 21 '17 at 11:44
  • That's all right with one, but I 'm not sure, what methods on 17 and 42 positions in the memory. – Pax Beach Apr 21 '17 at 11:47
  • 1
    Why are you mucking around with pointers and LoadLibrary? Request an instance of the interface and use it directly, as it's designed to be used. Why do you suppose the interfaces exist? So you can ignore them and do everything in a super round-about, unnecessarily complicated and error-prone fashion instead? – Ken White Apr 21 '17 at 12:29
  • Maybe this is a good idea, but I'm not sure that in an object, the method offset will be the same as in the interface. I'm making a hook injector for Direct3D by loading the DLL into the foreign process. I want to know what offset the Present () method has in the process, to make interception. – Pax Beach Apr 21 '17 at 12:36
  • @KenWhite That's how you link to DirectX libraries. As for why he wants to know the offset to the methods, that's to perform a code hook. – David Heffernan Apr 21 '17 at 12:58
  • 1
    @PaxBeach I think that the Delphi Detours library has code to detour interface methods. Either use that library, or use its source for inspiration. – David Heffernan Apr 21 '17 at 12:58
  • @PaxBeach I think that madCodeHook offers everything you need to hook code. You can choose if you want to hook APIs in your own process, or in a specific target process, or system wide. http://www.madshi.net/madCodeHookDescription.htm – fpiette Apr 21 '17 at 13:42
  • @fpiette why do I need pay 400 euro if I can write it myself? – Pax Beach Apr 21 '17 at 14:59
  • @David: Not according to the D3D9ExSample.cpp file in the Windows 7.0 SDK, it's not. For instance, see the `InitD3D()` and `CreateD3D9VDevice()` functions in that source code. It also calls methods of the interface retrieved using `pD3D->CheckDeviceFormat()` syntax. See also many other references to using it as a standard COM interface, and there's not a single reference to `LoadLibrary()` or `GetProcAddress()` in sight. – Ken White Apr 21 '17 at 16:55
  • @KenWhite Honestly. `Direct3DCreate9` is exported by `d3d9.dll`. You can import that function implicitly or explicitly. The latter uses `GetProcAddress`. Code written that way is often found for historical reasons. In the old days DirectX was not a system component and would not be found on vanilla systems. If you wanted your program to start up and run on such systems, perhaps with less functionality, then explicit linking was the answer. Such code persists today. It's how I do it still. You will find a typical example in the Delphi RTL, in `Winapi.Direct3D9`. – David Heffernan Apr 21 '17 at 18:22
  • @David: Then that's one option as to how to do it. Your previous comment said *That's how you link*, which was inaccurate. It's one way you can. You can also program against the native Win32 API when creating forms and buttons, but in modern times we don't. – Ken White Apr 21 '17 at 19:14
  • @ken OK. But it's a perfectly reasonable way to do it. Agreed? – David Heffernan Apr 21 '17 at 19:17
  • @David: It's a way to do it. I'd agree with that. Reasonable? Not so much. :-) – Ken White Apr 21 '17 at 19:19
  • @ken You have a lot of experience of this do you? – David Heffernan Apr 21 '17 at 19:20
  • @Rob Kennedy marked question with right answers. – Pax Beach Apr 21 '17 at 19:54
  • 1
    OK, these comments were getting a little personal, so I cleaned them up. Please try to keep things civil and polite. – Brad Larson Apr 21 '17 at 21:00
  • The post is closed for some reason of duplicate, therefore I have published сoncrete solution for Direct3D in the post https://ru.stackoverflow.com/a/657297/211994. If you don't understand that language, just see the code. – Pax Beach Apr 22 '17 at 23:46

0 Answers0