1 (изменено: Malcev, 2023-03-13 12:39:24)

Тема: AHK: Хук DirectX 9 сохранение экрана и добавление надписи

Тема для обсуждения "Хук DirectX 9 сохранение экрана и добавление надписи".
http://forum.script-coding.com/viewtopic.php?id=17678

2

Re: AHK: Хук DirectX 9 сохранение экрана и добавление надписи

Объяснил бы хоть для непосвящённых, какая задача решается, зачем DirectX9, зачем хук. Я например совсем не в теме.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3 (изменено: Malcev, 2019-09-15 19:03:52)

Re: AHK: Хук DirectX 9 сохранение экрана и добавление надписи

Задача перехватывать directx интерфейс для своих нужд, типа фрапса.
После того, как мы его перехватили, в принципе, мы можем делать с ним всё, что угодно - накладывать свои оверлеи или сохранять экран через backbuffer с огромной скоростью.
Делал по алгоритму:
http://spazzarama.com/2010/03/29/screen … api-hooks/
Поправил первый пост.

4 (изменено: teadrinker, 2019-09-16 00:22:46)

Re: AHK: Хук DirectX 9 сохранение экрана и добавление надписи

У меня на Windows 7 выдаёт ошибку:

IWICStream_InitializeFromFilename error: -2147024893
ErrorLevel: 0

Надо ещё уточнить, что код для 32 бит.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

5 (изменено: Malcev, 2019-09-16 00:31:50)

Re: AHK: Хук DirectX 9 сохранение экрана и добавление надписи

А приложение, которое хукаешь 64-битное?
В принципе код должен работать и на 32 бит и на 64бит, только длл нужны соответствующие.

6

Re: AHK: Хук DirectX 9 сохранение экрана и добавление надписи

Malcev пишет:

В принципе код должен работать и на 32 бит и на 64бит, только длл нужны соответствующие.

Да, неправильно выразился.

Malcev пишет:

А приложение, которое хукаешь 64-битное?

То, что в архиве.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

7

Re: AHK: Хук DirectX 9 сохранение экрана и добавление надписи

Похоже ошибка связана с путем файла.
Папка для сохранения файлов существует?

8

Re: AHK: Хук DirectX 9 сохранение экрана и добавление надписи

А, понял, она у тебя в minhook.ahk прописана, теперь работает. Я думал, minhook.ahk — это просто библиотека. User-friendly добавить надо.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

9 (изменено: Malcev, 2020-03-02 16:40:09)

Re: AHK: Хук DirectX 9 сохранение экрана и добавление надписи

Добавление надписи "Hello, World!" в тестируемое приложение.
minhook.ahk

MinhookDll := A_ScriptDir "\MinHook.dll"
global d3dx9_Version := "d3dx9_24"
global pOriginal_EndScene

SetWorkingDir %A_ScriptDir%
d3d := Direct3DCreate9(D3D_SDK_VERSION := 32) 
d3dx9()
VarSetCapacity(D3DPRESENT_PARAMETERS, 48+2*A_PtrSize, 0) 
NumPut(1, D3DPRESENT_PARAMETERS, 0)   ; BackBufferWidth
NumPut(1, D3DPRESENT_PARAMETERS, 4)   ; BackBufferHeight
NumPut(1, D3DPRESENT_PARAMETERS, 24)   ; D3DSWAPEFFECT_DISCARD
NumPut(1, D3DPRESENT_PARAMETERS, 24+2*A_PtrSize)   ; Windowed
IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT := 0, D3DDEVTYPE_HAL := 1, 0, D3DCREATE_HARDWARE_VERTEXPROCESSING := 0x00000040, &D3DPRESENT_PARAMETERS, device)
EndScene := IDirect3DDevice9_Get_EndScene(device)

Release(device)
Release(d3d)

MinHook_Init(MinhookDll)
MH_CreateHook(EndScene, RegisterCallback("EndScene_Hook", "F"), pOriginal_EndScene)
MH_EnableHook()
return


EndScene_Hook(device)
{
   Critical
   static n, font
   if (n = "")
   {
      if (font != "")
      {
         Release(font)
         font := ""
      }
      D3DXCreateFont(device, 70, autowidth := 0, FW_BOLD := 700, 0, false, DEFAULT_CHARSET := 0x1, OUT_DEFAULT_PRECIS := 0, ANTIALIASED_QUALITY := 0x4, DEFAULT_PITCH_I_FF_DONTCARE := 0, "Arial", font)
      VarSetCapacity(Rect, 16, 0)
      NumPut(0, Rect, 0, "int")
      NumPut(0, Rect, 4, "int")
      NumPut(640, Rect, 8, "int")
      NumPut(480, Rect, 12, "int")
      n := 1
   }
   ID3DXFont_DrawTextW(font, 0, "Hello, World!", -1, &Rect, DT_CENTER_I_DT_VCENTER := 1|4, 0xFFFFFFFF)
   DllCall(pOriginal_EndScene, "ptr", device)
   return 
}




