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

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

CreateFontIndirect 函数的定义

 CreateFontIndirect是Windows API中的一个函数,用于创建具有指定特征的逻辑字体,它允许程序精确地控制字体的各个方面。

函数原型:

HFONT CreateFontIndirect(
  CONST LOGFONT *lplf
);

参数:

  • lplf:指向LOGFONT结构的指针,该结构包含了新字体的属性。

返回值:

  • 如果函数成功,返回值是新创建的字体的句柄(HFONT)。
  • 如果函数失败,返回值是NULL。

这里我们其实关注的不是CreateFontIndirect函数而是他指向的这个LOGFONT结构。所以,我们下面来讲解一下LOGFONT。其实LOGFONT在之前介绍CreateFontA也出现过了。他们的结构是一模一样的。

LOGFONT结构

  1. lfHeight (0x00):
    • 定义字体的高度(单位是逻辑单位)。
    • 正值表示字符单元格高度,负值表示字符高度。
    • 设为0时,使用默认高度。
  2. lfWidth (0x04):
    • 定义字体的平均字符宽度。
    • 通常设为0,让系统根据lfHeight选择最佳宽度。
  3. lfEscapement (0x08):
    • 定义整个字符串的旋转角度,以0.1度为单位。
    • 例如,900表示90度旋转。
  4. lfOrientation (0x0C):
    • 定义每个字符的旋转角度,以0.1度为单位。
    • 通常与lfEscapement相同。
  5. lfWeight (0x10):
    • 定义字体的粗细,范围从0到1000。
    • 常用值:FW_NORMAL (400), FW_BOLD (700)。
  6. lfItalic (0x14):
    • 布尔值,指定字体是否为斜体。
  7. lfUnderline (0x15):
    • 布尔值,指定字体是否有下划线。
  8. lfStrikeOut (0x16):
    • 布尔值,指定字体是否有删除线。
  9. lfCharSet (0x17):
    • 指定字符集,如ANSI_CHARSET, DEFAULT_CHARSET等。
  10. lfOutPrecision (0x18):
    • 指定输出精度,影响Windows如何选择匹配字体。
  11. lfClipPrecision (0x19):
    • 指定裁剪精度,影响字符超出裁剪区域时的处理方式。
  12. lfQuality (0x1A):
    • 指定输出质量,影响字体渲染方式。
  13. lfPitchAndFamily (0x1B):
    • 低4位指定字体间距(FIXED_PITCH, VARIABLE_PITCH等)。
    • 高4位指定字体族(FF_DONTCARE, FF_ROMAN, FF_SWISS等)。
  14. 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

1 2 3

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

请登录后发表评论

    暂无评论内容