Results 1 to 7 of 7
  1. #1
    Hell_Demon's Avatar
    Join Date
    Mar 2008
    Gender
    male
    Location
    I love causing havoc
    Posts
    3,976
    Reputation
    343
    Thanks
    4,320
    My Mood
    Cheeky

    [Olly]Getting the D3D9 device pointer in MW2

    Since melodia had a question about d3d hooking I figured i'd write this up real quick(copied over from her forums):

    ---
    A quick tut on getting the D3D device pointer for MW2

    First load up iw4mp.exe into olly, and search for -> all intermodular calls.
    Sort them by name by clicking on the 'Destination' button above the calls.

    Start typing: Direct, you should now see two calls to Direct3DCreate9.
    Follow the first one:
    Code:
    004FC856  |. E8 05D21800    CALL <JMP.&d3d9.Direct3DCreate9>
    004FC85B  |. 8BF8           MOV EDI,EAX
    004FC85D  |. 85FF           TEST EDI,EDI
    004FC85F  |. 74 34          JE SHORT iw4mp.004FC895
    004FC861  |. 8B07           MOV EAX,DWORD PTR DS:[EDI]
    004FC863  |. 8B50 14        MOV EDX,DWORD PTR DS:[EAX+14]
    004FC866  |. 8D4C24 08      LEA ECX,DWORD PTR SS:[ESP+8]
    004FC86A  |. 51             PUSH ECX
    004FC86B  |. 6A 00          PUSH 0
    004FC86D  |. 6A 00          PUSH 0
    004FC86F  |. 57             PUSH EDI
    004FC870  |. FFD2           CALL EDX
    004FC872  |. 85C0           TEST EAX,EAX
    004FC874  |. 7C 17          JL SHORT iw4mp.004FC88D
    Aww... no absolute addies for us to use(we could still hook Direct3DCreate9 tho, but they will detect that)

    Let's try the other one:
    Code:
    0050DCAB  |. E8 B0BD1700    CALL <JMP.&d3d9.Direct3DCreate9>
    0050DCB0  |. 85C0           TEST EAX,EAX ; test against itself
    0050DCB2  |. A3 E4727306    MOV DWORD PTR DS:[67372E4],EAX ; BINGO! 0x67372E4 is where they store the device pointer!
    0050DCB7  |. 75 13          JNZ SHORT iw4mp.0050DCCC ; jump if D3DCreate9 didnt return a null pointer
    0050DCB9  |. 68 745B7800    PUSH iw4mp.00785B74                      ;  ASCII "Direct3D 9 failed to initialize
    "
    0050DCBE  |. 6A 08          PUSH 8
    0050DCC0  |. E8 0B27FFFF    CALL iw4mp.005003D0
    0x67372E4 is a pointer to the games IDirect3D9, from which they will call CreateDevice to have the actual device created.

    CreateDevice is the 16th virtual function in IDirect3D9, 0x4 is the size of a pointer, 16 = 0x10, 0x4*0x10 = 0x40, so we want to look at where IW4MP
    does something like the following:
    mov ECX, DWORD PTR DS:[67372E4];
    mov EAX, DWORD PTR DS:[ECX+40];
    call EAX;

    Now this is what I found:
    Code:
    0050DAB0   $ 83EC 10        SUB ESP,10
    0050DAB3   . 53             PUSH EBX
    0050DAB4   . 55             PUSH EBP
    0050DAB5   . 8B6C24 24      MOV EBP,DWORD PTR SS:[ESP+24]
    0050DAB9   . 56             PUSH ESI
    0050DABA   . 57             PUSH EDI
    0050DABB   . EB 03          JMP SHORT iw4mp.0050DAC0
    0050DABD     8D49 00        LEA ECX,DWORD PTR DS:[ECX]
    0050DAC0   > 68 085B7800    PUSH iw4mp.00785B08                      ;  ASCII "Creating Direct3D device...
    "
    0050DAC5   . 6A 08          PUSH 8
    0050DAC7   . E8 0429FFFF    CALL iw4mp.005003D0
    0050DACC   . 83C4 08        ADD ESP,8
    0050DACF   . 33DB           XOR EBX,EBX
    0050DAD1   . EB 0D          JMP SHORT iw4mp.0050DAE0
    0050DAD3   . 8DA424 0000000>LEA ESP,DWORD PTR SS:[ESP]
    0050DADA   . 8D9B 00000000  LEA EBX,DWORD PTR DS:[EBX]
    0050DAE0   > 8B3D EC727306  MOV EDI,DWORD PTR DS:[67372EC]
    0050DAE6   . 68 F8727306    PUSH iw4mp.067372F8
    0050DAEB   . BE F4727306    MOV ESI,iw4mp.067372F4
    0050DAF0   . E8 7BF0FFFF    CALL iw4mp.0050CB70
    0050DAF5   . 8B5424 2C      MOV EDX,DWORD PTR SS:[ESP+2C]
    0050DAF9   . 83C4 04        ADD ESP,4
    0050DAFC   . 68 E8727306    PUSH iw4mp.067372E8
    0050DB01   . 55             PUSH EBP
    0050DB02   . 52             PUSH EDX
    0050DB03   . 8B5424 30      MOV EDX,DWORD PTR SS:[ESP+30]
    0050DB07   . 52             PUSH EDX
    0050DB08   . A2 F0727306    MOV BYTE PTR DS:[67372F0],AL
    0050DB0D   . A1 E4727306    MOV EAX,DWORD PTR DS:[67372E4]
    0050DB12   . 8B08           MOV ECX,DWORD PTR DS:[EAX]
    0050DB14   . 6A 01          PUSH 1
    0050DB16   . 57             PUSH EDI
    0050DB17   . 50             PUSH EAX
    0050DB18   . 8B41 40        MOV EAX,DWORD PTR DS:[ECX+40]
    0050DB1B   . FFD0           CALL EAX
    0050DB1D   . 8BF0           MOV ESI,EAX
    0050DB1F   . 85F6           TEST ESI,ESI
    0050DB21   . 7D 28          JGE SHORT iw4mp.0050DB4B
    0050DB23   . 6A 64          PUSH 64                                  ; /Timeout = 100. ms
    0050DB25   . FF15 A4616D00  CALL DWORD PTR DS:[<&KERNEL32.Sleep>]    ; \Sleep
    0050DB2B   . 83C3 01        ADD EBX,1
    0050DB2E   . 83FB 14        CMP EBX,14
    0050DB31   .^75 AD          JNZ SHORT iw4mp.0050DAE0
    0050DB33   . 833D EC727306 >CMP DWORD PTR DS:[67372EC],0
    0050DB3A   . 74 5B          JE SHORT iw4mp.0050DB97
    0050DB3C   . C705 EC727306 >MOV DWORD PTR DS:[67372EC],0
    0050DB46   .^E9 75FFFFFF    JMP iw4mp.0050DAC0
    0050DB4B   > A1 E4727306    MOV EAX,DWORD PTR DS:[67372E4]
    0050DB50   . 8B08           MOV ECX,DWORD PTR DS:[EAX]
    0050DB52   . 8D5424 10      LEA EDX,DWORD PTR SS:[ESP+10]
    0050DB56   . 52             PUSH EDX
    0050DB57   . 8B15 EC727306  MOV EDX,DWORD PTR DS:[67372EC]
    0050DB5D   . 52             PUSH EDX
    0050DB5E   . 50             PUSH EAX
    0050DB5F   . 8B41 20        MOV EAX,DWORD PTR DS:[ECX+20]
    0050DB62   . FFD0           CALL EAX
    0050DB64   . 85C0           TEST EAX,EAX
    0050DB66   . 7C 1E          JL SHORT iw4mp.0050DB86
    0050DB68   . 8B4C24 10      MOV ECX,DWORD PTR SS:[ESP+10]
    0050DB6C   . 8B5424 14      MOV EDX,DWORD PTR SS:[ESP+14]
    0050DB70   . 890D FC727306  MOV DWORD PTR DS:[67372FC],ECX
    0050DB76   . 8915 00737306  MOV DWORD PTR DS:[6737300],EDX
    0050DB7C   . 8BC6           MOV EAX,ESI
    0050DB7E   . 5F             POP EDI
    0050DB7F   . 5E             POP ESI
    0050DB80   . 5D             POP EBP
    0050DB81   . 5B             POP EBX
    0050DB82   . 83C4 10        ADD ESP,10
    0050DB85   . C3             RETN
    0050DB86   > 8B45 00        MOV EAX,DWORD PTR SS:[EBP]
    0050DB89   . A3 FC727306    MOV DWORD PTR DS:[67372FC],EAX
    0050DB8E   . 8B4D 04        MOV ECX,DWORD PTR SS:[EBP+4]
    0050DB91   . 890D 00737306  MOV DWORD PTR DS:[6737300],ECX
    0050DB97   > 5F             POP EDI
    0050DB98   . 8BC6           MOV EAX,ESI
    0050DB9A   . 5E             POP ESI
    0050DB9B   . 5D             POP EBP
    0050DB9C   . 5B             POP EBX
    0050DB9D   . 83C4 10        ADD ESP,10
    0050DBA0   . C3             RETN
    now take a closer look at the following, this is what CreateDevice looks like:
    Code:
    HRESULT CreateDevice(
      [in]           UINT Adapter,
      [in]           D3DDEVTYPE DeviceType,
      [in]           HWND hFocusWindow,
      [in]           DWORD BehaviorFlags,
      [in, out]      D3DPRESENT_PARAMETERS *pPresentationParameters,
      [out, retval]  IDirect3DDevice9 **ppReturnedDeviceInterface
    );
    And this:

    Code:
    0050DAFC   . 68 E8727306    PUSH iw4mp.067372E8 ; push parameter
    0050DB01   . 55             PUSH EBP ; push parameter
    0050DB02   . 52             PUSH EDX ; push parameter
    0050DB03   . 8B5424 30      MOV EDX,DWORD PTR SS:[ESP+30] ; store one of the arguments to the function in EDX
    0050DB07   . 52             PUSH EDX ; Push parameter
    0050DB08   . A2 F0727306    MOV BYTE PTR DS:[67372F0],AL ; No idea
    0050DB0D   . A1 E4727306    MOV EAX,DWORD PTR DS:[67372E4] ; Store the pointer to the IDirect3D9 pointer in EAX
    0050DB12   . 8B08           MOV ECX,DWORD PTR DS:[EAX] ; Store the address of the actual IDirect3D9 in ECX
    0050DB14   . 6A 01          PUSH 1 ; push parameter
    0050DB16   . 57             PUSH EDI ; push parameter
    0050DB17   . 50             PUSH EAX ; push parameter
    0050DB18   . 8B41 40        MOV EAX,DWORD PTR DS:[ECX+40] ; Store the pointer to CreateDevice in EAX
    0050DB1B   . FFD0           CALL EAX ; Call EAX, which points to CreateDevice
    Since EDX is pushed twice, I just discard one since I have no idea what i'm doing.
    That leaves with 6 pushed parameters, since they're pushed in reverse order(last in first out), it would mean the last parameter of CreateDevice is pushed first.
    Code:
    PUSH iw4mp.067372E8
    OH SHIT! COULD THAT BE THE POINTER TO THE DEVICE POINTER? let's hope so, since I am unable to test

    IDirect3DDevice9 *myDevicePointer = *(IDirect3DDevice9**)0x067372E8;

    I hope this helped!

    Have fun,
    Hell_Demon
    Last edited by Hell_Demon; 04-22-2010 at 02:31 AM.
    Ah we-a blaze the fyah, make it bun dem!

  2. The Following 3 Users Say Thank You to Hell_Demon For This Useful Post:

    falzarex (04-21-2010),Void (04-21-2010),why06 (04-23-2010)

  3. #2
    Void's Avatar
    Join Date
    Sep 2009
    Gender
    male
    Location
    Inline.
    Posts
    3,198
    Reputation
    205
    Thanks
    1,445
    My Mood
    Mellow
    The device class is IDirect3DDevice9, not IDirect3D9. Though, your method still works. You can replace the CreateDevice function with your own and log the last parameter ( returned device pointer ) then start from step 1 using that pointer but for the device class.

    Geewd job HD.

  4. #3
    Hell_Demon's Avatar
    Join Date
    Mar 2008
    Gender
    male
    Location
    I love causing havoc
    Posts
    3,976
    Reputation
    343
    Thanks
    4,320
    My Mood
    Cheeky
    Quote Originally Posted by PedoWaldo44 View Post
    The device class is IDirect3DDevice9, not IDirect3D9. Though, your method still works. You can replace the CreateDevice function with your own and log the last parameter ( returned device pointer ) then start from step 1 using that pointer but for the device class.

    Geewd job HD.
    I realised that like right after I posted it, but had to go so was unable to edit my post.
    I'll go back to olly see where they store the device pointer(since I wan't to do it without changing anything in the game itself)

    edited main post to report my new finding
    Last edited by Hell_Demon; 04-22-2010 at 02:31 AM.
    Ah we-a blaze the fyah, make it bun dem!

  5. #4
    Void's Avatar
    Join Date
    Sep 2009
    Gender
    male
    Location
    Inline.
    Posts
    3,198
    Reputation
    205
    Thanks
    1,445
    My Mood
    Mellow
    To find it, just use the virtual method to get CreateDevice function, follow it and look in the stack. Last parameter is the device. In my "Hooking members of IDirect3DDevice9" tutorial, the inline assembly method I showed is what you should do in olly to find the function using the virtual table.

  6. #5
    Hell_Demon's Avatar
    Join Date
    Mar 2008
    Gender
    male
    Location
    I love causing havoc
    Posts
    3,976
    Reputation
    343
    Thanks
    4,320
    My Mood
    Cheeky
    Quote Originally Posted by PedoWaldo44 View Post
    To find it, just use the virtual method to get CreateDevice function, follow it and look in the stack. Last parameter is the device. In my "Hooking members of IDirect3DDevice9" tutorial, the inline assembly method I showed is what you should do in olly to find the function using the virtual table.
    wouldnt that require the game to be running?

    I doubt this is going to work

    Code:
    IDirect3DDevice9 *myDevicePointer;
    
    HRESULT (*oDrawIndexedPrimitive)(D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex,UINT MinVertexIndex,UINT NumVertices,UINT startIndex,UINT primCount);
    HRESULT xDrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveType,INT BaseVertexIndex,UINT MinVertexIndex,UINT NumVertices,UINT startIndex,UINT primCount)
    {
    	if(primCount == 1337)
    	{
    		myDevicePointer->SetRenderState(D3DRS_ZENABLE, FALSE);
    	}
    	HRESULT ret = oDrawIndexedPrimitive(PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount);
    	if(primCount == 1337)
    	{
    		myDevicePointer->SetRenderState(D3DRS_ZENABLE, TRUE);
    	}
    	return ret;
    }
    
    unsigned long HookVTableOffset(unsigned long address, int offset, unsigned long newFunc)
    {
    	unsigned long retval = *(unsigned long*)(address+(0x4*offset));
    	DWORD dwOld;
    	VirtualProtect((LPVOID)(address+(0x4*offset)), 4, PAGE_EXECUTE_READWRITE, &dwOld);
    	*(unsigned long*)(address+(0x4*offset)) = newFunc;
    	VirtualProtect((LPVOID)(address+(0x4*offset)), 4, dwOld, &dwOld);
    	return retval;
    }
    
    void SetupHook()
    {
    	myDevicePointer = *(IDirect3DDevice9**)0x067372E8;
    
    	oDrawIndexedPrimitive = (HRESULT (__cdecl *)(D3DPRIMITIVETYPE,INT,UINT,UINT,UINT,UINT))HookVTableOffset(*(unsigned long*)myDevicePointer, 82, (unsigned long)xDrawIndexedPrimitive);
    }
    82 is the offset in the vtable for DIP
    Last edited by Hell_Demon; 04-23-2010 at 07:36 AM.
    Ah we-a blaze the fyah, make it bun dem!

  7. #6
    Void's Avatar
    Join Date
    Sep 2009
    Gender
    male
    Location
    Inline.
    Posts
    3,198
    Reputation
    205
    Thanks
    1,445
    My Mood
    Mellow
    Hmm, I meant the inline assembly part. You have address for the created IDirect3D9 instance, using that method you can find CreateDevice, log the last parameter ( look in the stack window ) then use the method again to get the IDirect3DDevice9 address.

    I think your code will work, type definitions for those long annoying casts

  8. #7
    Hell_Demon's Avatar
    Join Date
    Mar 2008
    Gender
    male
    Location
    I love causing havoc
    Posts
    3,976
    Reputation
    343
    Thanks
    4,320
    My Mood
    Cheeky
    I don't like typedefs, never learned how to use those :P
    Ah we-a blaze the fyah, make it bun dem!

Similar Threads

  1. [Tutorial] How to find the pointer to the D3D9 device by lauwy
    By lauwy in forum CrossFire Hack Coding / Programming / Source Code
    Replies: 13
    Last Post: 12-06-2010, 10:40 AM
  2. [Request]What is the D3D Device Pointer
    By lilneo in forum C++/C Programming
    Replies: 7
    Last Post: 10-27-2010, 11:49 PM
  3. How to find the D3D device pointer?
    By Mr.Magicman in forum Combat Arms Help
    Replies: 0
    Last Post: 05-24-2010, 09:56 AM
  4. [CoD:MW2] Getting the D3D Device pointer
    By Hell_Demon in forum Reverse Engineering
    Replies: 0
    Last Post: 05-18-2010, 04:56 AM
  5. [TUT]finding the device pointer
    By RedThunder in forum C++/C Programming
    Replies: 8
    Last Post: 03-16-2010, 03:04 AM