D3DXCreateFont(pDevice, Height, Width, Weight, MipLevels, Italic, CharSet, OutputPrecision, Quality, PitchAndFamily, pFacename, ByRef ppFont)
{
   hr := DllCall(d3dx9_Version "\D3DXCreateFont", "ptr", pDevice, "int", Height, "uint", Width, "uint", Weight, "uint", MipLevels, "int", Italic, "uint", CharSet, "uint", OutputPrecision, "uint", Quality, "uint", PitchAndFamily, "str", pFacename, "ptr*", ppFont)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

ID3DXFont_DrawTextW(this, pSprite, pString, Count, pRect, Format, Color)
{
   hr := DllCall(NumGet(NumGet(this+0)+15*A_PtrSize), "ptr", this, "ptr", pSprite, "str", pString, "int", Count, "ptr", pRect, "uint", Format, "uint", Color)
   if !hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

d3dx9()
{
   if !DllCall("GetModuleHandle", "str", d3dx9_Version, "ptr")
   {
      if !DllCall("LoadLibrary","str", d3dx9_Version)
      {
         MsgBox, 16, Error, %d3dx9_Version% failed.
         ExitApp
      }
   }
}

Direct3DCreate9(SDKVersion)
{
   if !DllCall("GetModuleHandle","str","d3d9", "PTR")
   {
      MsgBox, 16, Error, d3d9 failed.
      ExitApp
   }
   return DllCall("d3d9\Direct3DCreate9", "uint", SDKVersion)
}

IDirect3D9_CreateDevice(this,Adapter,DeviceType,hFocusWindow,BehaviorFlags,pPresentationParameters,ByRef ppReturnedDeviceInterface)
{
   hr := DllCall(NumGet(NumGet(this+0)+16*A_PtrSize),"ptr",this,"uint",Adapter,"uint",DeviceType,"ptr",hFocusWindow,"uint",BehaviorFlags,"ptr",pPresentationParameters,"ptr*",ppReturnedDeviceInterface)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IDirect3DDevice9_Get_EndScene(this)
{
   return NumGet(NumGet(this+0)+42*A_PtrSize)
}

Release(this)
{
   DllCall(NumGet(NumGet(this+0)+2*A_PtrSize), "ptr", this)
   if ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

_Error(val)
{
   msgbox % val
   ExitApp
}




MinHook_Init(MinhookDll)
{
   Static h
   If Not h
   {
      h:=DllCall("LoadLibrary","Str",MinhookDll, "Ptr")
      MH_Initialize()
   }
}

; Creates a Hook for the specified target function, in disabled state.
; Parameters:
;   pTarget    [in]  A pointer to the target function, which will be
;                    overridden by the detour function.
;   pDetour    [in]  A pointer to the detour function, which will override
;                    the target function.
;   ppOriginal [out] A pointer to the trampoline function, which will be
;                    used to call the original target function.
;                    This parameter can be NULL.
MH_CreateHook(pTarget, pDetour, ByRef ppOriginal := 0) {
	return DllCall("MinHook\MH_CreateHook"
	               , "ptr", pTarget
	               , "ptr", pDetour
	               , "uptr*", ppOriginal )
}

; Initialize the MinHook library. You must call this function EXACTLY ONCE
; at the beginning of your program.
MH_Initialize() {
	return DllCall("MinHook\MH_Initialize")
}

; Uninitialize the MinHook library. You must call this function EXACTLY
; ONCE at the end of your program.
MH_Uninitialize() {
	return DllCall("MinHook\MH_Uninitialize")
}

; Removes an already created hook.
; Parameters:
;   pTarget [in] A pointer to the target function.
MH_RemoveHook(pTarget) {
	return DllCall("MinHook\MH_RemoveHook", "ptr", pTarget)
}

/*
	#define MH_ALL_HOOKS NULL
*/

; Enables an already created hook.
; Parameters:
;   pTarget [in] A pointer to the target function.
;                If this parameter is MH_ALL_HOOKS, all created hooks are
;                enabled in one go.
MH_EnableHook(pTarget := 0) {
	return DllCall("MinHook\MH_EnableHook", "ptr", pTarget)
}

; Disables an already created hook.
; Parameters:
;   pTarget [in] A pointer to the target function.
;                If this parameter is MH_ALL_HOOKS, all created hooks are
;                disabled in one go.
MH_DisableHook(pTarget := 0) {
	return DllCall("MinHook\MH_DisableHook", "ptr", pTarget)
}