CreateFontIndirect 函数的定义
函数原型:
HFONT CreateFontIndirect(
CONST LOGFONT *lplf
);
参数:
lplf:指向LOGFONT结构的指针,该结构包含了新字体的属性。
返回值:
如果函数成功,返回值是新创建的字体的句柄(HFONT)。 如果函数失败,返回值是NULL。
LOGFONT结构
- lfHeight (0x00):
定义字体的高度(单位是逻辑单位)。 正值表示字符单元格高度,负值表示字符高度。 设为0时,使用默认高度。
- lfWidth (0x04):
定义字体的平均字符宽度。 通常设为0,让系统根据lfHeight选择最佳宽度。
- lfEscapement (0x08):
定义整个字符串的旋转角度,以0.1度为单位。 例如,900表示90度旋转。
- lfOrientation (0x0C):
定义每个字符的旋转角度,以0.1度为单位。 通常与lfEscapement相同。
- lfWeight (0x10):
定义字体的粗细,范围从0到1000。 常用值:FW_NORMAL (400), FW_BOLD (700)。
- lfItalic (0x14):
布尔值,指定字体是否为斜体。
- lfUnderline (0x15):
布尔值,指定字体是否有下划线。
- lfStrikeOut (0x16):
布尔值,指定字体是否有删除线。
- lfCharSet (0x17):
指定字符集,如ANSI_CHARSET, DEFAULT_CHARSET等。
- lfOutPrecision (0x18):
指定输出精度,影响Windows如何选择匹配字体。
- lfClipPrecision (0x19):
指定裁剪精度,影响字符超出裁剪区域时的处理方式。
- lfQuality (0x1A):
指定输出质量,影响字体渲染方式。
- lfPitchAndFamily (0x1B):
低4位指定字体间距(FIXED_PITCH, VARIABLE_PITCH等)。 高4位指定字体族(FF_DONTCARE, FF_ROMAN, FF_SWISS等)。
- lfFaceName (0x1C):
字体名称,如”MSゴシック”、”MS Gothic”等。 最多可包含32个宽字符(包括结尾的null字符)。
代码结构
typedef struct tagLOGFONT {
LONG lfHeight; // 偏移: 0x00 - 字体高度(逻辑单位)
LONG lfWidth; // 偏移: 0x04 - 字体宽度(通常设为0让系统选择最佳宽度)
LONG lfEscapement; // 偏移: 0x08 - 字符串的旋转角度(0.1度为单位)
LONG lfOrientation; // 偏移: 0x0C - 每个字符的旋转角度(0.1度为单位)
LONG lfWeight; // 偏移: 0x10 - 字体粗细(0-1000,400为正常)
BYTE lfItalic; // 偏移: 0x14 - 是否斜体(TRUE或FALSE)
BYTE lfUnderline; // 偏移: 0x15 - 是否有下划线(TRUE或FALSE)
BYTE lfStrikeOut; // 偏移: 0x16 - 是否有删除线(TRUE或FALSE)
BYTE lfCharSet; // 偏移: 0x17 - 字符集(如ANSI_CHARSET, DEFAULT_CHARSET等)
BYTE lfOutPrecision; // 偏移: 0x18 - 输出精度
BYTE lfClipPrecision; // 偏移: 0x19 - 裁剪精度
BYTE lfQuality; // 偏移: 0x1A - 输出质量
BYTE lfPitchAndFamily;// 偏移: 0x1B - 字体间距和字体族
WCHAR lfFaceName[LF_FACESIZE]; // 偏移: 0x1C - 字体名称(最多32个宽字符)
} LOGFONT, *PLOGFONT;
// 注:LF_FACESIZE 通常定义为 32
HOOK代码示例
#include <windows.h>
#include <detours.h>
// 原始的CreateFontIndirect函数指针
static HFONT (WINAPI *TrueCreateFontIndirect)(CONST LOGFONT *lplf) = CreateFontIndirect;
// 我们的hook函数
HFONT WINAPI HookedCreateFontIndirect(CONST LOGFONT *lplf)
{
// 创建一个新的LOGFONT结构,复制原始结构的内容
LOGFONT newLogFont;
if (lplf)
memcpy(&newLogFont, lplf, sizeof(LOGFONT));
else
ZeroMemory(&newLogFont, sizeof(LOGFONT));
// 修改字符集为中文
newLogFont.lfCharSet = GB2312_CHARSET; // 使用GB2312字符集(简体中文)
// 修改字体为宋体
wcscpy_s(newLogFont.lfFaceName, LF_FACESIZE, L"宋体");
// 调用原始函数,但使用我们修改过的LOGFONT结构
return TrueCreateFontIndirect(&newLogFont);
}
// DLL主函数
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
{
if (DetourIsHelperProcess()) {
return TRUE;
}
if (dwReason == DLL_PROCESS_ATTACH) {
DetourRestoreAfterWith();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueCreateFontIndirect, HookedCreateFontIndirect);
LONG error = DetourTransactionCommit();
if (error == NO_ERROR) {
OutputDebugString(L"CreateFontIndirect hooked successfully.");
} else {
OutputDebugString(L"Error hooking CreateFontIndirect");
}
}
else if (dwReason == DLL_PROCESS_DETACH) {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)TrueCreateFontIndirect, HookedCreateFontIndirect);
DetourTransactionCommit();
}
return TRUE;
}
举个例子
![图片[1]-【WIN32/逆向】游戏创建字体的三大函数。CreateFont、CreateFontIndirect和CreateFontIndirectEx。-galgame](https://image.sweetkxq.top/sweet/x32dbg/LOGFONT.png)
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容