从字体文件中获取字体名字

JS逆向系列之猿人学爬虫第7题-动态字体,随风漂移 阅读详情

Introduction

Everyone can get a font name of one of installed fonts. But what if the font is still not installed in the system and you want to know what is that, programmatically? Of course you can temporary add it to system fonts and get its properties then (hmm... but how you will find now what was the font installed?). Well, maybe you can think about other ways, but I decided to look for specification of the TrueType and OpenType fonts file. Fortunately, Microsoft has very good articles on these files. If you want to know more about them, look at the end of this article for links.

Writing the code

Since all that interested me (and you in most cases) is only the font name and not other properties in the TTF file, our code is gonna be simple (actually only one function). The function will retrieve font name from given file and return it to calling program.

Data types definition

Since there is no structures defined in Windows header files (or I didn't find them), we gonna make our own. We need 4 structures and 2 macros (I will explain later, about them).

A TTF file consists of several tables, each table represent some data, regarding of its type. Some tables are required, some are not. We actually need only one of them, called "name", e.g. names table. This is the place where the font information is stored, like font name, copyright, trademark and more.

//This is TTF file header
typedef struct _tagTT_OFFSET_TABLE{
    USHORT uMajorVersion;
    USHORT uMinorVersion;
    USHORT uNumOfTables;
    USHORT uSearchRange;
    USHORT uEntrySelector;
    USHORT uRangeShift;
}TT_OFFSET_TABLE;

//Tables in TTF file and there placement and name (tag)
typedef struct _tagTT_TABLE_DIRECTORY{
    char szTag[4]; //table name
    ULONG uCheckSum; //Check sum
    ULONG uOffset; //Offset from beginning of file
    ULONG uLength; //length of the table in bytes
}TT_TABLE_DIRECTORY;

//Header of names table
typedef struct _tagTT_NAME_TABLE_HEADER{
    USHORT uFSelector; //format selector. Always 0
    USHORT uNRCount; //Name Records count
    USHORT uStorageOffset; //Offset for strings storage, 
                           //from start of the table
}TT_NAME_TABLE_HEADER;

//Record in names table
typedef struct _tagTT_NAME_RECORD{
    USHORT uPlatformID;
    USHORT uEncodingID;
    USHORT uLanguageID;
    USHORT uNameID;
    USHORT uStringLength;
    USHORT uStringOffset; //from start of storage area
}TT_NAME_RECORD;
Macros

Now only thing left is macros I was talking before. The macros definition looks like:

#define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)))

Now what is that? The reason we need those macros is that TTF files are stored in Big-Endian format, unlike in Windows systems, where all files are in Little Endian. Yeah I know it sounds silly with all those "endians" Smile | :) . Big Endian is used by Motorolla processors for example, where the higher byte is stored first, while in Little Endian (for Intel processors) the higher byte is the last. For example you have an integer variable 1 (which is 4 bytes long). Try to save it to file and open in any hexadecimal editor, you will see:

01 00 00 00    //Little Endian - Intel

This is Little Endian system (Intel). But for Big-Endian (Motorolla), the number will be stored vise versa:

00 00 00 01    //Big Endian - Motorolla

So these formats are incompatible. And TTF file as I said, is stored in Motorolla style (Big Endian). That's why we need those 2 macros to rearrange bytes in variables retrieved from TrueType font file.

Reading the file

Now we are prepared to read the TTF file. So let's get started.

First of all we need to read the file header (TT_OFFSET_TABLE structure):

CFile f;
CString csRetVal;

