【WIN32/逆向】游戏创建字体的三大函数。CreateFont、CreateFontIndirect和CreateFontIndirectEx。

共计9088字,阅读大约31分钟。

CreateFont 函数的定义

CreateFont 函数创建具有指定特征的逻辑字体。 随后可以选择逻辑字体作为任何设备的字体。

其中他有两个版本。一个是A版本一个是W版本

CreateFontA 和 CreateFontW

两个函数的差别:

  1. 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
);
  1. 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
);

重点参数——字符集参数()

以下是字符集参数所对应的语言和十进制值:

  1. ANSI_CHARSET (0): 西欧语言
  2. BALTIC_CHARSET (186): 波罗的海语言
  3. CHINESEBIG5_CHARSET (136): 繁体中文
  4. DEFAULT_CHARSET (1): 系统默认字符集
  5. EASTEUROPE_CHARSET (238): 东欧语言
  6. GB2312_CHARSET (134): 简体中文
  7. GREEK_CHARSET (161): 希腊语
  8. HANGUL_CHARSET (129): 韩语
  9. MAC_CHARSET (77): Macintosh 字符集
  10. OEM_CHARSET (255): OEM 字符集
  11. RUSSIAN_CHARSET (204): 俄语
  12. SHIFTJIS_CHARSET (128): 日语
  13. SYMBOL_CHARSET (2): 符号
  14. TURKISH_CHARSET (162): 土耳其语
  15. VIETNAMESE_CHARSET (163): 越南语
  16. JOHAB_CHARSET (130): 朝鲜语 (Johab)
  17. ARABIC_CHARSET (178): 阿拉伯语
  18. HEBREW_CHARSET (177): 希伯来语
  19. THAI_CHARSET (222): 泰语

OEM_CHARSET值指定依赖于操作系统的字符集。

DEFAULT_CHARSET根据当前系统区域设置设置为值。 例如,当系统区域设置为英语 (美国) 时,它将设置为ANSI_CHARSET。

操作系统中可能存在具有其他字符集的字体。 如果应用程序使用字符集未知的字体,则不应尝试翻译或解释使用该字体呈现的字符串。

为确保创建字体时的结果一致,请不要指定OEM_CHARSET或DEFAULT_CHARSET。 如果在 lpszFace 参数中指定字体名称,请确保 fdwCharSet 值与 lpszFace 中指定的字体的字符集匹配。(也就是说,你不要拿一个中文GB2312_CHARSET字符集去匹配日语的MSゴシック字体。)

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

1 2 3

温馨提示:
本文最后更新于2024-07-20 14:52:49,本文具有时效性,若有错误或已失效,请在下方留言或联系站长
© 版权声明
THE END
喜欢就支持一下吧
点赞11 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容