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

推荐订阅源

aimingoo的专栏
aimingoo的专栏
S
Securelist
博客园 - Franky
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
IT之家
IT之家
GbyAI
GbyAI
Microsoft Azure Blog
Microsoft Azure Blog
The Cloudflare Blog
云风的 BLOG
云风的 BLOG
N
News and Events Feed by Topic
AI
AI
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Schneier on Security
Schneier on Security
Attack and Defense Labs
Attack and Defense Labs
Vercel News
Vercel News
腾讯CDC
Google DeepMind News
Google DeepMind News
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
M
MIT News - Artificial intelligence
WordPress大学
WordPress大学
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
N
Netflix TechBlog - Medium
量子位
S
Schneier on Security
Hacker News: Ask HN
Hacker News: Ask HN
Cyberwarzone
Cyberwarzone
S
Security Affairs
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
N
News and Events Feed by Topic
T
Tenable Blog
PCI Perspectives
PCI Perspectives
MyScale Blog
MyScale Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Cyber Attacks, Cyber Crime and Cyber Security
W
WeLiveSecurity
N
News | PayPal Newsroom
P
Proofpoint News Feed
O
OpenAI News
C
CERT Recently Published Vulnerability Notes
B
Blog
Cisco Talos Blog
Cisco Talos Blog
Microsoft Security Blog
Microsoft Security Blog
V
Visual Studio Blog
MongoDB | Blog
MongoDB | Blog
大猫的无限游戏
大猫的无限游戏
A
Arctic Wolf
Y
Y Combinator Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Spread Privacy
Spread Privacy

看川博客

我被 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 符号即可。