惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
I
InfoQ
The Register - Security
The Register - Security
L
LangChain Blog
H
Help Net Security
The GitHub Blog
The GitHub Blog
S
Schneier on Security
博客园 - 【当耐特】
W
WeLiveSecurity
Attack and Defense Labs
Attack and Defense Labs
IT之家
IT之家
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Google DeepMind News
Google DeepMind News
The Cloudflare Blog
H
Heimdal Security Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Y
Y Combinator Blog
雷峰网
雷峰网
N
Netflix TechBlog - Medium
Security Archives - TechRepublic
Security Archives - TechRepublic
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
L
Lohrmann on Cybersecurity
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
T
The Exploit Database - CXSecurity.com
P
Privacy & Cybersecurity Law Blog
G
GRAHAM CLULEY
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
V
Visual Studio Blog
博客园 - 聂微东
PCI Perspectives
PCI Perspectives
Last Week in AI
Last Week in AI
A
Arctic Wolf
宝玉的分享
宝玉的分享
T
The Blog of Author Tim Ferriss
S
Secure Thoughts
T
Threat Research - Cisco Blogs
GbyAI
GbyAI
云风的 BLOG
云风的 BLOG
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
SegmentFault 最新的问题
SecWiki News
SecWiki News
月光博客
月光博客
大猫的无限游戏
大猫的无限游戏
Schneier on Security
Schneier on Security
P
Proofpoint News Feed
博客园 - Franky
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
AI
AI
Engineering at Meta
Engineering at Meta

看川博客

我被 AI "蒸馏" 了 - 看川博客 距离上线只差一个软件著作权证书 - 看川博客 开发简报(2):开发者需要先进的工具 - 看川博客 比越狱更棘手!iOS vPhone 虚拟机成黑灰产新温床 - 看川博客 开发简报(1):拥抱 AI、别无选择 - 看川博客 糟糕!我的 OpenClaw 中了病毒 - 看川博客 今天你用了多少词元? - 看川博客 闪忆 LiveMem:把回忆做成会动的壁纸 - 看川博客 Swift 从 ObservableObject 迁移到 @Observable 的再讨论 视频帧截图(Video2Frame)专业视频抽帧截图工具 - 看川博客 录音记事本 - 专业安全的录音工具 App - 看川博客 Swift 从 ObservableObject 迁移到 @Observable 从 Apple Distribution Managed 证书提取备案所需公钥和 SHA1 条码助手 iOS 2.0.0 升级指南 - 看川博客 SwiftUI Menu checkmark 文本对齐 - 看川博客 SwiftUI 系统颜色表查询 - 看川博客 读马伯庸《长安的荔枝》 - 看川博客 SwiftUI List selection 的使用提示 - 看川博客 PHP json_encode UTF-8 中文编码问题 - 看川博客 我为什么重新运营微信公众号 - 看川博客 使用 TrollStore(巨魔) 在非越狱设备上安装任意 IPA - 看川博客 条码助手小程序更新 - 看川博客 iOS 18 中 libdyld.dylib/dyld 的一些变化 涨粉神器?解密“抖音黑科技”云端商城 - 看川博客
C++ RTTI 信息对二进制体积和安全性的影响 - 看川博客
2025-03-21 · via 看川博客

RTTI 是 C++ 提供的运行时机制用于确定对象的类型。借助 RTTI,程序可以在运行时识别对象信息,这在处理多态对象时十分有用。但另一方面,RTTI 会在包体积和安全性上可能有负面影响。

RTTI,即 Run-Time Type Information。

RTTI 的作用

C++ 主要提供了两个操作符来使用 RTTI 特性:

  • typeid 操作符

用于获取对象的类型信息,返回一个 std::type_info 对象,这个对象包含了类型的名称等关键信息。

  • dynamic_cast 操作符

用于在继承层次结构中进行安全的类型转换(从基类指针或引用转换为派生类指针或引用)。如果转换失败,对于指针类型,dynamic_cast 会返回 nullptr;对于引用类型,dynamic_cast 会抛出 std::bad_cast 异常。

使用 AI 生成的一个简单示例展示 typeid 和 dynamic_cast 的用法:

#include <iostream>

class Base {
public:
    virtual ~Base() {}
};

class Derived : public Base {};

int main() {
    Base* basePtr = new Derived();

    // 使用 typeid 获取类型信息
    std::cout << "Type of basePtr: " << typeid(*basePtr).name() << std::endl;

    // 使用 dynamic_cast 进行向下转换
    Derived* derivedPtr = dynamic_cast<Derived*>(basePtr);
    if (derivedPtr) {
        std::cout << "Downcast successful!" << std::endl;
    } else {
        std::cout << "Downcast failed!" << std::endl;
    }

    delete basePtr;
    return 0;
}

RTTI 负面影响

RTTI 的实现依赖于编译器在编译时生成额外的类型信息,并将这些信息在最终的二进制文件中保留。这些类型信息包含类的层次结构、类型名称等,程序在运行时可以根据这些信息来确定对象的实际类型。因此,RTTI 在增加动态性的同时,也不可避免地引入了一些负面作用:

  • 会使编译后的二进制文件增大

项目中 C++ 代码比较多的话,影响比较显著。在 kanchuan 测试的项目中,启用 RTTI 后,二进制包体积增大了 5M。

  • 二进制安全性

启用 RTTI 后,可能会给攻击者暴露一些关键的类信息。

  • 性能影响

相比前两个影响,在现有 CPU 算力的情况下对性能的影响相对没那么重要。但在对性能要求极高的场景下,关闭 RTTI 可以提高程序的运行效率(避免了运行时计算)。

如何关闭 RTTI

代码中不能包含 typeid 和 dynamic_cast 的使用,同时可以增加 -fno-rtti 编译参数禁用 RTTI。以 Protocol Buffers 为例,其 C++ 版本(至少 从 V21.12 版本开始)提供了禁用 RTTI 的支持:

"OTHER_CPLUSPLUSFLAGS" => "-fno-rtti"

即可编译 “NO RTTI“ 的版本。

如何确定关闭 RTTI 是否生效

__ZTI 是 GCC 和 Clang 编译器为 type_info 类型生成的符号的前缀,以 iOS Mach-O 二进制文件为例,可以通过以下命令查找与 RTTI 相关的符号:

nm {binary_file} | grep "__ZTI"

需要注意的是,即使在工程中配置 -fno-rtti,也可能还是找到一些 "__ZTI" 符号,比如:

0000000000004600 S __ZTISt11logic_error
0000000000004618 S __ZTISt12length_error
0000000000004630 S __ZTISt12out_of_range
00000000000045f0 S __ZTISt9exception
00000000000038a0 S __ZTISt11logic_error
00000000000038b8 S __ZTISt12length_error
0000000000003890 S __ZTISt9exception
0000000000001ff0 S __ZTISt11logic_error
0000000000002008 S __ZTISt12length_error
0000000000001fe0 S __ZTISt9exception
000000000000d350 S __ZTISt11logic_error
000000000000d368 S __ZTISt12length_error
000000000000d340 S __ZTISt9exception
000000000000c0c0 S __ZTISt11logic_error
000000000000c0d8 S __ZTISt12length_error
000000000000c0b0 S __ZTISt9exception

这些是依赖的标准库或其他三方库中可能存在的 RTTI,只要确保没有我们自己业务代码的 __ZTI 符号即可。