directx 9 endscene hook

Advanced game related topics
xorc1zt
Enthusiast
Enthusiast
Posts: 276
Joined: Sat Jul 09, 2011 7:57 am

directx 9 endscene hook

Post by xorc1zt »

this code is a dll who hook endscene() function from direct3d

the dll is doing
1. create a direct3d device, scan the virtual table to get the functions address then delete the device (being useless)
2. hook d3d endcene() address, we write a JMP to our function
3. we grab the device address from endscene arguments and use it to draw anythings

Code: Select all

; DirectX 9 Hook
; xorc1zt


#D3DFMT_A8R8G8B8=21
#D3DPOOL_SCRATCH=3
#D3DADAPTER_DEFAULT=0
#D3DDEVTYPE_HAL=1
#D3DDEVTYPE_NULLREF=4
#D3DDEVTYPE_REF=2
#D3DDEVTYPE_SW=3
#D3DDEVTYPE_FORCE_DWORD=$ffffffff
#D3DCREATE_SOFTWARE_VERTEXPROCESSING=$00000020
#D3DCREATE_HARDWARE_VERTEXPROCESSING=$00000040
#D3D_SDK_VERSION=32
#D3DSWAPEFFECT_DISCARD=1
#D3DFMT_UNKNOWN=0
#D3DXIFF_BMP=0
#D3DCLEAR_TARGET=1 
#ENDSCENE = 42

Structure D3DPRESENT_PARAMETERS
  BackBufferWidth.i
  BackBufferHeight.i
  BackBufferFormat.i
  BackBufferCount.i
  MultiSampleType.i
  MultiSampleQuality.l
  SwapEffect.i
  hDeviceWindow.i
  Windowed.i
  EnableAutoDepthStencil.i
  AutoDepthStencilFormat.i
  Flags.l
  FullScreen_RefreshRateInHz.i
  PresentationInterval.i
EndStructure
Global *g_pD3D.IDirect3D9
Global *g_pd3dDevice.IDirect3DDevice9
Global Dim dxfuncsaddress.l(0)
Global *endscene
Global *backtoendscene
Global *device.IDirect3DDevice9