//lpszFilePath is the path to our font file
if(f.Open(lpszFilePath, CFile::modeRead|CFile::shareDenyWrite)){

    //define and read file header
    TT_OFFSET_TABLE ttOffsetTable;
    f.Read(&ttOffsetTable, sizeof(TT_OFFSET_TABLE));

    //remember to rearrange bytes in the field you gonna use
    ttOffsetTable.uNumOfTables = SWAPWORD(ttOffsetTable.uNumOfTables);
    ttOffsetTable.uMajorVersion = SWAPWORD(ttOffsetTable.uMajorVersion);
    ttOffsetTable.uMinorVersion = SWAPWORD(ttOffsetTable.uMinorVersion);

    //check is this is a true type font and the version is 1.0
    if(ttOffsetTable.uMajorVersion != 1 || ttOffsetTable.uMinorVersion != 0)
        return csRetVal;

Right after the file header goes Offsets Table. You can find here an offset to interesting you table, "name" in our case.

    TT_TABLE_DIRECTORY tblDir;
    BOOL bFound = FALSE;
    CString csTemp;

    for(int i=0; i< ttOffsetTable.uNumOfTables; i++){
        f.Read(&tblDir, sizeof(TT_TABLE_DIRECTORY));
        csTemp.Empty();

        //table's tag cannot exceed 4 characters
        strncpy(csTemp.GetBuffer(4), tblDir.szTag, 4);
        csTemp.ReleaseBuffer();
        if(csTemp.CompareNoCase(_T("name")) == 0){
            //we found our table. Rearrange order and quit the loop
            bFound = TRUE;
            tblDir.uLength = SWAPLONG(tblDir.uLength);
            tblDir.uOffset = SWAPLONG(tblDir.uOffset);
            break;
        }
    }

We finally found the names table, so let's read its header:

    if(bFound){
        //move to offset we got from Offsets Table
        f.Seek(tblDir.uOffset, CFile::begin);
        TT_NAME_TABLE_HEADER ttNTHeader;
        f.Read(&ttNTHeader, sizeof(TT_NAME_TABLE_HEADER));

        //again, don't forget to swap bytes!
        ttNTHeader.uNRCount = SWAPWORD(ttNTHeader.uNRCount);
        ttNTHeader.uStorageOffset = SWAPWORD(ttNTHeader.uStorageOffset);
        TT_NAME_RECORD ttRecord;
        bFound = FALSE;

Right after the Names Table header, go records in it. So we need to run through all records to find information interesting to us - font name.

    for(int i=0; i<ttNTHeader.uNRCount; i++){
    f.Read(&ttRecord, sizeof(TT_NAME_RECORD));
    ttRecord.uNameID = SWAPWORD(ttRecord.uNameID);

    //1 says that this is font name. 0 for example determines copyright info
    if(ttRecord.uNameID == 1){
        ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength);
        ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset);

        //save file position, so we can return to continue with search
        int nPos = f.GetPosition();
        f.Seek(tblDir.uOffset + ttRecord.uStringOffset + 
                 ttNTHeader.uStorageOffset, CFile::begin);

        //bug fix: see the post by SimonSays to read more about it
        TCHAR lpszNameBuf = csTemp.GetBuffer(ttRecord.uStringLength + 1);
        ZeroMemory(lpszNameBuf, ttRecord.uStringLength + 1);
        f.Read(lpszNameBuf, ttRecord.uStringLength);
        csTemp.ReleaseBuffer();

        //yes, still need to check if the font name is not empty
        //if it is, continue the search
        if(csTemp.GetLength() > 0){
            csRetVal = csTemp;
            break;
        }
        f.Seek(nPos, CFile::begin);
    }
}

That's all! Now we can return csRetVal containing our font name.

You can download the full working function and use in your code. I included also a demo project with same function, but customized a bit, so it returned also copyright and trademark information.

If you want to continue with TTF files, you can look at Microsoft's specification on them. But remember that deeper you are going to TTF, more differences between TrueType and OpenType you may find. Anyway, below are the links to articles about TTF.


【CVPR 2025】低光增强HVI论文精读与源码复现---part1 论文网络精读 【CVPR 2025】本文参考论文HVI: A New Color Space for Low-light Image Enhancement part1 在文章中对论文核心网络与原理展开详细解释 part2 对论文公开代码的arch网络与其他核心部分展开详细解释 阅读详情

相关推荐

iOS Certificates, Identifiers & Profiles简介

1. Certificates Certificates是生成开发和生产所需的证书。 2.1 certSigningRequest文件 生成证书前,需要先生成certSigningRequest文件,certSigningRequest文件由【钥匙串访问】生成。 选择菜单【钥匙串访问】,【证书助理】下的【从证书颁发机构请求证书…】 填写【用户电子邮件地址: 】,将【请求是:】的选项改为【储存到磁盘】 输入certSigningRequest文件的文件名,并指定保存位置。 保存certSignin

假装你是大灰狼的专栏 7059

获取TrueType字体信息

引言对TrueType字体有一定了解的人,相信一定对Windows中Fonts文件夹中中文字体文件显示的名字感到好奇。将中文字体复制到该目录下显示的是中文字体名,而将该字体复制到其它位置则没有享受到该待遇变成一串英文了,该文将讲述该实现背后的秘密。TrueType字体格式说明TrueType字体有一个文件头和很多表组成,具体结构如下所示: > TrueType Header信息 + N个表头信息

kwfly的专栏 8649

Mac 环境配置jdk、Maven

3、终端打开配置jdk时候建好的脚本文件: open -e .bash_profile。4、查看maven是否安装成功和系统能不能识别maven/mvn命令:⬇️。输入⬇️并保存: 其中第一行JAVA_HOME替换为自己下的jdk路径。,安装编译好的二进制版本,具体安装zip还是tar.gz我看的。5、查看jdk是否安装成功和系统能不能识别java命令:⬇️。至此,我的Mac系统的环境配置jdk、Maven完成!然后就发现我的maven命令还是没作用,不识别,下载后直接安装即可,很快,点几下就OK了。

