Hello,
I would like to intercept DrawText calls in my game. Is it something that inner space can help me with or should I find another way ?
Intercepting directx DrawText calls
Moderators: Lavish Software Team, Moderators
There actually isnt a Direct3D DrawText function. Assuming the game uses D3DX, it would use the gdi32 ExtTextOutA/ExtTextOutW, but there's no guarantee of that. A lot of games use their own routines, some even use maps of textures for fonts. But, you can certainly try using a detour of ExtTextOutA and ExtTextOutW in an extension.
Code: Select all
EzDetour(ExtTextOutA,ExtTextOutA_detour,ExtTextOutA_trampoline);
Lax, I really appreciate your prompt response.Lax wrote:There actually isnt a Direct3D DrawText function. Assuming the game uses D3DX, it would use the gdi32 ExtTextOutA/ExtTextOutW, but there's no guarantee of that. A lot of games use their own routines, some even use maps of textures for fonts. But, you can certainly try using a detour of ExtTextOutA and ExtTextOutW in an extension.
Code: Select all
EzDetour(ExtTextOutA,ExtTextOutA_detour,ExtTextOutA_trampoline);
Is there any documentation/sample how to use it ? I tried to search wiki but has not found anything about it.
What is exactly trampoline in this case ? I thought a trampoline would be automatically generated for me ? So if I need to supply it myself how to go about writing it ?
Thanks
Well, I didn't want to do all the work for you 

Code: Select all
DETOUR_TRAMPOLINE_EMPTY(BOOL WINAPI ExtTextOutA_tramopline(
HDC hdc, // handle to DC
int X, // x-coordinate of reference point
int Y, // y-coordinate of reference point
UINT fuOptions, // text-output options
CONST RECT* lprc, // optional dimensions
LPCTSTR lpString, // string
UINT cbCount, // number of characters in string
CONST INT* lpDx // array of spacing values
));
BOOL WINAPI ExtTextOutA_detour(
HDC hdc, // handle to DC
int X, // x-coordinate of reference point
int Y, // y-coordinate of reference point
UINT fuOptions, // text-output options
CONST RECT* lprc, // optional dimensions
LPCTSTR lpString, // string
UINT cbCount, // number of characters in string
CONST INT* lpDx // array of spacing values
)
{
// do any stuff you want to do during the intercept
printf("ExtTextOutA(%s)",lpString);
// call the trampoline with the original data (or your own data, but original here)
return ExtTextOutA_trampoline(hdc,X,Y,fuOptions,lprc,lpString,cbCount,lpDx);
}
Thx a lot Lax. It worked. As i am struggling to learn c++ every bit of working code helps a lot.Lax wrote:Well, I didn't want to do all the work for you![]()
As you expected my game does not use this call for rendering its ingame text. I know that interception worked because i got echo of some inner space text on the console.
That brings a couple more questions. Is there any other standard way of outputting text in games ? i found this reference in msdn:
ID3DXFont::DrawText
http://msdn.microsoft.com/archive/defau ... awText.asp
Any chance to intercept this call also in a similar way to ExtTextOut ?
Is there any tool that shows directx call made by an app ?
That is the call used by ID3DXFont::DrawTextA. ID3DXFont::DrawTextW uses ExtTextOutW, which you should try instead of A since it didnt work for the game you're trying. There are two versions of every text-related function in Windows, one uses ANSI encoding (A is for ANSI) and the other uses unicode (W is for Wide, as in unicode).
Try this instead.
Try this instead.
Code: Select all
DETOUR_TRAMPOLINE_EMPTY(BOOL WINAPI ExtTextOutW_tramopline(
HDC hdc, // handle to DC
int X, // x-coordinate of reference point
int Y, // y-coordinate of reference point
UINT fuOptions, // text-output options
CONST RECT* lprc, // optional dimensions
LPCWSTR lpString, // string
UINT cbCount, // number of characters in string
CONST INT* lpDx // array of spacing values
));
BOOL WINAPI ExtTextOutW_detour(
HDC hdc, // handle to DC
int X, // x-coordinate of reference point
int Y, // y-coordinate of reference point
UINT fuOptions, // text-output options
CONST RECT* lprc, // optional dimensions
LPCWSTR lpString, // string
UINT cbCount, // number of characters in string
CONST INT* lpDx // array of spacing values
)
{
// do any stuff you want to do during the intercept
printf("ExtTextOutW(%S)",lpString);
// call the trampoline with the original data (or your own data, but original here)
return ExtTextOutW_trampoline(hdc,X,Y,fuOptions,lprc,lpString,cbCount,lpDx);
}
Thx again Lax, unicode version does not work either. Seems the game uses their own custom way for drawing text.Lax wrote:That is the call used by ID3DXFont::DrawTextA. ID3DXFont::DrawTextW uses ExtTextOutW, which you should try instead of A since it didnt work for the game you're trying. There are two versions of every text-related function in Windows, one uses ANSI encoding (A is for ANSI) and the other uses unicode (W is for Wide, as in unicode).