使用 Visual C++ 的地址清理程序:忽略读取缓冲区溢出,同时仍捕获写入缓冲区溢出

Posted

技术标签:

【中文标题】使用 Visual C++ 的地址清理程序:忽略读取缓冲区溢出,同时仍捕获写入缓冲区溢出【英文标题】:Address Sanitizer with Visual C++: ignore read buffer overflows while still catching write buffer overflows 【发布时间】:2021-12-11 14:25:00 【问题描述】:

考虑以下示例:

int main()

    char* p = new char[10];
    
    srand(p[11]); // heap buffer overflow - read

    p[11] = rand(); // heap buffer overflow - write

我希望 ASan 暂时不要标记 heap buffer overflow - read,同时仍标记 heap buffer overflow - write

我想要这样做的原因是现在专注于更危险的错误。读取溢出要么立即崩溃,要么没有后果,而写入溢出可能会导致稍后在其他地方触发的损坏。对于一些小的溢出,即使是立即崩溃也被排除在外。所以我肯定也会研究读取溢出,但稍后。

有没有办法做到这一点?

【问题讨论】:

【参考方案1】:

实现这一点有两个方向。

1。触发错误后继续

要在出错后继续,应使用-fsanitize-recover=address 选项。来自FAQ:

问:AddressSanitizer 在报告第一个错误后能否继续运行?

A:可以,AddressSanitizer 最近获得了错误后继续模式。这有点实验性,因此可能还不如默认设置可靠(并且不及时支持)。还要记住,第一个错误之后的错误实际上可能是虚假的。要启用错误后继续,请使用-fsanitize-recover=address 编译,然后使用ASAN_OPTIONS=halt_on_error=0 运行您的代码。

MSVC 编译器尚不支持此选项。有一个issue 可以添加它。

如果可行,则可以安装一个自定义处理程序来检查它是读取还是写入错误,忽略读取错误并报告写入错误。

2。不要检测读取错误

正如@yugr 所指出的,有-mllvm -asan-instrument-reads=false 选项可以实现这一点。但是 MSVC 编译器也不支持这个选项。

但仍有一些方法可以避免在某些地方使用编译器检测。它是__declspec(no_sanitize_address)。因此,可以通过隔离已知的读取错误来实现目标,如下所示:

__declspec(no_sanitize_address)
void isolate_read_heap_buffer_overflow(char* p)

    srand(p[11]); // heap buffer overflow - read


int main()

    char* p = new char[10];
    
    isolate_read_heap_buffer_overflow(p);

    p[11] = rand(); // heap buffer overflow - write

    return 0;


其他更好的选择

还有clang-cl编译器,其实就是支持Visual C++语义的Clang。 Visual Studio 安装程序会安装它。因此,如果可以重新定位项目以使用 Clang,这将打开 Clang 中可用的所有 Address Sanitizer 功能。不幸的是,重新定位一些遗留代码库可能是一项漫长的任务。

【讨论】:

【参考方案2】:

理论上,向 CL 包装器提供 -mllvm -asan-instrument-reads=false 应该会禁用读取检测。

【讨论】:

我已经编辑了我的答案来提及这一点,我也找到了一个可以接受的解决方案

以上是关于使用 Visual C++ 的地址清理程序:忽略读取缓冲区溢出,同时仍捕获写入缓冲区溢出的主要内容,如果未能解决你的问题,请参考以下文章

C++ 指针使用 Visual Studio 更改地址,而不是使用 OsX 中的 Xcode 或 Linux 中的 gcc

用啥软件来查看一个用Microsoft Visual C++ 6.0 编写的程序的源代码

Visual Studio 2008 C++ 误报内存地址位置

应用程序重新启动 C++ Visual Studio 时保存编辑控件用户输入和恢复的有效方法

Visual c++ 6.0 应用程序大小大于 Visual Studio 2010 应用程序大小

Visual C++(VC)6.0下载地址及安装教程