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
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
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
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
);
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
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: Select all
PUSH iw4mp.067372E8
IDirect3DDevice9 *myDevicePointer = *(IDirect3DDevice9**)0x067372E8;
I made it /me :D
This is probably way to advanced for sethioz, but I guess other people around here migth have fun with this :)
Have fun,
Hell_Demon