Тема: AHK: Хук DirectX 11 и добавление надписи
Желательно запускать исходную программу в режиме suspended, после чего инжектить autohotkey.dll.
Потом узнавать адрес IDXGISwapChain_Present и хукать его с помощью minhook.dll.
inject.ahk - запускает программу в режиме suspended:
В TargetProgram вписываем путь к запускаемой программе.
TargetProgram := "GFXTest.exe"
AutoHotkeyDll := "AutoHotkey.dll"
HookFile := "minhook.ahk"
array := {"TargetProgram": TargetProgram, "AutoHotkey.dll": AutoHotkeyDll, "HookFile": HookFile}
For key, value in array
{
if !FileExist(value)
{
msgbox %value% does not exist
ExitApp
}
if (key = "HookFile")
Continue
oFile := FileOpen(value, "r")
oFile.Seek(0x3c)
oFile.Seek(oFile.ReadInt()+4)
machineType := oFile.ReadUShort()
oFile.Close()
if (machineType = 0x14c) and (A_PtrSize = 8)
{
msgbox %key% 32 bit, but AutoHotkey.exe 64 bit
ExitApp
}
if ((machineType = 0x8664) or (machineType = 0x200)) and (A_PtrSize = 4)
{
msgbox %key% 64 bit, but AutoHotkey.exe 32 bit
ExitApp
}
}
#Persistent
VarSetCapacity(StartupInfo, size := 9*A_PtrSize + 32, 0)
NumPut(size, StartupInfo)
VarSetCapacity(ProcessInfo, 2*A_PtrSize + 8, 0)
DllCall("CreateProcess", "ptr", 0, "str", TargetProgram, "ptr", 0, "ptr", 0, "int", 0, "int", CREATE_SUSPENDED := 4, "ptr", 0, "ptr", 0, "ptr", &StartupInfo, "ptr", &ProcessInfo)
DllCall("CloseHandle", Ptr, hThread := NumGet(ProcessInfo))
DllCall("CloseHandle", Ptr, hProcess := NumGet(&ProcessInfo + A_PtrSize))
PID := NumGet(&ProcessInfo + 2*A_PtrSize, "UInt")
rThread:=""
rThread:=InjectAhkDll(pid, AutoHotkeyDll,, 1)
h := DllCall("OpenProcess", "uint", PROCESS_ALL_ACCESS := 0x1F0FFF, "int", 0, "uint", PID, "ptr")
DllCall("ntdll.dll\NtResumeProcess", "ptr", h)
DllCall("CloseHandle", "ptr", h)
FileRead,HookScript, %HookFile%
rThread.Exec(HookScript)
return
InjectAhkDll(PID,dll:="AutoHotkey64.dll",script:=0, deleteThread := false)
{
static PROCESS_ALL_ACCESS:=0x1F0FFF,MEM_COMMIT := 0x1000,MEM_RELEASE:=0x8000,PAGE_EXECUTE_READWRITE:=64
,hKernel32:=DllCall("LoadLibrary","Str","kernel32.dll","PTR"),LoadLibraryA:=DllCall("GetProcAddress","PTR",hKernel32,"AStr","LoadLibraryA","PTR")
,FreeLibrary:=DllCall("GetProcAddress","PTR",hKernel32,"AStr","FreeLibrary","PTR")
,TH32CS_SNAPMODULE:=0x00000008,INVALID_HANDLE_VALUE:=-1
,MAX_PATH:=260,MAX_MODULE_NAME32:=255,ModuleName:="",init:=VarSetCapacity(ModuleName,MAX_PATH*(A_IsUnicode?2:1))
base:= deleteThread ? {__Call:"InjectAhkDll",__Delete:"InjectAhkDll"} : {__Call:"InjectAhkDll"}
if IsObject(PID)
{
if (dll!="Exec" && script)
return "Only Exec method can be used here!"
hProc := DllCall("OpenProcess", "UInt", PROCESS_ALL_ACCESS, "Int",0, "UInt", PID.PID,"PTR")
if !hProc
return "Could not open process for PID: " PID.PID
if (!script) ; Free Library in remote process (object is being deleted)
{
; Terminate the thread in ahkdll
hThread := DllCall("CreateRemoteThread", "PTR", hProc, "PTR", 0, "PTR", 0, "PTR", PID.ahkTerminate, "PTR", 0, "UInt", 0, "PTR", 0,"PTR")
DllCall("WaitForSingleObject", "PTR", hThread, "UInt", 0xFFFFFFFF)
,DllCall("CloseHandle", "PTR", hThread)
; Free library in remote process
hThread := DllCall("CreateRemoteThread", "PTR", hProc, "UInt", 0, "UInt", 0, "PTR", FreeLibrary, "PTR", PID.hModule, "UInt", 0, "UInt", 0,"PTR")
DllCall("WaitForSingleObject", "PTR", hThread, "UInt", 0xFFFFFFFF)
,DllCall("CloseHandle", "PTR", hThread),DllCall("CloseHandle", "PTR", hProc)
return
}
nScriptLength := VarSetCapacity(nScript, (StrLen(script)+1)*(A_IsUnicode?2:1), 0)
,StrPut(script,&nScript)
; Reserve memory in remote process where our script will be saved
if !pBufferRemote := DllCall("VirtualAllocEx", "Ptr", hProc, "Ptr", 0, "PTR", nScriptLength, "UInt", MEM_COMMIT, "UInt", PAGE_EXECUTE_READWRITE, "Ptr")
return "Could not reseve memory for process"
,DllCall("CloseHandle", "PTR", hProc)
; Write script to remote process memory
DllCall("WriteProcessMemory", "Ptr", hProc, "Ptr", pBufferRemote, "Ptr", &nScript, "PTR", nScriptLength, "Ptr", 0)
; Start execution of code
hThread := DllCall("CreateRemoteThread", "PTR", hProc, "PTR", 0, "PTR", 0, "PTR", PID.ahkExec, "PTR", pBufferRemote, "UInt", 0, "PTR", 0,"PTR")
if !hThread
{
DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nScriptLength,MEM_RELEASE)
,DllCall("CloseHandle", "PTR", hProc)
return "Could not execute script in remote process"
}
; Wait for thread to finish
DllCall("WaitForSingleObject", "PTR", hThread, "UInt", 0xFFFFFFFF)
; Get Exit code returned by ahkExec (1 = script could be executed / 0 = script could not be executed)
DllCall("GetExitCodeThread", "PTR", hThread, "UIntP", lpExitCode)
if !lpExitCode
return "Could not execute script in remote process"
DllCall("CloseHandle", "PTR", hThread)
,DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nScriptLength,MEM_RELEASE)
,DllCall("CloseHandle", "PTR", hProc)
return
}
else if !hDll:=DllCall("LoadLibrary","Str",dll,"PTR")
return "Could not find " dll " library", DllCall("CloseHandle", "PTR", hProc)
else
{
hProc := DllCall("OpenProcess","UInt", PROCESS_ALL_ACCESS, "Int",0,"UInt", DllCall("GetCurrentProcessId"),"PTR")
DllCall("GetModuleFileName","PTR",hDll,"PTR",&ModuleName,"UInt",MAX_PATH)
DllCall("CloseHandle","PTR",hProc)
}
; Open Process to PID
hProc := DllCall("OpenProcess", "UInt", PROCESS_ALL_ACCESS, "Int",0, "UInt", PID,"PTR")
if !hProc
return "Could not open process for PID: " PID
Loop, Files, %dll%, F
dll := A_LoopFileLongPath
; Reserve some memory and write dll path (ANSI)
nDirLength := VarSetCapacity(nDir, StrLen(dll)+1, 0)
,StrPut(dll,&nDir,"CP0")
; Reserve memory in remote process
if !pBufferRemote := DllCall("VirtualAllocEx", "Ptr", hProc, "Ptr", 0, "PTR", nDirLength, "UInt", MEM_COMMIT, "UInt", PAGE_EXECUTE_READWRITE, "Ptr")
return "Could not reseve memory for process", DllCall("CloseHandle", "PTR", hProc)
; Write dll path to remote process memory
DllCall("WriteProcessMemory", "Ptr", hProc, "Ptr", pBufferRemote, "Ptr", &nDir, "PTR", nDirLength, "Ptr", 0)
; Start new thread loading our dll
hThread:=DllCall("CreateRemoteThread","PTR",hProc,"PTR",0,"PTR",0,"PTR",LoadLibraryA,"PTR",pBufferRemote,"UInt",0,"PTR",0,"PTR")
if !hThread
{
DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nDirLength,"Uint",MEM_RELEASE)
,DllCall("CloseHandle", "PTR", hProc)
return "Could not load " dll " in remote process"
}
; Wait for thread to finish
DllCall("WaitForSingleObject", "PTR", hThread, "UInt", 0xFFFFFFFF)
; Get Exit code returned by thread (HMODULE for our dll)
DllCall("GetExitCodeThread", "PTR", hThread, "UInt*", hModule)
; Close Thread
DllCall("CloseHandle", "PTR", hThread)
if (A_PtrSize=8)
{ ; use different method to retrieve base address because GetExitCodeThread returns DWORD only
hModule:=0,VarSetCapacity(me32, (A_PtrSize=8?48:32)+(A_IsUnicode?1032:516), 0) ;W:1080:1064, A:564:548
; Take a snapshot of all modules in the specified process.
hModuleSnap := DllCall("CreateToolhelp32Snapshot","UInt", TH32CS_SNAPMODULE,"UInt", PID, "PTR" )
if ( hModuleSnap != INVALID_HANDLE_VALUE )
{
; reset hModule and set the size of the structure before using it.
NumPut((A_PtrSize=8?48:32)+(A_IsUnicode?1032:516), &me32, 0, "UInt") ;dwSize ;W:1080:1064, A:564:548
; Retrieve information about the first module,
; and exit if unsuccessful
if ( !DllCall("Module32First" (A_IsUnicode?"W":""),"PTR", hModuleSnap,"PTR", &me32 ) )
{
; Free memory used for passing dll path to remote thread
DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nDirLength,MEM_RELEASE)
,DllCall("CloseHandle","PTR", hModuleSnap ) ; Must clean up the snapshot object!
return false
}
; Now walk the module list of the process,and display information about each module
while(A_Index=1 || DllCall("Module32Next" (A_IsUnicode?"W":""),"PTR",hModuleSnap,"PTR", &me32 ) )
if (StrGet(&me32+(A_PtrSize=8?48:32)+(A_IsUnicode?512:256))=dll) ;szExePath ;W:560:544, A:304:288
{
hModule := NumGet(me32, A_PtrSize=8?40:28, "Ptr") ;hModule
break
}
DllCall("CloseHandle","PTR",hModuleSnap) ; clean up
}
}
hDll:=DllCall("LoadLibrary","Str",dll,"PTR")
; Calculate pointer to ahkdll and ahkExec functions
ahktextdll:=hModule+DllCall("GetProcAddress","PTR",hDll,"AStr","ahktextdll","PTR")-hDll
ahkExec:=hModule+DllCall("GetProcAddress","PTR",hDll,"AStr","ahkExec","PTR")-hDll
ahkTerminate:=hModule+DllCall("GetProcAddress","PTR",hDll,"AStr","ahkTerminate","PTR")-hDll
if script
{
nScriptLength := VarSetCapacity(nScript, (StrLen(script)+1)*(A_IsUnicode?2:1), 0)
,StrPut(script,&nScript)
; Reserve memory in remote process where our script will be saved
if !pBufferScript := DllCall("VirtualAllocEx", "Ptr", hProc, "Ptr", 0, "PTR", nScriptLength, "UInt", MEM_COMMIT, "UInt", PAGE_EXECUTE_READWRITE, "Ptr")
return "Could not reseve memory for process"
,DllCall("CloseHandle", "PTR", hProc)
; Write script to remote process memory
DllCall("WriteProcessMemory", "Ptr", hProc, "Ptr", pBufferScript, "Ptr", &nScript, "PTR", nScriptLength, "Ptr", 0)
}
else
pBufferScript:=0
; Run ahkdll function in remote thread
hThread := DllCall("CreateRemoteThread","PTR",hProc,"PTR",0,"PTR",0,"PTR",ahktextdll,"PTR",pBufferScript,"PTR",0,"UInt",0,"PTR")
if !hThread
{ ; could not start ahkdll in remote process
; Free memory used for passing dll path to remote thread
DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nDirLength,MEM_RELEASE)
DllCall("CloseHandle", "PTR", hProc)
return "Could not start ahkdll in remote process"
}
DllCall("WaitForSingleObject", "PTR", hThread, "UInt", 0xFFFFFFFF)
DllCall("GetExitCodeThread", "PTR", hThread, "UIntP", lpExitCode)
; Release memory and handles
DllCall("VirtualFreeEx","PTR",hProc,"PTR",pBufferRemote,"PTR",nDirLength,MEM_RELEASE)
DllCall("CloseHandle", "PTR", hThread)
DllCall("CloseHandle", "PTR", hProc)
if !lpExitCode ; thread could not be created.
return "Could not create a thread in remote process"
return {PID:PID,hModule:hModule,ahkExec:ahkExec,ahkTerminate:ahkTerminate,base:base}
}
minhook.ahk
В TargetWinTitle вписываем название окна запускаемой программы.
TargetWinTitle := "ahk_class gfx_test"
MinhookDll := "MinHook.dll"
Global FW1FontWrapperDll := "FW1FontWrapper.dll"
Global IDXGISwapChain_Present_Original, IDXGISwapChain_ResizeBuffers_Original, ResolutionChanged, widthChanged, heightChanged
array := {"MinHook.dll": MinhookDll, "FW1FontWrapper.dll": FW1FontWrapperDll}
For key, value in array
{
if !FileExist(value)
{
msgbox %value% does not exist
ExitApp
}
oFile := FileOpen(value, "r")
oFile.Seek(0x3c)
oFile.Seek(oFile.ReadInt()+4)
machineType := oFile.ReadUShort()
oFile.Close()
if (machineType = 0x14c) and (A_PtrSize = 8)
{
msgbox %key% 32 bit, but AutoHotkey.exe 64 bit
ExitApp
}
if ((machineType = 0x8664) or (machineType = 0x200)) and (A_PtrSize = 4)
{
msgbox %key% 64 bit, but AutoHotkey.exe 32 bit
ExitApp
}
}
WinWait, % TargetWinTitle
hwnd := WinExist(TargetWinTitle)
SetWorkingDir %A_ScriptDir%
LoadDll()
VarSetCapacity(SwapChainDesc, 48+A_PtrSize*3, 0)
NumPut(60, SwapChainDesc, 8, "uint") ; DXGI_MODE_DESC DXGI_RATIONAL Numerator
NumPut(1, SwapChainDesc, 12, "uint") ; DXGI_MODE_DESC DXGI_RATIONAL Denominator
NumPut(DXGI_FORMAT_R8G8B8A8_UNORM := 28, SwapChainDesc, 16, "uint") ; DXGI_MODE_DESC Format
NumPut(1, SwapChainDesc, 28, "uint") ; DXGI_SAMPLE_DESC count
NumPut(DXGI_USAGE_RENDER_TARGET_OUTPUT := 32, SwapChainDesc, 36, "uint") ; BufferUsage
NumPut(1, SwapChainDesc, 40, "uint") ; BufferCount
NumPut(hwnd, SwapChainDesc, 40+A_PtrSize, "ptr") ; OutputWindow
NumPut(1, SwapChainDesc, 40+2*A_PtrSize, "int") ; Windowed
NumPut(DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH := 2, SwapChainDesc, 48+2*A_PtrSize, "uint") ; Flags
VarSetCapacity(D3D_FEATURE_LEVEL, 4, 0)
NumPut(D3D_FEATURE_LEVEL_11_0 := 0xb000, D3D_FEATURE_LEVEL, 0, "uint")
D3D11CreateDeviceAndSwapChain(0, D3D_DRIVER_TYPE_HARDWARE := 1, 0, 0, &D3D_FEATURE_LEVEL, 1, D3D11_SDK_VERSION := 7, &SwapChainDesc, IDXGI_SwapChain, ID3D11Device, 0, ID3D11DeviceContext)
IDXGISwapChain_Present := IDXGISwapChain_Present_Get(IDXGI_SwapChain)
IDXGISwapChain_ResizeBuffers := IDXGISwapChain_ResizeBuffers_Get(IDXGI_SwapChain)
Release(IDXGI_SwapChain)
Release(ID3D11DeviceContext)
Release(ID3D11Device)
IDXGI_SwapChain := ID3D11DeviceContext := ID3D11Device := ""
MinHook_Init(MinhookDll)
MH_CreateHook(IDXGISwapChain_Present, RegisterCallback("IDXGISwapChain_Present_Hook", "F"), IDXGISwapChain_Present_Original)
MH_CreateHook(IDXGISwapChain_ResizeBuffers, RegisterCallback("IDXGISwapChain_ResizeBuffers_Hook", "F"), IDXGISwapChain_ResizeBuffers_Original)
MH_EnableHook()
return
IDXGISwapChain_Present_Hook(SwapChain, SyncInterval, Flags)
{
Critical
static Init, iFontWrapper, ImmediateContext, ResolutionOK, width, height
if (ResolutionChanged = 1)
ResolutionOk := ResolutionChanged := "", width := widthChanged, height := heightChanged
if (ResolutionOK = "")
{
if ImmediateContext
{
Release(ImmediateContext)
ImmediateContext := ""
}
IDXGISwapChain_GetDevice(SwapChain, ID3D11Device)
ID3D11Device_GetImmediateContext(ID3D11Device, ImmediateContext)
if (Init = "")
{
if (width = "")
{
VarSetCapacity(SwapChainDesc, 48+A_PtrSize*3, 0)
IDXGISwapChain_GetDesc(SwapChain, &SwapChainDesc)
width := NumGet(SwapChainDesc, 0, "uint")
height := NumGet(SwapChainDesc, 4, "uint")
}
FW1CreateFactory(pFW1Factory)
iFW1Factory := FW1Factory_Query(pFW1Factory)
IFW1Factory_CreateFontWrapper(iFW1Factory, ID3D11Device, "Arial", pFontWrapper)
iFontWrapper := FW1FontWrapper_Query(pFontWrapper)
ObjRelease(iFW1Factory)
iFW1Factory := ""
Init := 1
}
ResolutionOK := 1
}
IFW1FontWrapper_DrawString(iFontWrapper, ImmediateContext, "Hello, World!", width*0.1, width/2, height/2, 0xFFFFFFFF, 0x1|0x4|0x800) ; FW1_CENTER|FW1_VCENTER|FW1_RESTORESTATE
DllCall(IDXGISwapChain_Present_Original, "ptr", SwapChain, "uint", SyncInterval, "uint", Flags)
return
}
IDXGISwapChain_ResizeBuffers_Hook(SwapChain, BufferCount, SwapChainWidth, SwapChainHeight, NewFormatBuf, SwapChainFlags)
{
widthChanged := SwapChainWidth, heightChanged := SwapChainHeight
ResolutionChanged := 1
DllCall(IDXGISwapChain_ResizeBuffers_Original, "ptr", SwapChain, "uint", BufferCount, "uint", SwapChainWidth, "uint", SwapChainHeight, "uint", NewFormatBuf, "uint", SwapChainFlags)
return
}
LoadDll()
{
if !DllCall("GetModuleHandle","str","DXGI", "ptr")
{
MsgBox, 16, Error, DXGI failed.
ExitApp
}
if !DllCall("GetModuleHandle","str","D3D11", "ptr")
{
MsgBox, 16, Error, D3D11 failed.
ExitApp
}
if !DllCall("GetModuleHandle","str","FW1FontWrapper")
DllCall("LoadLibrary","Str", FW1FontWrapperDll, "ptr")
return
}
FW1CreateFactory(ByRef ppFactory)
{
hr := DllCall(FW1FontWrapperDll "\FW1CreateFactory", "uint", FW1_VERSION := 0x110f, "ptr*", ppFactory)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
FW1Factory_Query(pFactory)
{
hr := ComObjQuery(pFactory, "{8004DB2B-B5F9-4420-A6A2-E17E15E4C336}")
if !hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
return hr
}
IFW1Factory_CreateFontWrapper(this, pDevice, pszFontFamily, ByRef ppFontWrapper)
{
hr := DllCall(NumGet(NumGet(this+0)+5*A_PtrSize), "ptr", this, "ptr", pDevice, "str", pszFontFamily, "ptr*", ppFontWrapper)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
FW1FontWrapper_Query(pFontWrapper)
{
hr := ComObjQuery(pFontWrapper, "{83347A5C-B0B1-460e-A35C-427E8B85F9F4}")
if !hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
return hr
}
IFW1FontWrapper_DrawString(this, pContext, pszString, FontSize, X, Y, Color, Flags)
{
hr := DllCall(NumGet(NumGet(this+0)+14*A_PtrSize), "ptr", this, "ptr", pContext, "str", pszString, "float", FontSize, "float", X, "float", Y, "uint", Color, "uint", Flags)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
D3D11CreateDeviceAndSwapChain(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, SwapChainDesc, ByRef ppSwapChain, ByRef ppDevice, pFeatureLevel, ByRef ppImmediateContext)
{
hr := DllCall("D3D11\D3D11CreateDeviceAndSwapChain", "ptr", pAdapter, "int", DriverType, "ptr", Software, "uint", Flags, "ptr", pFeatureLevels, "uint", FeatureLevels, "uint", SDKVersion, "ptr", SwapChainDesc, "ptr*", ppSwapChain, "ptr*", ppDevice, "ptr", pFeatureLevel, "ptr*", ppImmediateContext)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDXGISwapChain_GetDevice(this, ByRef ppDevice)
{
GUID(riid, "{db6f6ddb-ac77-4e88-8253-819df9bbf140}")
hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "ptr", &riid, "ptr*", ppDevice)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
ID3D11Device_GetImmediateContext(this, ByRef ppImmediateContext)
{
DllCall(NumGet(NumGet(this+0)+40*A_PtrSize), "ptr", this, "ptr*", ppImmediateContext)
if ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDXGISwapChain_GetDesc(this, pDesc)
{
hr := DllCall(NumGet(NumGet(this+0)+12*A_PtrSize), "ptr", this, "ptr", pDesc)
if hr or ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
IDXGISwapChain_Present_Get(this)
{
return NumGet(NumGet(this+0)+8*A_PtrSize)
}
IDXGISwapChain_ResizeBuffers_Get(this)
{
return NumGet(NumGet(this+0)+13*A_PtrSize)
}
Release(this)
{
DllCall(NumGet(NumGet(this+0)+2*A_PtrSize), "ptr", this)
if ErrorLevel
_Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}
GUID(ByRef GUID, sGUID)
{
VarSetCapacity(GUID, 16, 0)
return DllCall("ole32\CLSIDFromString", "WStr", sGUID, "Ptr", &GUID) >= 0 ? &GUID : ""
}
_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)
}
Так как в DirectX11 отсутствует поддержка Direct2D / Fonts, то можно использовать FW1FontWrapper библиотеку, что я и сделал.
dll и саму программу прикрепил в приложении.
Тема для обсуждения