weixin_42416791的博客 4409

获取TTF文件的字体名

//========================================================================//TITLE://    获取TTF文件的字体名//AUTHOR://    norains//DATE://    Monday 22-December-2008//Environment://    VS2005 + ARM BSP//=====

norains的专栏 8919

OpenClaw 完整部署教程

版本:OpenClaw 2026.2.13更新日期:2026-02-26适用系统:Linux (Ubuntu/Debian/CentOS)

qq_39436086的博客 2318

从开源到落地:SimpleBGC 三轴稳像平台全栈技术解析(上)

SimpleBGC是一款开源的稳定云台控制系统,相比专业设备具有显著的价格优势(仅为1/5-1/10),采用模块化设计支持全场景适配。系统包含硬件设计、软件代码和算法三大核心:硬件采用STM32主控和IMU传感器,支持6步换向和FOC电机驱动;软件采用三层架构(驱动层、算法层、应用层),实现姿态解算和PID控制;算法方面提供互补滤波(基础版)和卡尔曼滤波(高端版),可达到±0.5°至±0.1°的稳定精度。该系统适用于无人机航拍、工业检测等多种应用场景,特别适合DIY开发者和中小企业进行定制化开发。

bother3000的博客 3685

使用fontTools解析字体文件name数据表

使用python的fontTools解析ttf格式字体文件的name数据表

薛定谔的哈士奇……的博客 2554

Multisim的探针(Probe)及数字电路的一些调试技巧的应用

Multisim的探针(Probe)及数字电路的一些调试技巧的应用 --EE Bang   By  WRS 上图为555方波发生器,根据R1,R2,C2参数的配置可产生频率为46.3KHZ,占空比50%的方波信号,如果用示波器查看波形参数的话需要用两个坐标轴做差,操作不便,另外如果要修改电路将上述电阻换成滑动变阻器的话,使其产生可变频率

Agent Christmas的博客 3万+

查看字体列表,查看字体名称

$ fc-list 参考:http://www.yolinux.com/TUTORIALS/LinuxListOfFonts.html 转载于:https://www.cnblogs.com/zhangshaojian/p/6155252.html

weixin_33835103的博客 777

Multisim实战:从零搭建体温检测报警电路(附完整仿真文件+调试技巧)

本文详细介绍了如何使用Multisim从零搭建体温检测报警电路,涵盖LM35温度传感器、LM358运算放大器等核心器件的选型与连接,以及信号调理、阈值比较和数码管显示等关键电路设计。附赠完整仿真文件和实用调试技巧,帮助电子工程初学者快速掌握体温温度检测系统的设计与实现。

weixin_28285943的博客 294

从仿真到实战:PMOS缓启动与栅极泄放电路的优化设计

本文深入探讨了PMOS缓启动与栅极泄放电路的优化设计,通过立创EDA仿真和实物调试,解决了关断速度慢和耐压问题。文章详细介绍了电路改进方案和低功耗优化技巧,为工程师提供了实用的工程实践建议,帮助提升电源开关电路的性能和可靠性。

weixin_28721917的博客 260

获取Windows系统安装的字体名称极其对应的字体文件名

        在我们的Flex+PHP+Apache的web项目中,有个模块需要通过输入文字,设置字体,生成JPG图片。因为Flex和PHP中没有直接访问获取Windows系统字体的函数,只好用Delphi做了一个获取系统字体和对应的字体文件名的工具。原理很简单,通过Screen.Fonts中的字体名称,查询系统注册表HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/W

yingw的专栏 1万+

《S32系列芯片——Boot & HSE详解》持续更新中...

专栏总目录,将详细介绍S32系列芯片的Boot功能,最终给出HSE基于IVT的Secure Boot方案!!!

车载系统攻城狮 4387

swift 自定义字体使用

