CreateFont 函数的定义
CreateFont 函数创建具有指定特征的逻辑字体。 随后可以选择逻辑字体作为任何设备的字体。
其中他有两个版本。一个是A版本一个是W版本
CreateFontA 和 CreateFontW
两个函数的差别:
CreateFontA
CreateFontA 是 ANSI 版本的创建字体函数。它使用 ANSI 字符集来处理字符串参数。
HFONT CreateFontA(
int nHeight,
int nWidth,
int nEscapement,
int nOrientation,
int fnWeight,
DWORD fdwItalic,
DWORD fdwUnderline,
DWORD fdwStrikeOut,
DWORD fdwCharSet,
DWORD fdwOutputPrecision,
DWORD fdwClipPrecision,
DWORD fdwQuality,
DWORD fdwPitchAndFamily,
LPCSTR lpszFace
);
CreateFontW
CreateFontW 是 Unicode 版本的创建字体函数。它使用 Unicode 字符集来处理字符串参数。
HFONT CreateFontW(
int nHeight,
int nWidth,
int nEscapement,
int nOrientation,
int fnWeight,
DWORD fdwItalic,
DWORD fdwUnderline,
DWORD fdwStrikeOut,
DWORD fdwCharSet,
DWORD fdwOutputPrecision,
DWORD fdwClipPrecision,
DWORD fdwQuality,
DWORD fdwPitchAndFamily,
LPCWSTR lpszFace
);
重点参数——字符集参数()
以下是字符集参数所对应的语言和十进制值:
- ANSI_CHARSET (0): 西欧语言
- BALTIC_CHARSET (186): 波罗的海语言
- CHINESEBIG5_CHARSET (136): 繁体中文
- DEFAULT_CHARSET (1): 系统默认字符集
- EASTEUROPE_CHARSET (238): 东欧语言
- GB2312_CHARSET (134): 简体中文
- GREEK_CHARSET (161): 希腊语
- HANGUL_CHARSET (129): 韩语
- MAC_CHARSET (77): Macintosh 字符集
- OEM_CHARSET (255): OEM 字符集
- RUSSIAN_CHARSET (204): 俄语
- SHIFTJIS_CHARSET (128): 日语
- SYMBOL_CHARSET (2): 符号
- TURKISH_CHARSET (162): 土耳其语
- VIETNAMESE_CHARSET (163): 越南语
- JOHAB_CHARSET (130): 朝鲜语 (Johab)
- ARABIC_CHARSET (178): 阿拉伯语
- HEBREW_CHARSET (177): 希伯来语
- THAI_CHARSET (222): 泰语
操作系统中可能存在具有其他字符集的字体。 如果应用程序使用字符集未知的字体,则不应尝试翻译或解释使用该字体呈现的字符串。
为确保创建字体时的结果一致,请不要指定OEM_CHARSET或DEFAULT_CHARSET。 如果在
HOOK代码示例
#include <windows.h>
#include <detours.h>
// 原始的CreateFontA函数指针
static HFONT (WINAPI *TrueCreateFontA)(
int nHeight, // +0x00 字体高度
int nWidth, // +0x04 字体宽度
int nEscapement, // +0x08 字符串的角度(单位:十分之一度)
int nOrientation, // +0x0C 每个字符的角度(单位:十分之一度)
int fnWeight, // +0x10 字体粗细(范围:0-1000)
DWORD fdwItalic, // +0x14 是否斜体
DWORD fdwUnderline, // +0x18 是否下划线
DWORD fdwStrikeOut, // +0x1C 是否删除线
DWORD fdwCharSet, // +0x20 字符集
DWORD fdwOutputPrecision, // +0x24 输出精度
DWORD fdwClipPrecision, // +0x28 裁剪精度
DWORD fdwQuality, // +0x2C 输出质量
DWORD fdwPitchAndFamily, // +0x30 字体间距和族
LPCWSTR lpszFace // +0x34 字体名称(Unicode字符串)
) = CreateFontA;
// Hook后的CreateFontA函数
HFONT WINAPI HookedCreateFontA(
int nHeight,
int nWidth,
int nEscapement,
int nOrientation,
int fnWeight,
DWORD fdwItalic,
DWORD fdwUnderline,
DWORD fdwStrikeOut,
DWORD fdwCharSet,
DWORD fdwOutputPrecision,
DWORD fdwClipPrecision,
DWORD fdwQuality,
DWORD fdwPitchAndFamily,
LPCSTR lpszFace
)
{
// 修改字符集为中文
fdwCharSet = CHINESEBIG5_CHARSET;
// 修改字体为宋体
lpszFace = "宋体";
// 调用原始的CreateFontA函数
return TrueCreateFontA(
nHeight,
nWidth,
nEscapement,
nOrientation,
fnWeight,
fdwItalic,
fdwUnderline,
fdwStrikeOut,
fdwCharSet,
fdwOutputPrecision,
fdwClipPrecision,
fdwQuality,
fdwPitchAndFamily,
lpszFace
);
}
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
{
if (DetourIsHelperProcess()) {
return TRUE;
}
if (dwReason == DLL_PROCESS_ATTACH) {
DetourRestoreAfterWith();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueCreateFontA, HookedCreateFontA);
LONG error = DetourTransactionCommit();
if (error == NO_ERROR) {
OutputDebugString("Successfully hooked CreateFontA");
} else {
OutputDebugString("Failed to hook CreateFontA");
}
} else if (dwReason == DLL_PROCESS_DETACH) {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)TrueCreateFontA, HookedCreateFontA);
DetourTransactionCommit();
}
return TRUE;
}
举个例子
![图片[1]-【WIN32/逆向】游戏创建字体的三大函数。CreateFont、CreateFontIndirect和CreateFontIndirectEx。-galgame](https://image.sweetkxq.top/sweet/x32dbg/createfonta.png)
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容