---
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: Select all
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: Select all
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: Select all
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: Select all
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: Select all
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.
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.
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
---
Can't be arsed reuploading pictures etc, so here are my other 2 guides.
No recoil
No flash/stun