[C#][Patch Independant] Getting the IDirect3DDevice9 Pointer menu

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 15 of 19
  1. #1
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [C#][Patch Independant] Getting the IDirect3DDevice9 Pointer

    Alright, so we've switched some stuff around in Onyx lately, and I needed a way to 'dynamically' grab the DX device pointer, irregardless of the current patch.

    We've been using the same approach in native code, but the idea is to avoid the native code!

    There are 2 ways to get the DX device pointer (and therefor; the other func pointers [EndScene, Reset, etc])

    1) Keep a list of updated offsets that change each patch. This can be quite annoying, and is usually just a pain in the ass.
    2) Create a device, get the pointer, and be done with it.

    Obviously #2 is what we'll be doing!

    Before I go any further, this was written using some of the API from WhiteMagic, and requires that you be in process if you want to make use of the EndScene function. (This approach will still work if you just want the pointer to the device to set flags and whatnot.)

    This method of grabbing the pointer is definitely not 'fool proof', however it works fine for WoW from what I can tell. (Only tested on Win7 x86/x64) As Cypher will probably say, this is a 'bad' way to do it, however it is really just a POC code. I'm not all that worried about possible race conditions and the like, as the code is run in a separate thread anyway. (And DX is written well enough to avoid such race conditions)

    Anyhow! Here's the methodology;

    1) Create a window that we'll pass to DX to create our device.
    2) Create the device.
    3) Get the pointer and return it.
    4) Clean up.

    I know, it's really hard.

    Anyhow: ON TO THE CODE!

    Code:
    using System;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    using Microsoft.DirectX.Direct3D;
    
    namespace DirectXGetDevice
    {
        // 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<D3DRelease>(Reader.GetVFunc(device, 2));
                var d3dRelease = Utilities.RegisterDelegate<D3DRelease>(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: D3DRelease
    
            [UnmanagedFunctionPointer(CallingConvention.StdCall)]
            private delegate void D3DRelease(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
        }
    }
    Notice the comments! READ THEM!

    Credits:
    kynox: Original DX hooking code.
    malu: Making me write this code because he's an XP-fag.
    Cypher: you can bitch later about silly issues.

    If you use this code, I only ask that you give credit where credit is due.
    Last edited by Apoc; 02-22-2010 at 01:33 PM.

    [C#][Patch Independant] Getting the IDirect3DDevice9 Pointer
  2. Thanks Frosttall (1 members gave Thanks to Apoc for this useful post)
  3. #2
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1358
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Obligatory:
    This is a 'bad' way to do it.

  4. #3
    adaephon's Avatar Active Member
    Reputation
    76
    Join Date
    May 2009
    Posts
    167
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    irregardless = not regardless = regard...ing? :P

  5. #4
    !@^^@!'s Avatar Active Member
    Reputation
    23
    Join Date
    Feb 2007
    Posts
    155
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Nice Apoc, but a few suggestions:
    Replace "Reader" and "Utilities" with Magic.Instance as you enabled easy singleton "mode" with whitemagic
    Tell me if you released a new version of whitemagic because the "Reader.GetVFunc" is "GetObjectVtableFunction" in the version I have :P

    Anyroad thanks a bunch works like a charm \o/

  6. #5
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If you read the post, I said 'some' of the API is shared. We use a different setup in our actual implementation.

    If you can't figure out what needs to be changed, you shouldn't be touching it. Simple enough right?

  7. #6
    zzgw's Avatar Member
    Reputation
    6
    Join Date
    Mar 2008
    Posts
    31
    Thanks G/R
    0/2
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I probably am missing something here but what exactly is wrong with hooking CreateDevice* and going from there?

  8. #7
    Robske's Avatar Contributor
    Reputation
    305
    Join Date
    May 2007
    Posts
    1,062
    Thanks G/R
    3/4
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Wouldn't

    Code:
    System.Windows.Forms.Form form = new System.Windows.Forms.Form ();
    
    if (createDevice(direct3D, 0, 1, form.Handle, 0x20, ref d3dpp, out device) < 0)
             throw new Exception("Failed to create device.");
    
    (...)
    
    form.Dispose();
    Suffice?

    I took a quick look at Managed DirectX's Device constructor:

    Code:
    public Device(int adapter, DeviceType deviceType, Control renderWindow, CreateFlags behaviorFlags, params PresentParameters[] presentationParameters);
    
    public Device(int adapter, DeviceType deviceType, IntPtr renderWindowHandle, CreateFlags behaviorFlags, params PresentParameters[] presentationParameters);
    So wouldn't you be able to create a new managed device using a trivial form/control implementation and snatch the pointer from it?

    Originally Posted by zzgw View Post
    I probably am missing something here but what exactly is wrong with hooking CreateDevice* and going from there?
    What if your library gets injected after the device was created?
    "Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." - Martin Golding
    "I cried a little earlier when I had to poop" - Sku

  9. #8
    ramey's Avatar Member
    Reputation
    45
    Join Date
    Jan 2008
    Posts
    320
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Cypher View Post
    Obligatory:
    This is a 'bad' way to do it.
    +1.

    filla

  10. #9
    !@^^@!'s Avatar Active Member
    Reputation
    23
    Join Date
    Feb 2007
    Posts
    155
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Apoc View Post
    If you read the post, I said 'some' of the API is shared. We use a different setup in our actual implementation.

    If you can't figure out what needs to be changed, you shouldn't be touching it. Simple enough right?
    Yeh sorry didn't notice that part, anyway I assume that the last sentece was directed at the script kiddies else I can throw the shit you threw after me right back in your head and tell you to read my post again and comprehend it
    Last edited by !@^^@!; 02-22-2010 at 11:00 AM.

  11. #10
    zzgw's Avatar Member
    Reputation
    6
    Join Date
    Mar 2008
    Posts
    31
    Thanks G/R
    0/2
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Robske View Post
    What if your library gets injected after the device was created?
    Ah okay, that's a good point, although injection on startup is required by a bunch of things and pretty much the way to go anyway, I'd think, so not really an inconvenience compared to all the hoops you have to jump through to grab a valid pointer afterwards.

  12. #11
    wanyancan's Avatar Member
    Reputation
    1
    Join Date
    May 2009
    Posts
    40
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Probably, to some others use static address is easier..
    Here's how to find JuJu's pointers.
    Credits: Apoc, JuJu
    Code:
    enum Direct3D9Ptrs
    {
        pDevicePtr_1 = 0x00C776B8,              // 3.3.2
        pDevicePtr_2 = 0x397C,                  // 3.3.2
        oEndScene = 0xA8,                       // 3.3.2
    };
    Code:
    /*
    to find pDevicePtr_1 (which has more than 2500 xrefs)
    search:
    .rdata:00A166C0 43 6F 6E 73 6F 6C 65 44+aConsoledevic_0 db 'ConsoleDeviceInitialize(): output device does not have dual TMUs!'
    go above to:
    .text:006FE1E7 E8 E4 80 F1 FF                          call    apoc_wyc_BeforeInitWnd   <<<< In this call, LD3device will be created, but inside, this->[0x28h] will be called, no worry, at least is found.
    .text:006FE1EC 83 C4 10                                add     esp, 10h
    .text:006FE1EF 85 C0                                   test    eax, eax
    .text:006FE1F1 A3 B8 52 CC 00                          mov     dword_CC52B8, eax
    .text:006FE1F6 0F 84 79 FF FF FF                       jz      loc_6FE175
    .text:006FE1FC
    .text:006FE1FC                         loc_6FE1FC:                             ; CODE XREF: apoc_ConsoleDeviceInitialize+38Fj
    .text:006FE1FC                                                                 ; apoc_ConsoleDeviceInitialize+4B2j
    .text:006FE1FC B9 16 00 00 00                          mov     ecx, 16h
    .text:006FE201 8D 75 94                                lea     esi, [ebp+var_6C]
    .text:006FE204 BF D8 52 CC 00                          mov     edi, offset unk_CC52D8
    .text:006FE209 F3 A5                                   rep movsd
    .text:006FE20B B9 16 00 00 00                          mov     ecx, 16h
    .text:006FE210 8D 75 94                                lea     esi, [ebp+var_6C]
    .text:006FE213 BF 00 54 CC 00                          mov     edi, offset unk_CC5400
    .text:006FE218 F3 A5                                   rep movsd
    .text:006FE21A 8D 75 94                                lea     esi, [ebp+var_6C]
    .text:006FE21D E8 8E E9 FF FF                          call    sub_6FCBB0
    .text:006FE222 8B 0D B8 76 C7 00                       mov     ecx, dword ptr unk_C776B8    <<<< this is pDevicePtr_1 !
    .text:006FE228 E8 D3 9B F1 FF                          call    apoc_CGxDevice__Caps
    .text:006FE22D 83 38 02                                cmp     dword ptr [eax], 2
    .text:006FE230 0F 83 3C 01 00 00                       jnb     loc_6FE372
    .text:006FE236 8B 15 B8 52 CC 00                       mov     edx, dword_CC52B8
    .text:006FE23C 52                                      push    edx             ; char
    .text:006FE23D E8 7E 99 F1 FF                          call    sub_617BC0
    .text:006FE242 68 C0 66 A1 00                          push    offset aConsoledevic_0 ; "ConsoleDeviceInitialize(): output devic"...
    
    to find pDevicePtr_2:
    search signature:  1B DB   83 E3 30   83 C3 22   53   52   6A 01   6A 00
    CPU Disasm
    Address   Hex dump          Command                                  Comments  (3.3.2 zhTW dump)
    006243F4  |.  8B86 78390000 MOV EAX,DWORD PTR DS:[ESI+3978]
    006243FA  |.  8B08          MOV ECX,DWORD PTR DS:[EAX]
    006243FC  |.  F6DB          NEG BL
    006243FE  |.  8DBE 7C390000 LEA EDI,[ESI+397C]				ppReturnedDeviceInterface  <<<< THE pDevicePtr_2
    00624404  |.  57            PUSH EDI
    00624405  |.  8D55 C4       LEA EDX,[LOCAL.16]
    00624408  |.  52            PUSH EDX					   pPresentationParameters
    00624409  |.  8B96 68390000 MOV EDX,DWORD PTR DS:[ESI+3968]
    0062440F  |.  1BDB          SBB EBX,EBX                          <<<<<< this is the bytes as signature to  search for
    00624411  |.  83E3 30       AND EBX,00000030
    00624414  |.  83C3 22       ADD EBX,22		          = 0x52
    00624417  |.  53            PUSH EBX			  D3DCREATE  = D3DCREATE_HARDWARE_VERTEXPROCESSING(0x40)+D3DCREATE_PUREDEVICE(0x10) +D3DCREATE_FPU_PRESERVE(0x02)
    00624418  |.  52            PUSH EDX			hFocusWindow
    00624419  |.  6A 01         PUSH 1				DeviceType   typedef enum D3DDEVTYPE  {    D3DDEVTYPE_HAL = 1, D3DDEVTYPE_NULLREF = 4,D3DDEVTYPE_REF = 2, D3DDEVTYPE_SW = 3,D3DDEVTYPE_FORCE_DWORD = 0xffffffff,} D3DDEVTYPE, *LPD3DDEVTYPE;
    0062441B  |.  6A 00         PUSH 0				Adapter  : 0 for primary monitor
    0062441D  |.  50            PUSH EAX          << IDirect3D9
    0062441E  |.  8B41 40       MOV EAX,DWORD PTR DS:[ECX+40]          <<<< this is    IDirect3D9-> STDMETHOD(CreateDevice)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface) PURE;
    00624421  |.  FFD0          CALL EAX
    
    to find oEndScene:
    Check d3d9.h  IDirect3DDevice9::EndScene
    
    to find D3D_SDK_VERSION being used in case blizz use a new SDK (almost impossible but anyway):
    search aDirect3dcreate ; "Direct3DCreate9", then compare with <d3d9.h>
    .text:00635871 68 48 BD A0 00                          push    offset aD3d9_dll ; "d3d9.dll"
    .text:00635876 C7 06 00 00 00 00                       mov     dword ptr [esi], 0
    .text:0063587C FF 15 64 52 9C 00                       call    ds:LoadLibraryA
    .text:00635882 85 C0                                   test    eax, eax
    .text:00635884 89 07                                   mov     [edi], eax
    .text:00635886 75 07                                   jnz     short loc_63588F
    .text:00635888 68 90 CB A0 00                          push    offset aCgxdeviced3d9e ; "CGxDeviceD3d9Ex::ILoadD3dLib(): unable "...
    .text:0063588D EB 26                                   jmp     short loc_6358B5
    .text:0063588F                         ; ---------------------------------------------------------------------------
    .text:0063588F
    .text:0063588F                         loc_63588F:                             ; CODE XREF: sub_635860+26j
    .text:0063588F 68 00 BD A0 00                          push    offset aDirect3dcreate ; "Direct3DCreate9"
    .text:00635894 50                                      push    eax
    .text:00635895 FF 15 8C A3 AD 00                       call    off_ADA38C
    .text:0063589B 85 C0                                   test    eax, eax
    .text:0063589D 75 07                                   jnz     short loc_6358A6
    .text:0063589F 68 54 CB A0 00                          push    offset aCgxdeviced3d_4 ; "CGxDeviceD3d9Ex::ILoadD3dLib(): unable "...
    .text:006358A4 EB 0F                                   jmp     short loc_6358B5
    .text:006358A6                         ; ---------------------------------------------------------------------------
    .text:006358A6
    .text:006358A6                         loc_6358A6:                             ; CODE XREF: sub_635860+3Dj
    .text:006358A6 6A 20                                   push    20h                  <<<<< this is the D3D_SDK_VERSION
    .text:006358A8 FF D0                                   call    eax
    
    */
    enum Direct3D9Ptrs
    {
        pDevicePtr_1 = 0x00C776B8,              // 3.3.2
        pDevicePtr_2 = 0x397C,                  // 3.3.2
        oEndScene = 0xA8,                       // 3.3.2
    };
    When exe starts, it follows the procedure as below:
    0. "apoc_ConsoleDeviceInitialize()" at sub6FDDE0 (by searching "do hardware detection")
    1. load 'd3d9.dll' on the fly in ".text:00623CD0 apoc_CGxDeviceD3d__ILoadD3dLib proc near"
    2. call Direct3DCreate9(D3D_SDK_VERSION)
    3. load 'd3d9.dll' again in ".text:00623CD0 apoc_CGxDeviceD3d__ILoadD3dLib proc near"
    4. call Direct3DCreate9(D3D_SDK_VERSION)
    5. Window created, start initializing.
    5. CreateDevice() called by IDirect3D9-> VTable[0x40]
    which is inside sub_624310
    which is inside "CGxDeviceD3d:eviceSetFormat(): unable to set format!"
    which is called by CGxDeviceD3d->VTable[0x34]
    which is inside sub_617cf0
    which is inside sub_6254a0
    which is called by someClass->VTable[0x28]
    which is called by sub_6162d0
    which is called by "apoc_ConsoleDeviceInitialize()"
    back to the step 0. "apoc_ConsoleDeviceInitialize()" again.

    So once consoleDeviceInitialize() is found and hooked, your dll can create D3Device before the real one starts.

    ps: "->" is really the source of all evilness, as the symbol represents, it only allows tracking in one direction.

  13. #12
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    @Robske; read the first post again. I said there were most likely simpler ways to do it. I decided to wrap it in native* code instead of dealing with possible headaches that come from .NETs class/window wrapping.

    @Others; this will work whether you're injecting before the game has started (eg; from a suspended process state), or if you're injecting while it's running. Either or, makes no difference to the code.

    @zzgw; if you're lib requires that it is injected before WoW actually starts; you need to rethink your code.

    @!@^^@!; it wasn't directed towards you. (Well, it was, but not as an insult.)

    To everyone else; this code is meant to be agnostic to WoW. It doesn't require you to know, or update, and addresses during a patch. It's really that simple.

    Edit; I edited the first post with new code. I tested both methods, and both work. I'm leaving both the Managed DirectX way to do it (GetDevicePointerManaged) and the 'native' way, if you choose to not include the extra libraries.

    The code is much smaller and cleaner now. (Thanks Robske)
    Last edited by Apoc; 02-22-2010 at 01:26 PM.

  14. #13
    lanman92's Avatar Active Member
    Reputation
    50
    Join Date
    Mar 2007
    Posts
    1,033
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Not to hi-jack the thread, but can I ask why you always use 'var' instead of an explicit type?

  15. #14
    wanyancan's Avatar Member
    Reputation
    1
    Join Date
    May 2009
    Posts
    40
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    @apoc: During the test, I found that there's a biggest problem. Every time you call CreateDevice, it creates a new instance. Hence the IDIRECT3DDEVICE9* you get is NOT the devicePtr that the game windows uses. The new devicePtr you created is just to draw on your dummy window. (Direct3DCreate9 returned pD3D is the same however)
    Code:
    [12:48:50]: Direct3DCreate9 OK, pD3D: 0x148C6F60 [.\puredll.cpp] @ 180   <<<< same pD3D
    [12:48:50]: pD3D->CreateDevice with hWnd : 00040502 [.\puredll.cpp] @ 188
    [12:48:50]: pD3D->CreateDevice OK, pd3dDevice: 0x15630140 *pd3dDevice= 0x15632EDC [.\puredll.cpp] @ 195   <<< different every time
    [12:48:50]: pd3dDevice -> Vtable[42] = 6AEECE09 [.\puredll.cpp] @ 203   <<<< real EndScene address in d3d9.dll
    [12:48:50]: Direct3DCreate9 OK, pD3D: 0x148C6F60 [.\puredll.cpp] @ 180  <<< same as above
    [12:48:50]: pD3D->CreateDevice with hWnd : 00050502 [.\puredll.cpp] @ 188
    [12:48:50]: pD3D->CreateDevice OK, pd3dDevice: 0x157107E0 *pd3dDevice= 0x1571357C [.\puredll.cpp] @ 195    <<< different every time
    [12:48:50]: pd3dDevice -> Vtable[16] = 6AF28DDA [.\puredll.cpp] @ 203  <<<< real Reset address in d3d9.dll
    
    
    [12:48:50]: IDirect3DDevice9* is 0x3498A20 [.\puredll.cpp] @ 303    <<< obtained from  *(*0x00C776B8 + 0x397C)
    [12:48:50]: VTable starts at 349B7BC [.\puredll.cpp] @ 307
    [12:48:50]: EndScene (A8) in VTable reads 6AEECE09 [.\puredll.cpp] @ 309 <<< the same EndScene of course in d3d9.dll
    [12:48:50]: &Vtable[orig_end_scene]= 0x55162980 [.\puredll.cpp] @ 311  <<< the entry to EndScene in vtable of the real game's drawing device, which is where new endscene address is written to.
    [12:48:50]: new EndScene directed to 0x17461330 [.\puredll.cpp] @ 314
    [12:48:50]: end scene is successfully hooked! [.\puredll.cpp] @ 124
    Actually, in order to get the real devicePtr, remembering that EndScene is called by pd3dDevice->EndScene, we can get the devicePtr by reading the 'this' ptr in the newly hooked Endscene (this = [EBP+0x8] the first argument to EndScene). But the problem is without knowing devicePtr, how could EndScene be hooked ? :P Therefore static ptr is still being used.

  16. #15
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1358
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by wanyancan View Post
    @apoc: During the test, I found that there's a biggest problem. Every time you call CreateDevice, it creates a new instance. Hence the IDIRECT3DDEVICE9* you get is NOT the devicePtr that the game windows uses. The new devicePtr you created is just to draw on your dummy window. (Direct3DCreate9 returned pD3D is the same however)
    Code:
    [12:48:50]: Direct3DCreate9 OK, pD3D: 0x148C6F60 [.\puredll.cpp] @ 180   <<<< same pD3D
    [12:48:50]: pD3D->CreateDevice with hWnd : 00040502 [.\puredll.cpp] @ 188
    [12:48:50]: pD3D->CreateDevice OK, pd3dDevice: 0x15630140 *pd3dDevice= 0x15632EDC [.\puredll.cpp] @ 195   <<< different every time
    [12:48:50]: pd3dDevice -> Vtable[42] = 6AEECE09 [.\puredll.cpp] @ 203   <<<< real EndScene address in d3d9.dll
    [12:48:50]: Direct3DCreate9 OK, pD3D: 0x148C6F60 [.\puredll.cpp] @ 180  <<< same as above
    [12:48:50]: pD3D->CreateDevice with hWnd : 00050502 [.\puredll.cpp] @ 188
    [12:48:50]: pD3D->CreateDevice OK, pd3dDevice: 0x157107E0 *pd3dDevice= 0x1571357C [.\puredll.cpp] @ 195    <<< different every time
    [12:48:50]: pd3dDevice -> Vtable[16] = 6AF28DDA [.\puredll.cpp] @ 203  <<<< real Reset address in d3d9.dll
    
    
    [12:48:50]: IDirect3DDevice9* is 0x3498A20 [.\puredll.cpp] @ 303    <<< obtained from  *(*0x00C776B8 + 0x397C)
    [12:48:50]: VTable starts at 349B7BC [.\puredll.cpp] @ 307
    [12:48:50]: EndScene (A8) in VTable reads 6AEECE09 [.\puredll.cpp] @ 309 <<< the same EndScene of course in d3d9.dll
    [12:48:50]: &Vtable[orig_end_scene]= 0x55162980 [.\puredll.cpp] @ 311  <<< the entry to EndScene in vtable of the real game's drawing device, which is where new endscene address is written to.
    [12:48:50]: new EndScene directed to 0x17461330 [.\puredll.cpp] @ 314
    [12:48:50]: end scene is successfully hooked! [.\puredll.cpp] @ 124
    Actually, in order to get the real devicePtr, remembering that EndScene is called by pd3dDevice->EndScene, we can get the devicePtr by reading the 'this' ptr in the newly hooked Endscene (this = [EBP+0x8] the first argument to EndScene). But the problem is without knowing devicePtr, how could EndScene be hooked ? :P Therefore static ptr is still being used.
    Just because a new device is returned doesn't mean you can't hook EndScene.

    Just grab the address of the function and hook it. Then destroy your device, and when EndScene is called then the first parameter will be the game's device (as you already stated).

Page 1 of 2 12 LastLast

Similar Threads

  1. [Guide] Patch 5.2 - How to get the new Mount from Raremobs
    By mrnice in forum World of Warcraft Guides
    Replies: 9
    Last Post: 05-17-2013, 04:24 PM
  2. [Patch] Having problem patch cataclysm to get the map file
    By leonne in forum WoW EMU Questions & Requests
    Replies: 0
    Last Post: 06-18-2010, 11:42 PM
  3. Where to get the patch to put Prog. Isle back?
    By sonnyd666 in forum World of Warcraft Emulator Servers
    Replies: 18
    Last Post: 06-22-2008, 01:19 AM
  4. A New way to get the s_curMgr pointer
    By kynox in forum WoW Memory Editing
    Replies: 5
    Last Post: 04-01-2008, 09:39 AM
  5. Your First Mount - Where to Get the Cash while Grinding
    By Matt in forum World of Warcraft Guides
    Replies: 2
    Last Post: 05-12-2006, 06:58 PM
All times are GMT -5. The time now is 05:38 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search