在info.plist 中加入Fonts provided by application,写入自定义字体的xxx.ttf 直接托自定义字体拖入项目即可。 如何获取ttf的名字? 直接双击xxx.ttf加入字体库到电脑,postScript为字体的名字。 如何调用 myNameLabel.font = UIFont(name: "MComicHKS-Medium",

Kangl的博客 1757

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Swift 引入第三方字体库

引入第三方字体库为了达到好的效果展现,我们往往会引入第三方字体库,以使我们工程中的字体展示达到最佳,这方面可能对于阅读之类的APP会用到的更多.在这里也是随便从网上下载的一个字体,名为经典隶书变体后缀为.ttf的;实践 1.将该文件加入到我们的工程中; 2.在Xcode中进行设置; (1)在info.plist中的Information Property List ->点击后面的+号,添加F

zhouwenchun 2499

java根据名字生成头像,上传云,window和liunx呈现不一样解决办法

为什么本地名字能显现出来,liunx上不行呢?先说下我的需求:是根据客户的名称生成一个带名字的头像,这样在一定的环境中,可以只看头像就知道谁是谁了,所以才做了一下开发;第一个方法里面是输出的是一个文件,然后放入到第二个方法里面,就能得到一个可以访问的地址,那么这个地址就是头像的地址;1.找到windows上对应的字体库,下载到本地桌面。再本地测试没有问题,上传到liunx就出现了问题;此时,在运行上面的程序,发现就正常了,问题解决了。

pingchangmile的博客 316

猿人学 web 第七题:动态字体,随风漂移

里面的 font-family 也就是一个特定的名字,src 就表示需要引用的具体的文件,而这个文件就是字体文件,一般是 ttf 类型,eot 类型,现在因为 ttf 类型文件过大,在移动端使用的时候会导致加载速度过慢,woff 类型的文件较为广泛应用。通过比较,其他字符的 on 值也不变,所以可以用过 on 值形成映射关系从而进行识别,将下载后的 ttf 文件放到。可以看出 on标签是一直不会变的,也就意外这 on标签所对应的数字也是不会变的,所以我们可以得到下面这段映射关系。

weixin_45091564的博客 449

猿人学web端爬虫攻防大赛赛题第7题——动态字体,随风漂移

形式的数据与页面中的数字是一一对应的,直接搞一个字典,获取每个页面的数据然后对照一下就完事了。可惜没那么简单,再访问同一个页面,你会发现对照关系变了。woff 文件是字体文件,实际上就是编码和字符的映射表,如 섴,&#x 是字符前缀,c134 是字符对应的编码。在看数据包的session中没有任何加密字段,请求头中也没有加密的参数。接下来就是获取所有召唤师的名字了,在js代码中进行了处理。所以上面的想法是有问题的,再看响应数据中的。有了映射字典就可以请求并解析到正确的数字了。与第一页的数据一致,没问题。

weixin_45091564的博客 1934

猿人学js逆向比赛第一届第七题

本文分析了网页字体加密的解密方法。通过解析返回的woff字体文件,发现加密字符与页面数字存在对应关系。使用ddddocr动态识别字体,将误识别的"o"手动修正为"0"后成功解密数据。文章还探讨了如何追踪召唤师名称与胜点的对应关系,通过在Python中还原网页表达式验证了解密方法的有效性。整个分析过程展示了针对字体加密数据的逆向处理方法。

m0_62945506的博客 1138

IOS添加自定义的字体文件

  以文本为主体的app或者非文本主体的纯文本页面往往需要配置系统字体以外的特(qi)殊(怪)字体,所以这个技能有时候需要get的。   这项技能的步骤分为三步:   第一步:按照PM的要求下载文字文件,一般是.ttf文件,这里我们使用一款比较可爱的字体来进行演示 字体一般可以直接百度字体下载即可下载。   解压将其中的 草莓之心.ttf 添加到project的资源路径(其实...

weixin_33947521的博客 117

C#实现根据字体名称获取字体文件名

基于注册表和字体文件夹,使用C#实现根据字体名称获取字体文件名

gc_2299的博客 2489

windows 中获取字体文件名

windows 获取字体文件名

cnkeysky的博客 4674

根据字体的中文名 获取 字体的路径 和 英文名

根据字体中文名找到路径,根据字体中文名找到英文名

Polaris 3614

TTF字体文件内容获取

项目开中,在等级证书打印的模块中,规定使用指定的字体,但是涉及到了广大考生的姓名就出现了问题.因中国文化博大精深,考生的名字也是丰富多彩的,在打印证书的过程中,发现规定使用的字体根本不够用,总有一些考生的姓名中包含有生僻字,结果就会出现PDF证书上面名字打印不出来. 总结:在使用字体渲染某些字符时,有可能渲染出空白或者“口”字形,原因在于该字体文件中不包含该字符的字形。 出现这个问题后,首先想到的是在生成证书之前,对广大考生的姓名进行扫描检测,事先知道哪些考生姓名中的字在规定使用的字体中不存在,这时候.

Climber813 9968

VB 获得系统字体列表

Private Sub Form_Load()Dim counterFor counter = 0 To Screen.FontCount - 1    List1.AddItem Screen.Fonts(counter)NextEnd Sub

鞠勇鸿的技术专栏 4000
上一篇: GUID生成
下一篇: C++ 中wchar_t范围来判断其是否是中文,数字还是其他
普通网友
博客等级 码龄14年 9粉丝 21原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值