Finding the Direct3D VMT table to hook EndScene menu

User Tag List

Results 1 to 15 of 15
  1. #1
    revertlife's Avatar Private
    Reputation
    11
    Join Date
    Jun 2010
    Posts
    11
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Finding the Direct3D VMT table to hook EndScene

    Can anyone give me insight on how to find the Driect3D device VMT table either in disassembly or at runtime?

    In my injected DLL I have tried to use the hardcoded addresses give in the 3.3.5 Offset topic but whenever I read from the D3D Device pointer address (0x00C5DF80), I read 0x00000000. I've also attached a debugger to WoW.exe both during login screen and ingame and in both cases the memory address is just zeroes.

    Am I supposed to use the given 3.3.5 offset to add to another address? In another direction, can I use SlimDX from my injected DLL to create my own Direct3D object and use that as a pointer to the VMT or does each separate instance of the Direct3D object have its own VMT?

    Edit: Ignore that last question. 10 seconds after posting I realized that the SlimDX VMT will point to the same EndScene function. However, would there be any issues with SlimDX somehow using another instance of the Direct3D DLL or would Windows make sure that the DLL injected into the WoW process uses the same dll?

    Edit2: Ignore the edit as well. SlimDX creates a managed Direct3D object of its own, so it doesn't have the same VMT as a normal D3d device.
    Last edited by revertlife; 07-06-2010 at 04:06 PM.

    Finding the Direct3D VMT table to hook EndScene
  2. #2
    galpha's Avatar Member
    Reputation
    5
    Join Date
    Nov 2007
    Posts
    48
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You got 3 possibilities here:

    1 - Grab the D3D pointer from the static address.
    2 - Create your own device and grab the VMT from your D3D Interface (it has the same VMT as the WoW one) then destroy it.
    3 - Hook CreateDevice and grab the WoW D3D Interface from there.

  3. #3
    russmice's Avatar Private
    Reputation
    6
    Join Date
    Jun 2010
    Posts
    4
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    its simple

    1 - find Direct3DCreate9 offset in dll

    Code:
    	HMODULE hDLL;
    	hDLL=GetModuleHandleA("d3d9");
    	LPDIRECT3D9(__stdcall*pDirect3DCreate9)(UINT) = (LPDIRECT3D9(__stdcall*)(UINT))GetProcAddress( hDLL, "Direct3DCreate9");
    2 - get IDirect3D9
    Code:
    LPDIRECT3D9 pD3D = pDirect3DCreate9(D3D_SDK_VERSION);
    3 - get IDirect3DDevice9 by create and destroy device in OTHER window, not WOW
    Code:
    	LPDIRECT3D9 pD3D = pDirect3DCreate9(D3D_SDK_VERSION);
    	D3DDISPLAYMODE d3ddm;
    	HRESULT hRes = pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm );
    	D3DPRESENT_PARAMETERS d3dpp; 
        ZeroMemory( &d3dpp, sizeof(d3dpp));
        d3dpp.Windowed = true;
        d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
        d3dpp.BackBufferFormat = d3ddm.Format;
    
    	IDirect3DDevice9 * ppReturnedDeviceInterface;	// interface IDirect3DDevice9 (pointer to array of pointers)
    
    	HWND hWnd=FindWindowA(NULL, "Your window");
    
    	hRes = pD3D->CreateDevice( 
    		D3DADAPTER_DEFAULT,
    		D3DDEVTYPE_HAL,	// the device we suppose any app would be using.
    		hWnd,
    		D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_DISABLE_DRIVER_MANAGEMENT,
    		&d3dpp, &ppReturnedDeviceInterface);
    4 - you got it
    Code:
    unsigned long* pInterface = (unsigned long*)*((unsigned long*)ppReturnedDeviceInterface);
    is array of poiters to methods. For example pInterface[17] -- IDirect3DDevice9::Present
    pInterface[16] -- IDirect3DDevice9::Reset
    open d3d9.h and count any method offset for any interface. It's constant in VMT

    Pointer to VMT may be different in different proccess due to d3d9 dynamic loading, but offset in VMT already same.

    Sorry for my English :confused:

  4. #4
    revertlife's Avatar Private
    Reputation
    11
    Join Date
    Jun 2010
    Posts
    11
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for both of your posts.

    russmice, это кажотсо лехко но не в C# :P (It may seem easy but it's not in C#). Any DirectX implementation in C# is a wrapper on the C++ object so it doesn't have the same VMT (if any at all).

    I'm going to try creating the device and getting the COM pointer from SlimDX. Hopefully it works.

    Do you have to actually create the D3D device inside of a window? You can't just set the window handle to null and the buffer size to 0x0?

  5. #5
    russmice's Avatar Private
    Reputation
    6
    Join Date
    Jun 2010
    Posts
    4
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Device pointer in SlimDX and WOW is different. Only way to get real WOW d3d device pointer - hook any regular d3d function in WOW and get real WOW pDevice at call. For examle hook Present. Its called for each frame. Or find pDevice static in WOW memory.
    If you need hook function only, not real pDevice, you need only memory offset in d3d9 VMT and difference between d3d9 memory base in WOW and ANY another process.

    d3d COM don't like null and zero sized objects. 100% you get crash at the application ends and com server trying free allocated resource.

  6. #6
    MaiN's Avatar Elite User
    Reputation
    335
    Join Date
    Sep 2006
    Posts
    1,047
    Thanks G/R
    0/10
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    SlimDX stores the native IDirect3DDevice9 interface in the Device class. I don't know if it's public, but if it isn't you can just get it with Reflection. MDX and XNA also store it. MDX and SlimDX can also create a device from a native device, very useful if you want to render inside WoW.

    Originally Posted by russmice View Post
    Device pointer in SlimDX and WOW is different. Only way to get real WOW d3d device pointer - hook any regular d3d function in WOW and get real WOW pDevice at call. For examle hook Present. Its called for each frame. Or find pDevice static in WOW memory.
    If you need hook function only, not real pDevice, you need only memory offset in d3d9 VMT and difference between d3d9 memory base in WOW and ANY another process.

    d3d COM don't like null and zero sized objects. 100% you get crash at the application ends and com server trying free allocated resource.
    Obviously they aren't the same as SlimDX creates a new one. You can create a new one and then hook some of the virtual functions, for instance EndScene. Once it's hooked you can obtain the actual device pointer from calls to the function. Many times you wont need the device pointer, but this is a very patchproof way to do it. This way you can hook EndScene in any patch as well.
    Last edited by MaiN; 07-07-2010 at 08:36 AM. Reason: typo
    [16:15:41] Cypher: caus the CPU is a dick
    [16:16:07] kynox: CPU is mad
    [16:16:15] Cypher: CPU is all like
    [16:16:16] Cypher: whatever, i do what i want

  7. #7
    russmice's Avatar Private
    Reputation
    6
    Join Date
    Jun 2010
    Posts
    4
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If you need real device pointer you don't need SlimDX. Real pDevice obtain only in process address space by hook or as static data in memory. If you try render inside WOW with unknown real pDevice for WOW, you take bullshit in unknown place. pDevice is lhuge set of d3d descriptors for rendering, including all scene rendering attributes. This data is placed only in creating proccess address space, and not present in any other places, including render device.

    For render inside WOW scene you need stay in WOW address space and know real wow d3d device pointer.

    You always need real d3d device pointer, if system have >1 d3d caller, or system have >1 d3d reader, or it's Vista with Aero is on. All client calls to d3d COM interfaces including pDevice as render surface descriptor.

  8. #8
    MaiN's Avatar Elite User
    Reputation
    335
    Join Date
    Sep 2006
    Posts
    1,047
    Thanks G/R
    0/10
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by russmice View Post
    If you need real device pointer you don't need SlimDX. Real pDevice obtain only in process address space by hook or as static data in memory. If you try render inside WOW with unknown real pDevice for WOW, you take bullshit in unknown place. pDevice is lhuge set of d3d descriptors for rendering, including all scene rendering attributes. This data is placed only in creating proccess address space, and not present in any other places, including render device.

    For render inside WOW scene you need stay in WOW address space and know real wow d3d device pointer.

    You always need real d3d device pointer, if system have >1 d3d caller, or system have >1 d3d reader, or it's Vista with Aero is on. All client calls to d3d COM interfaces including pDevice as render surface descriptor.
    He's obviously in-process. And if he isn't, then he needs to read the rules.
    [16:15:41] Cypher: caus the CPU is a dick
    [16:16:07] kynox: CPU is mad
    [16:16:15] Cypher: CPU is all like
    [16:16:16] Cypher: whatever, i do what i want

  9. #9
    russmice's Avatar Private
    Reputation
    6
    Join Date
    Jun 2010
    Posts
    4
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If he in process address space with .NET4.0 CLR and JIT and 100500 executing memory pages it's huge LOL for any defence. For inside WOW-scene rendering need only about 2-3 kbyte code and shared memory segment. 1 hook for non-critical d3d function and 1 critical section or mutex and small render data transfer routine.

  10. #10
    MaiN's Avatar Elite User
    Reputation
    335
    Join Date
    Sep 2006
    Posts
    1,047
    Thanks G/R
    0/10
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by russmice View Post
    If he in process address space with .NET4.0 CLR and JIT and 100500 executing memory pages it's huge LOL for any defence. For inside WOW-scene rendering need only about 2-3 kbyte code and shared memory segment. 1 hook for non-critical d3d function and 1 critical section or mutex and small render data transfer routine.
    What are you talking about? There is NOTHING wrong with having a whole library injected.
    [16:15:41] Cypher: caus the CPU is a dick
    [16:16:07] kynox: CPU is mad
    [16:16:15] Cypher: CPU is all like
    [16:16:16] Cypher: whatever, i do what i want

  11. #11
    revertlife's Avatar Private
    Reputation
    11
    Join Date
    Jun 2010
    Posts
    11
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by russmice View Post
    If you need real device pointer you don't need SlimDX. Real pDevice obtain only in process address space by hook or as static data in memory. If you try render inside WOW with unknown real pDevice for WOW, you take bullshit in unknown place. pDevice is lhuge set of d3d descriptors for rendering, including all scene rendering attributes. This data is placed only in creating proccess address space, and not present in any other places, including render device.

    For render inside WOW scene you need stay in WOW address space and know real wow d3d device pointer.

    You always need real d3d device pointer, if system have >1 d3d caller, or system have >1 d3d reader, or it's Vista with Aero is on. All client calls to d3d COM interfaces including pDevice as render surface descriptor.
    The first method of every DirectX method is a pointer to the pDevice calling it. On the very first EndScene call I will be able to grab the pointer to the real D3D object and do whatever I want to it.

    MaiN, SlimDX does have a property called "COMPointer" that is supposed to point to the internal object. Hopefully it's the proper D3device object and has the VMT.

  12. #12
    revertlife's Avatar Private
    Reputation
    11
    Join Date
    Jun 2010
    Posts
    11
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Alright it worked. Look at my tutorial on how to inject and hook EndScene() by using SlimDX to create a D3D object.

    http://www.mmowned.com/forums/world-...ne-hooker.html

  13. #13
    Apoc's Avatar Angry Penguin
    Reputation
    1387
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/12
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The VMT is the 42nd vfunc. That's all you really need to know. There's no real reason to use SlimDX unless you plan on actually rendering in the game.

  14. #14
    Apoc's Avatar Angry Penguin
    Reputation
    1387
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/12
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Bah, stupid edit button fails.

    Here's the code I released a while ago, to grab the current device's EndScene pointer. It assumes you're in process:

    Code:
    using System;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    //using Microsoft.DirectX.Direct3D;
    
    namespace Onyx.WoW.Native
    {
        // ReSharper disable InconsistentNaming
        internal static class DirectX
        {
            #region Actual Useful Funcs
    
            //public static unsafe IntPtr GetDevicePointerManaged(uint funcIndex)
            //{
            //    var window = new Form();
            //    var device = new Device(0, (DeviceType) 1, window,
            //                            CreateFlags.SoftwareVertexProcessing,
            //                            new PresentParameters
            //                                {
            //                                    Windowed = true,
            //                                    SwapEffect = SwapEffect.Discard,
            //                                    BackBufferFormat = Format.Unknown,
            //                                });
            //    // This func requires an unsafe context due to the COM pointer
            //    var devicePtr = (IntPtr) device.UnmanagedComPointer;
    
            //    IntPtr ret = funcIndex < 0 ? devicePtr : Reader.GetVFunc(devicePtr, funcIndex);
    
            //    device.Dispose();
            //    window.Dispose();
            //    return ret;
            //}
    
            /// <summary>
            /// Returns a function pointer for the current DirectX device.
            /// </summary>
            /// <param name="funcIndex">The index to the function you want to retrieve.</param>
            /// <returns></returns>
            public static IntPtr GetDevicePointer(uint funcIndex)
            {
                // Create a new 'window'
                var window = new Form();
    
                // Grabbed from d3d9.h
                const uint D3D_SDK_VERSION = 32;
    
                // Create the IDirect3D* object.
                IntPtr direct3D = Direct3DCreate9(D3D_SDK_VERSION);
    
                // Make sure it's valid. (Should always be valid....)
                if (direct3D == IntPtr.Zero)
                    throw new Exception("Failed to create D3D.");
    
                // Setup some present params...
                var d3dpp = new D3DPRESENT_PARAMETERS {Windowed = true, SwapEffect = 1, BackBufferFormat = 0};
    
                IntPtr device;
    
                // CreateDevice is a vfunc of IDirect3D. Hence; why this entire thing only works in process! (Unless you
                // know of some way to hook funcs from out of process...)
                // It's the 16th vfunc btw.
                // Check d3d9.h
                var createDevice = Utilities.RegisterDelegate<IDirect3D9_CreateDevice>(Reader.GetVFunc(direct3D, 16));
    
                // Pass it some vals. You can check d3d9.h for what these actually are....
                if (createDevice(direct3D, 0, 1, window.Handle, 0x20, ref d3dpp, out device) < 0)
                    throw new Exception("Failed to create device.");
    
                // If we passed anything lower than 0, just return the device pointer. Otherwise,
                // grab the vfunc pointer. (Useful for EndScene/Reset/etc)
                IntPtr ret = funcIndex < 0 ? device : Reader.GetVFunc(device, funcIndex);
    
                // We now have a valid pointer to the device. We can release the shit we don't need now. :)
                // Again, the Release() funcs are virtual. Part of the IUnknown interface for COM.
                // They're the 3rd vfunc. (2nd index)
                var deviceRelease = Utilities.RegisterDelegate<D3DVirtVoid>(Reader.GetVFunc(device, 2));
                var d3dRelease = Utilities.RegisterDelegate<D3DVirtVoid>(Reader.GetVFunc(direct3D, 2));
    
                // And finally, release the device and d3d object.
                deviceRelease(device);
                d3dRelease(direct3D);
    
                // Destroy the window...
                window.Dispose();
                // Tell the CLR to finalize the object asap.
    
                // And we can FINALLY return the pointer to the device or func.
                return ret;
            }
    
            public static IntPtr GetEndScenePointer()
            {
                return GetDevicePointer(42);
            }
    
            //public static IntPtr GetEndScenePointerManaged()
            //{
            //    return GetDevicePointerManaged(42);
            //}
    
            public static IntPtr GetResetPointer()
            {
                return GetDevicePointer(16);
            }
    
            //public static IntPtr GetResetPointerManaged()
            //{
            //    return GetDevicePointerManaged(16);
            //}
    
            #endregion
    
            #region DllImports
    
            [DllImport("d3d9.dll")]
            private static extern IntPtr Direct3DCreate9(uint sdkVersion);
    
            #region Nested type: D3DVirtVoid
    
            [UnmanagedFunctionPointer(CallingConvention.StdCall)]
            private delegate void D3DVirtVoid(IntPtr instance);
    
            #endregion
    
            #region Nested type: IDirect3D9_CreateDevice
    
            [UnmanagedFunctionPointer(CallingConvention.StdCall)]
            private delegate int IDirect3D9_CreateDevice(IntPtr instance, uint adapter, uint deviceType,
                                                         IntPtr focusWindow,
                                                         uint behaviorFlags,
                                                         [In] ref D3DPRESENT_PARAMETERS presentationParameters,
                                                         [Out] out IntPtr returnedDeviceInterface);
    
            #endregion
    
            #endregion
    
            #region Structs n Shit
    
            [StructLayout(LayoutKind.Sequential)]
            private struct D3DPRESENT_PARAMETERS
            {
                public readonly uint BackBufferWidth;
                public readonly uint BackBufferHeight;
                public uint BackBufferFormat;
                public readonly uint BackBufferCount;
                public readonly uint MultiSampleType;
                public readonly uint MultiSampleQuality;
                public uint SwapEffect;
                public readonly IntPtr hDeviceWindow;
                [MarshalAs(UnmanagedType.Bool)] public bool Windowed;
                [MarshalAs(UnmanagedType.Bool)] public readonly bool EnableAutoDepthStencil;
                public readonly uint AutoDepthStencilFormat;
                public readonly uint Flags;
                public readonly uint FullScreen_RefreshRateInHz;
                public readonly uint PresentationInterval;
            }
    
            #endregion
        }
    }

  15. #15
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1356
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/4
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by russmice View Post
    If he in process address space with .NET4.0 CLR and JIT and 100500 executing memory pages it's huge LOL for any defence. For inside WOW-scene rendering need only about 2-3 kbyte code and shared memory segment. 1 hook for non-critical d3d function and 1 critical section or mutex and small render data transfer routine.
    What the ****? Were you dropped on your head as a child?

Similar Threads

  1. [Database] where can i find monster's exp table from the db?
    By jpxtreme in forum WoW EMU Questions & Requests
    Replies: 2
    Last Post: 07-18-2010, 10:45 AM
  2. Help me find the model :D
    By ven in forum WoW ME Questions and Requests
    Replies: 0
    Last Post: 04-10-2007, 03:16 AM
  3. Cannot find the files to edit :(
    By Rekro in forum WoW ME Questions and Requests
    Replies: 6
    Last Post: 01-01-2007, 06:07 PM
  4. Finding the .blp-files to Striker's Set
    By Violence in forum World of Warcraft General
    Replies: 0
    Last Post: 10-04-2006, 06:02 PM
  5. Find The Flag Carrier In WSG
    By impulse102 in forum World of Warcraft Exploits
    Replies: 20
    Last Post: 07-29-2006, 12:48 PM
All times are GMT -5. The time now is 09:42 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search