Procedure grabvtable()
  OpenWindow(0,0,0,300,300, "hello")
  d3dpp.D3DPRESENT_PARAMETERS
  d3dpp\Windowed=#True
  d3dpp\SwapEffect=#D3DSWAPEFFECT_DISCARD
  d3dpp\BackBufferFormat=#D3DFMT_UNKNOWN
  d3dpp\BackBufferWidth=320
  d3dpp\BackBufferHeight=240
  d3dpp\hDeviceWindow=WindowID(0)
  OpenLibrary(0,"d3d9.dll")
  *g_pD3D=CallFunction(0,"Direct3DCreate9",#D3D_SDK_VERSION)
  *g_pD3D\CreateDevice(#D3DADAPTER_DEFAULT,#D3DDEVTYPE_HAL,0,#D3DCREATE_HARDWARE_VERTEXPROCESSING,@d3dpp,@*g_pd3dDevice)
  *vtable.l = PeekL(*g_pd3dDevice) ; store the address of the vtable
  ConsoleColor(7, 0)
  Print("D3D Address = ")
  ConsoleColor(4, 0)
  PrintN("0x" + Hex(*g_pD3D))
  ConsoleColor(7, 0)
  Print("D3D Device Address = ")
  ConsoleColor(4, 0)
  PrintN("0x" + Hex(*g_pd3dDevice))
  ConsoleColor(7, 0)
  Print("D3D VTable Address = ")
  ConsoleColor(4, 0)
  PrintN("0x" + Hex(*vtable))
  PrintN("")
  PrintN("")
  ConsoleColor(7, 0)
  PrintN("VTABLE Functions Address:")
  boucle.i=0
  vtablefuncaddress.l = PeekL(*vtable) ; read the first address of the vtable
  While(vtablefuncaddress) ; read each address till end of the vtable
    ;Debug Str(boucle) + " " + Hex(vtablefuncaddress) + "  +" + Str(boucle*4)
    ConsoleColor(7, 0)
    Print(Str(boucle))
    ConsoleColor(4, 0)
    Print(" 0x" + Hex(vtablefuncaddress))
    ConsoleColor(2, 0)
    PrintN("  +" + Hex(boucle*4))
    dxfuncsaddress(boucle)=vtablefuncaddress
    boucle+1
    ReDim dxfuncsaddress(boucle)
    vtablefuncaddress = PeekL(*vtable+(boucle*4))
  Wend
  ConsoleColor(7, 0)
  PrintN("VTable End")
  *g_pd3dDevice\Release()
  *g_pD3D\Release()
  CloseWindow(0)
EndProcedure

Procedure myEndscene(*adevice)
  ;first argument is the device address
  *device=*adevice ;

  ;we save the registers and flags
  PUSHAD
  PUSHFD
  
  ;we do our stuff
  ConsoleColor(7, 0)
  PrintN("myEndscene called!")
  *device\Clear(0, 0, #D3DCLEAR_TARGET, RGBA(0,255,0,0), 0.0, 0) 
  
  ;we restore the registers and flags
  POPFD
  POPAD
  ;POP ebx
  ;here is the original endscene first bytes
  MOV edi,edi
  PUSH EBP
  MOV EBP, ESP
  ;we jump back to endscene
  JMP *backtoendscene
EndProcedure

;First bytes of endscene should be this
;   6B0A279F   8BFF             MOV EDI,EDI
;   6B0A27A1   55               PUSH EBP
;   6B0A27A2   8BEC             MOV EBP,ESP
;   6B0A27A4   6A FF            PUSH -1
Procedure.i EndsceneHOOK()
  protection.w
  *endscene = dxfuncsaddress(#ENDSCENE)
  JMPaddr.l = (@myEndscene() - *endscene)-5
  ConsoleColor(7, 0)
  Print("Endscene (")
  ConsoleColor(4, 0)
  Print("0x"+Hex(dxfuncsaddress(#ENDSCENE)))
  ConsoleColor(7, 0)
  Print(") : ")
  ConsoleColor(14, 0)
  Print(Hex(PeekA(*endscene))+" ")
  Print(Hex(PeekA(*endscene+1))+" ")
  Print(Hex(PeekA(*endscene+2))+" ")
  Print(Hex(PeekA(*endscene+3))+" ")
  Print(Hex(PeekA(*endscene+4))+" ")
  Print(Hex(PeekA(*endscene+5))+" ")
  PrintN(Hex(PeekA(*endscene+6))+" ")
  
  ConsoleColor(7, 0)
  Print("Writting a jump to myEndscene (")
  ConsoleColor(4, 0)
  Print("0x"+Hex(@myEndscene()))
  ConsoleColor(7, 0)
  PrintN(")")
  
  ; make the target writable, write our jump and restore the protection.
  VirtualProtect_(*endscene, 5, #PAGE_EXECUTE_READWRITE, @protection)
  PokeA(*endscene,$E9)
  PokeL(*endscene+1, JMPaddr)
  VirtualProtect_(*endscene, 5, protection, @protection )
  
  ConsoleColor(7, 0)
  Print("Endscene (")
  ConsoleColor(4, 0)
  Print("0x"+Hex(dxfuncsaddress(#ENDSCENE)))
  ConsoleColor(7, 0)
  Print(") : ")
  ConsoleColor(14, 0)
  Print(Hex(PeekA(*endscene))+" ")
  Print(Hex(PeekA(*endscene+1))+" ")
  Print(Hex(PeekA(*endscene+2))+" ")
  Print(Hex(PeekA(*endscene+3))+" ")
  Print(Hex(PeekA(*endscene+4))+" ")
  Print(Hex(PeekA(*endscene+5))+" ")
  PrintN(Hex(PeekA(*endscene+6))+" ")
  
  *backtoendscene = *endscene+5
  ConsoleColor(7, 0)
  Print("myEndscene will Jump back to ")
  ConsoleColor(4, 0)
  PrintN("0x"+Hex(*backtoendscene))
  PrintN("")
  PrintN("")
EndProcedure

Procedure MyThread()
  grabvtable()
  EndsceneHOOK()
EndProcedure

ProcedureDLL AttachProcess(Instance)
  OpenConsole()
  ConsoleTitle("D3D Hook")
  CreateThread(@MyThread(),1)
  
EndProcedure
  
ProcedureDLL DetachProcess(Instance)
  CloseConsole()  
EndProcedure
  
  
ProcedureDLL AttachThread(Instance)

EndProcedure
  
ProcedureDLL DetachThread(Instance)

EndProcedure

A little executable code to test the dll, after the dll got injected the screen should turn green.

Code: Select all

#D3DFMT_A8R8G8B8=21
#D3DPOOL_SCRATCH=3
#D3DADAPTER_DEFAULT=0
#D3DDEVTYPE_HAL=1
#D3DDEVTYPE_NULLREF=4
#D3DDEVTYPE_REF=2
#D3DDEVTYPE_SW=3
#D3DDEVTYPE_FORCE_DWORD=$ffffffff
#D3DCREATE_SOFTWARE_VERTEXPROCESSING=$00000020
#D3DCREATE_HARDWARE_VERTEXPROCESSING=$00000040
#D3D_SDK_VERSION=32
#D3DSWAPEFFECT_DISCARD=1
#D3DFMT_UNKNOWN=0
#D3DXIFF_BMP=0
#D3DCLEAR_TARGET=1
Global Dim dxfuncsaddress.l(0)

Procedure test()
  Debug test
EndProcedure

Structure D3DPRESENT_PARAMETERS
  BackBufferWidth.i
  BackBufferHeight.i
  BackBufferFormat.i
  BackBufferCount.i
  MultiSampleType.i
  MultiSampleQuality.l
  SwapEffect.i
  hDeviceWindow.i
  Windowed.i
  EnableAutoDepthStencil.i
  AutoDepthStencilFormat.i
  Flags.l
  FullScreen_RefreshRateInHz.i
  PresentationInterval.i
EndStructure

*g_pD3D.IDirect3D9
*g_pd3dDevice.IDirect3DDevice9

OpenWindow(0,0,0,300,300,"Direct3D Tutorial 01: CreateDevice",#WS_OVERLAPPEDWINDOW | 1)
d3dpp.D3DPRESENT_PARAMETERS
d3dpp\Windowed=#True
d3dpp\SwapEffect=#D3DSWAPEFFECT_DISCARD
d3dpp\BackBufferFormat=#D3DFMT_UNKNOWN
d3dpp\BackBufferWidth=320
d3dpp\BackBufferHeight=240
d3dpp\hDeviceWindow=WindowID(0)

r = OpenLibrary(0,"d3d9.dll")
*g_pD3D=CallFunction(0,"Direct3DCreate9",#D3D_SDK_VERSION)
*g_pD3D\CreateDevice(#D3DADAPTER_DEFAULT,#D3DDEVTYPE_HAL,0,#D3DCREATE_HARDWARE_VERTEXPROCESSING,@d3dpp,@*g_pd3dDevice)
*vtable.l = PeekL(*g_pd3dDevice) ; store the address for the vtable
Debug "D3DCreate at 0x"+Hex(*g_pD3D)
Debug "Device at 0x"+Hex(*g_pd3dDevice)
Debug "Vtable at 0x" + Hex(PeekL(*g_pd3dDevice))
boucle.i=0
  vtablefuncaddress.l = PeekL(*vtable) ; read the first address of the vtable
  While(vtablefuncaddress) ; read each address till end of the vtable
    Debug Str(boucle) + " " + Hex(vtablefuncaddress) + "  +" + Str(boucle*4)
    boucle+1
    vtablefuncaddress = PeekL(*vtable+(boucle*4))
  Wend


  Repeat
   *g_pd3dDevice\Clear(0, 0, #D3DCLEAR_TARGET, RGBA(255,0,0,0), 0.0, 0) 
   *g_pd3dDevice\BeginScene()
   *g_pd3dDevice\EndScene()
   *g_pd3dDevice\Present(NULL, NULL, NULL, NULL)
  Until WaitWindowEvent()=#PB_Event_CloseWindow 
End
The code work with Far Cry 2 and should work with any dx9 games. To inject the dll i use Winject 1.7
User avatar
Shield
Addict
Addict
Posts: 1021
Joined: Fri Jan 21, 2011 8:25 am
Location: 'stralia!
Contact:

Re: directx 9 endscene hook

Post by Shield »

Hi

Wanted to test your code for the whole week but couldn't until now.
It works great! Thanks for sharing that code, great example on how to do such things,
very interesting! :)
Image
Blog: Why Does It Suck? (http://whydoesitsuck.com/)
"You can disagree with me as much as you want, but during this talk, by definition, anybody who disagrees is stupid and ugly."
- Linus Torvalds
Machiavelli
User
User
Posts: 26
Joined: Sun May 24, 2009 2:38 pm

Re: directx 9 endscene hook

Post by Machiavelli »

But how to draw some text?
xorc1zt
Enthusiast
Enthusiast
Posts: 276
Joined: Sat Jul 09, 2011 7:57 am

Re: directx 9 endscene hook

Post by xorc1zt »

after endscene is hook you got the device pointer from arguments

Code: Select all

Procedure myEndscene(*adevice)
  ;first argument is the device address
  *device=*adevice ;
u can do everything with the device like create a new font with D3DXCreateFont
Zach
Addict
Addict
Posts: 1654
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: directx 9 endscene hook

Post by Zach »

Neat subject, I won't really pretend to understand it... But may I ask what a practical application of this code would be?
Image
xorc1zt
Enthusiast
Enthusiast
Posts: 276
Joined: Sat Jul 09, 2011 7:57 am

Re: directx 9 endscene hook

Post by xorc1zt »

softwares like teamspeak, xfire, mumble or steam are detouring directx to add a overlay into any games. Fraps doing the same to be able to record videos.
Zach
Addict
Addict
Posts: 1654
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: directx 9 endscene hook

Post by Zach »

I think I understand. Thanks
Image
xorc1zt
Enthusiast
Enthusiast
Posts: 276
Joined: Sat Jul 09, 2011 7:57 am

Re: directx 9 endscene hook

Post by xorc1zt »

Detouring is modifying the first bytes of a function, we write a jump to our function who will jump back to the first one.

this schema show how work the detour method is used here
Image
User avatar
Comtois
Addict
Addict
Posts: 1429
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Re: directx 9 endscene hook

Post by Comtois »

xorc1zt wrote:To inject the dll i use Winject 1.7
Or you can use this code, it work fine., i have tested with your dll and your example :)

Code: Select all

; Code de SFSxOI
; Injecter une Dll dans un exécutable

Prototype.i PFNCreateToolhelp32Snapshot(dwFlags.i, th32ProcessID.i) ;
Prototype.b PFNProcess32First(hSnapshot.i, *lppe.PROCESSENTRY32) ;
Prototype.b PFNProcess32Next(hSnapshot.i, *lppe.PROCESSENTRY32) ;

Procedure GetPidByName(p_name$)
    Protected hDLL.i, process_name$
    Protected PEntry.PROCESSENTRY32, hTool32.i
    Protected pCreateToolhelp32Snapshot.PFNCreateToolhelp32Snapshot
    Protected pProcess32First.PFNProcess32First
    Protected pProcess32Next.PFNProcess32Next
    Protected pid.i
   
    hDLL = OpenLibrary(#PB_Any,"kernel32.dll")
   
    If hDLL
        pCreateToolhelp32Snapshot = GetFunction(hDLL,"CreateToolhelp32Snapshot")
        pProcess32First = GetFunction(hDLL,"Process32First")
        pProcess32Next = GetFunction(hDLL,"Process32Next")
    Else
        ProcedureReturn 0
    EndIf
   
    PEntry\dwSize = SizeOf(PROCESSENTRY32)
    hTool32 = pCreateToolhelp32Snapshot(#TH32CS_SNAPPROCESS, 0)
    pProcess32First(hTool32, @PEntry)
    process_name$ = Space(#MAX_PATH)
    CopyMemory(@PEntry\szExeFile,@process_name$,#MAX_PATH)
   
    If  UCase(process_name$) = UCase(p_name$)
        ProcedureReturn PEntry\th32ProcessID
    EndIf
   
    While pProcess32Next(hTool32, @PEntry) > 0
        process_name$ = Space(#MAX_PATH)
        CopyMemory(@PEntry\szExeFile,@process_name$,#MAX_PATH)
       
        If  UCase(process_name$) = UCase(p_name$)
            ProcedureReturn PEntry\th32ProcessID
        EndIf
   
    Wend
   
    CloseLibrary(hDLL)
   
    ProcedureReturn 0
EndProcedure

Procedure InjectLibA(dwProcessId.i, pszLibFile$)
  hProcess.i
  hThread.i
  lzLibFileRemote.i
  lSize.i
  endSize.i
  lsThreadRtn.i

  hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_CREATE_THREAD | #PROCESS_VM_OPERATION | #PROCESS_VM_WRITE, 0, dwProcessId)

  If hProcess = 0 : Goto ErrHandle : EndIf
  lSize = 1 + Len(pszLibFile$)
  endSize = lSize

  lzLibFileRemote = VirtualAllocEx_(hProcess, #Null, endSize, #MEM_COMMIT, #PAGE_READWRITE)

  If lzLibFileRemote = 0 : Goto ErrHandle : EndIf

  If (WriteProcessMemory_(hProcess, lzLibFileRemote, pszLibFile$, endSize, #Null) = 0) : Goto ErrHandle : EndIf

  OpenLibrary(0, "Kernel32.dll") : lsThreadRtn = GetFunction(0, "LoadLibraryA") : CloseLibrary(0)

  If lsThreadRtn = 0 : Goto ErrHandle : EndIf

  hThread = CreateRemoteThread_(hProcess, #Null, #Null, lsThreadRtn, lzLibFileRemote, #Null, #Null)

  If (hThread = 0) : Goto ErrHandle : EndIf

  WaitForSingleObject_(hThread, #INFINITE)

  If lzLibFileRemote<>0
    VirtualFreeEx_(hProcess, lzLibFileRemote, 0, #MEM_RELEASE)
    MessageRequester("Inject Status", "Injection Suceeded", 0)
    Else
    VirtualFreeEx_(hProcess, lzLibFileRemote, 0, #MEM_RELEASE)
    MessageRequester("Inject Status", "Injection Failed !!!", 0)
  EndIf
  End

  ErrHandle:
      CloseHandle_(hThread)
      CloseHandle_(hProcess)
EndProcedure

Input_proc$ = InputRequester("Simple DLL injector", "Please enter target process name (.exe):", "") ;enter process name i.e...notepad.exe
val_pid.i = GetPidByName(Input_proc$)
Delay(10)
File_dll$ = OpenFileRequester("Choose .dll file to inject", "C:\", "DLL File (*.dll)|*.dll;*.dll", 0)
Delay(10)
InjectLibA(val_pid, File_dll$)
Please correct my english
http://purebasic.developpez.com/
User avatar
graph100
Enthusiast
Enthusiast
Posts: 115
Joined: Tue Aug 10, 2010 3:17 pm

Re: directx 9 endscene hook

Post by graph100 »

c'est pas dangereux ça ?

How do you know the entrie point of the dll you are injecting ? You just have to put the dll inside the executing exe and it works ?
_________________________________________________
My Website : CeriseCode (Warning : perpetual changes & not completed ;))
Machiavelli
User
User
Posts: 26
Joined: Sun May 24, 2009 2:38 pm

Re: directx 9 endscene hook

Post by Machiavelli »

xorc1zt wrote:after endscene is hook you got the device pointer from arguments

Code: Select all

Procedure myEndscene(*adevice)
  ;first argument is the device address
  *device=*adevice ;
u can do everything with the device like create a new font with D3DXCreateFont
I tried, but the target app is crashes everytime.
Is D3DXCreateFont in d3d9.dll and should i just call it, or D3DXCreateFontA?
xorc1zt
Enthusiast
Enthusiast
Posts: 276
Joined: Sat Jul 09, 2011 7:57 am

Re: directx 9 endscene hook

Post by xorc1zt »

D3DXCreateFont is from D3DX9 Api (d3dx9.lib)

From msdn

Code: Select all

HRESULT D3DXCreateFont(
  __in   LPDIRECT3DDEVICE9 pDevice,
  __in   INT Height,
  __in   UINT Width,
  __in   UINT Weight,
  __in   UINT MipLevels,
  __in   BOOL Italic,
  __in   DWORD CharSet,
  __in   DWORD OutputPrecision,
  __in   DWORD Quality,
  __in   DWORD PitchAndFamily,
  __in   LPCTSTR pFacename,
  __out  LPD3DXFONT *ppFont
);
The compiler setting also determines the function version. If Unicode is defined, the function call resolves to D3DXCreateFontW. Otherwise, the function call resolves to D3DXCreateFontA because ANSI strings are being used.
http://msdn.microsoft.com/en-us/library ... 85%29.aspx

you must use D3DXCreateFontW for unicode or D3DXCreateFontA for ascii

Import of D3DXCreateFontA

Code: Select all

Import "lib\d3dx9.lib" ; DirectX SDX
  D3DXCreateFontA(*pDevice, Height.i, Width.l, Weight.l, MipLevels.l, Italic.b, CharSet.l, OutputPrecision.l, Quality.l, PitchAndFamily.l, *pFacename, *ppFont)
EndImport
Creation of the font

Code: Select all

*testfont.ID3DXFont
name.s = "Courrier New"
D3DXCreateFontA(*D3DDevice, 12, 0,0,1,0, #DEFAULT_CHARSET, #OUT_DEFAULT_PRECIS, #DEFAULT_QUALITY, #DEFAULT_PITCH, @name,@*testfont)
to draw text you must call drawtext()

Code: Select all

INT DrawText(
  [in]  LPD3DXSPRITE pSprite,
  [in]  LPCTSTR pString,
  [in]  INT Count,
  [in]  LPRECT pRect,
  [in]  DWORD Format,
  [in]  D3DCOLOR Color
);
This method must be called inside a BeginScene ... EndScene block. The only exception is when an application calls DrawText with DT_CALCRECT to calculate the size of a given block of text.
http://msdn.microsoft.com/en-us/library ... 85%29.aspx

First you must create a new rectangle

Code: Select all

textrect.RECT
textrect\left= 10 ; X
textrect\top= 10 ; Y
Then calculate the size of the rectangle with DrawText and DT_CALCRECT as parameter
DT_CALCRECT

Determines the width and height of the rectangle. If there are multiple lines of text, DrawText uses the width of the rectangle pointed to by the pRect parameter and extends the base of the rectangle to bound the last line of text. If there is only one line of text, DrawText modifies the right side of the rectangle so that it bounds the last character in the line. In either case, DrawText returns the height of the formatted text but does not draw the text.

Code: Select all

*testfont\DrawTextA(NULL, "HelloWorld", -1, textrect, #DT_CALCRECT | #DT_LEFT, NULL)
Debug textrect\right
Debug textrect\bottom
and finally draw the text

Code: Select all

   *D3DDevice\Clear(0, 0, #D3DCLEAR_TARGET, D3DRGBA(0,0,0,255), 0.0, 0) 
   *D3DDevice\BeginScene()
   *testfont\DrawTextA(NULL, "HelloWorld", -1, textrect, #DT_LEFT, D3DRGBA(0,0,255,255))
   *D3DDevice\EndScene()
   *D3DDevice\Present(NULL, NULL, NULL, NULL)
You can't use RGBA() with directx, here is a compatible macro

Code: Select all

Macro D3DRGBA (r, g, b, a)
  (a&$ff)<<24 | (r&$ff)<<16 | (g&$ff)<<8 | (b&$ff)
EndMacro
rincewind
New User
New User
Posts: 1
Joined: Fri Jan 06, 2012 1:03 pm

Re: directx 9 endscene hook

Post by rincewind »

So whats wrong with this code?

Code: Select all

del
UPD:
Anyway, punkbuster kicks me using this method.
Does anyone know how is overlay works in Mumble or can translate it to PB?
Liqu
User
User
Posts: 77
Joined: Sun Apr 21, 2013 10:31 am

Re: directx 9 endscene hook

Post by Liqu »

would someone please update the code to PB 5?
since i get syntax error :(

i want to create an overlay menu inside directx game ( like warcraft, cod, bf3 , etc ) like steam did, an example to create it will be very helpful

thank you :)
Liqu
User
User
Posts: 77
Joined: Sun Apr 21, 2013 10:31 am

Re: directx 9 endscene hook

Post by Liqu »

Code Updated to PB 5.20 by Demivec

Code: Select all

; DirectX 9 Hook
; xorc1zt


#D3DFMT_A8R8G8B8=21
#D3DPOOL_SCRATCH=3
#D3DADAPTER_DEFAULT=0
#D3DDEVTYPE_HAL=1
#D3DDEVTYPE_NULLREF=4
#D3DDEVTYPE_REF=2
#D3DDEVTYPE_SW=3
#D3DDEVTYPE_FORCE_DWORD=$ffffffff
#D3DCREATE_SOFTWARE_VERTEXPROCESSING=$00000020
#D3DCREATE_HARDWARE_VERTEXPROCESSING=$00000040
#D3D_SDK_VERSION=32
#D3DSWAPEFFECT_DISCARD=1
#D3DFMT_UNKNOWN=0
#D3DXIFF_BMP=0
#D3DCLEAR_TARGET=1 
#ENDSCENE = 42

Structure D3DPRESENT_PARAMETERS
  BackBufferWidth.i
  BackBufferHeight.i
  BackBufferFormat.i
  BackBufferCount.i
  MultiSampleType.i
  MultiSampleQuality.l
  SwapEffect.i
  hDeviceWindow.i
  Windowed.i
  EnableAutoDepthStencil.i
  AutoDepthStencilFormat.i
  Flags.l
  FullScreen_RefreshRateInHz.i
  PresentationInterval.i
EndStructure
Global *g_pD3D.IDirect3D9
Global *g_pd3dDevice.IDirect3DDevice9
Global Dim dxfuncsaddress.l(0)
Global *endscene
Global *backtoendscene
Global *device.IDirect3DDevice9

Procedure grabvtable()
  OpenWindow(0,0,0,300,300, "hello")
  d3dpp.D3DPRESENT_PARAMETERS
  d3dpp\Windowed=#True
  d3dpp\SwapEffect=#D3DSWAPEFFECT_DISCARD
  d3dpp\BackBufferFormat=#D3DFMT_UNKNOWN
  d3dpp\BackBufferWidth=320
  d3dpp\BackBufferHeight=240
  d3dpp\hDeviceWindow=WindowID(0)
  OpenLibrary(0,"d3d9.dll")
  *g_pD3D=CallFunction(0,"Direct3DCreate9",#D3D_SDK_VERSION)
  *g_pD3D\CreateDevice(#D3DADAPTER_DEFAULT,#D3DDEVTYPE_HAL,0,#D3DCREATE_HARDWARE_VERTEXPROCESSING,@d3dpp,@*g_pd3dDevice)
  *vtable = PeekL(*g_pd3dDevice) ; store the address of the vtable
  ConsoleColor(7, 0)
  Print("D3D Address = ")
  ConsoleColor(4, 0)
  PrintN("0x" + Hex(*g_pD3D))
  ConsoleColor(7, 0)
  Print("D3D Device Address = ")
  ConsoleColor(4, 0)
  PrintN("0x" + Hex(*g_pd3dDevice))
  ConsoleColor(7, 0)
  Print("D3D VTable Address = ")
  ConsoleColor(4, 0)
  PrintN("0x" + Hex(*vtable))
  PrintN("")
  PrintN("")
  ConsoleColor(7, 0)
  PrintN("VTABLE Functions Address:")
  boucle.i=0
  vtablefuncaddress.l = PeekL(*vtable) ; read the first address of the vtable
  While(vtablefuncaddress) ; read each address till end of the vtable
    ;Debug Str(boucle) + " " + Hex(vtablefuncaddress) + "  +" + Str(boucle*4)
    ConsoleColor(7, 0)
    Print(Str(boucle))
    ConsoleColor(4, 0)
    Print(" 0x" + Hex(vtablefuncaddress))
    ConsoleColor(2, 0)
    PrintN("  +" + Hex(boucle*4))
    dxfuncsaddress(boucle)=vtablefuncaddress
    boucle+1
    ReDim dxfuncsaddress(boucle)
    vtablefuncaddress = PeekL(*vtable+(boucle*4))
  Wend
  ConsoleColor(7, 0)
  PrintN("VTable End")
  *g_pd3dDevice\Release()
  *g_pD3D\Release()
  CloseWindow(0)
EndProcedure

Procedure myEndscene(*adevice)
  ;first argument is the device address
  *device=*adevice ;

  ;we save the registers and flags
  !PUSHAD
  !PUSHFD
  
  ;we do our stuff
  ConsoleColor(7, 0)
  PrintN("myEndscene called!")
  *device\Clear(0, 0, #D3DCLEAR_TARGET, RGBA(0,255,0,0), 0.0, 0) 
  
  ;we restore the registers and flags
  !POPFD
  !POPAD
  ;POP ebx
  ;here is the original endscene first bytes
  !MOV edi,edi
  !PUSH EBP
  !MOV EBP, ESP
  ;we jump back to endscene
  JMP *backtoendscene
EndProcedure

;First bytes of endscene should be this
;   6B0A279F   8BFF             MOV EDI,EDI
;   6B0A27A1   55               PUSH EBP
;   6B0A27A2   8BEC             MOV EBP,ESP
;   6B0A27A4   6A FF            PUSH -1
Procedure.i EndsceneHOOK()
  protection.w
  *endscene = dxfuncsaddress(#ENDSCENE)
  JMPaddr.l = (@myEndscene() - *endscene)-5
  ConsoleColor(7, 0)
  Print("Endscene (")
  ConsoleColor(4, 0)
  Print("0x"+Hex(dxfuncsaddress(#ENDSCENE)))
  ConsoleColor(7, 0)
  Print(") : ")
  ConsoleColor(14, 0)
  Print(Hex(PeekA(*endscene))+" ")
  Print(Hex(PeekA(*endscene+1))+" ")
  Print(Hex(PeekA(*endscene+2))+" ")
  Print(Hex(PeekA(*endscene+3))+" ")
  Print(Hex(PeekA(*endscene+4))+" ")
  Print(Hex(PeekA(*endscene+5))+" ")
  PrintN(Hex(PeekA(*endscene+6))+" ")
  
  ConsoleColor(7, 0)
  Print("Writting a jump to myEndscene (")
  ConsoleColor(4, 0)
  Print("0x"+Hex(@myEndscene()))
  ConsoleColor(7, 0)
  PrintN(")")
  
  ; make the target writable, write our jump and restore the protection.
  VirtualProtect_(*endscene, 5, #PAGE_EXECUTE_READWRITE, @protection)
  PokeA(*endscene,$E9)
  PokeL(*endscene+1, JMPaddr)
  VirtualProtect_(*endscene, 5, protection, @protection )
  
  ConsoleColor(7, 0)
  Print("Endscene (")
  ConsoleColor(4, 0)
  Print("0x"+Hex(dxfuncsaddress(#ENDSCENE)))
  ConsoleColor(7, 0)
  Print(") : ")
  ConsoleColor(14, 0)
  Print(Hex(PeekA(*endscene))+" ")
  Print(Hex(PeekA(*endscene+1))+" ")
  Print(Hex(PeekA(*endscene+2))+" ")
  Print(Hex(PeekA(*endscene+3))+" ")
  Print(Hex(PeekA(*endscene+4))+" ")
  Print(Hex(PeekA(*endscene+5))+" ")
  PrintN(Hex(PeekA(*endscene+6))+" ")
  
  *backtoendscene = *endscene+5
  ConsoleColor(7, 0)
  Print("myEndscene will Jump back to ")
  ConsoleColor(4, 0)
  PrintN("0x"+Hex(*backtoendscene))
  PrintN("")
  PrintN("")
EndProcedure

Procedure MyThread()
  grabvtable()
  EndsceneHOOK()
EndProcedure

ProcedureDLL AttachProcess(Instance)
  OpenConsole()
  ConsoleTitle("D3D Hook")
  CreateThread(@MyThread(),1)
  
EndProcedure
  
ProcedureDLL DetachProcess(Instance)
  CloseConsole()  
EndProcedure
  
  
ProcedureDLL AttachThread(Instance)

EndProcedure
  
ProcedureDLL DetachThread(Instance)

EndProcedure

Code: Select all

#D3DFMT_A8R8G8B8=21
#D3DPOOL_SCRATCH=3
#D3DADAPTER_DEFAULT=0
#D3DDEVTYPE_HAL=1
#D3DDEVTYPE_NULLREF=4
#D3DDEVTYPE_REF=2
#D3DDEVTYPE_SW=3
#D3DDEVTYPE_FORCE_DWORD=$ffffffff
#D3DCREATE_SOFTWARE_VERTEXPROCESSING=$00000020
#D3DCREATE_HARDWARE_VERTEXPROCESSING=$00000040
#D3D_SDK_VERSION=32
#D3DSWAPEFFECT_DISCARD=1
#D3DFMT_UNKNOWN=0
#D3DXIFF_BMP=0
#D3DCLEAR_TARGET=1
Global Dim dxfuncsaddress.l(0)

Procedure test()
  Debug test
EndProcedure

Structure D3DPRESENT_PARAMETERS
  BackBufferWidth.i
  BackBufferHeight.i
  BackBufferFormat.i
  BackBufferCount.i
  MultiSampleType.i
  MultiSampleQuality.l
  SwapEffect.i
  hDeviceWindow.i
  Windowed.i
  EnableAutoDepthStencil.i
  AutoDepthStencilFormat.i
  Flags.l
  FullScreen_RefreshRateInHz.i
  PresentationInterval.i
EndStructure

*g_pD3D.IDirect3D9
*g_pd3dDevice.IDirect3DDevice9

OpenWindow(0,0,0,300,300,"Direct3D Tutorial 01: CreateDevice",#WS_OVERLAPPEDWINDOW | 1)
d3dpp.D3DPRESENT_PARAMETERS
d3dpp\Windowed=#True
d3dpp\SwapEffect=#D3DSWAPEFFECT_DISCARD
d3dpp\BackBufferFormat=#D3DFMT_UNKNOWN
d3dpp\BackBufferWidth=320
d3dpp\BackBufferHeight=240
d3dpp\hDeviceWindow=WindowID(0)

r = OpenLibrary(0,"d3d9.dll")
*g_pD3D=CallFunction(0,"Direct3DCreate9",#D3D_SDK_VERSION)
*g_pD3D\CreateDevice(#D3DADAPTER_DEFAULT,#D3DDEVTYPE_HAL,0,#D3DCREATE_HARDWARE_VERTEXPROCESSING,@d3dpp,@*g_pd3dDevice)
*vtable = PeekL(*g_pd3dDevice) ; store the address for the vtable
Debug "D3DCreate at 0x"+Hex(*g_pD3D)
Debug "Device at 0x"+Hex(*g_pd3dDevice)
Debug "Vtable at 0x" + Hex(PeekL(*g_pd3dDevice))
boucle.i=0
  vtablefuncaddress.l = PeekL(*vtable) ; read the first address of the vtable
  While(vtablefuncaddress) ; read each address till end of the vtable
    Debug Str(boucle) + " " + Hex(vtablefuncaddress) + "  +" + Str(boucle*4)
    boucle+1
    vtablefuncaddress = PeekL(*vtable+(boucle*4))
  Wend


  Repeat
   *g_pd3dDevice\Clear(0, 0, #D3DCLEAR_TARGET, RGBA(255,0,0,0), 0.0, 0) 
   *g_pd3dDevice\BeginScene()
   *g_pd3dDevice\EndScene()
   *g_pd3dDevice\Present(NULL, NULL, NULL, NULL)
  Until WaitWindowEvent()=#PB_Event_CloseWindow 
End

even the code has been updated, i don't know how to use it :oops:

i've compile the dll to testdll.dll then launch the second code, open war3.exe ( warcraft 3 ), use Injecter une Dll dans un exécutable by SFSxOI then nothing happened, no green screen
i also tried open war3.exe, use injector, open second code, but nothing happened too.

really need enlightment :)
Post Reply