Address Sanitizer

news/2024/11/20 19:34:30/文章来源:https://www.cnblogs.com/Dydong/p/18289319

Address Sanitizer

Introduction

Address Sanitizer是一款内存检测器,它可以检测在堆栈,全局变量等地方的溢出。后来被整合到了GCC等编译器中,Address Sanitizer由两部分组成:一个Instrumentation模块和一个运行时库。Instrumentation模块修改代码来检查每个内存访问的影子状态,并在堆栈和全局对象周围创建有毒的红色区域,以检测溢出和下溢。运行时库替换malloc、free和相关函数,在分配的堆区域周围创建有毒的红区,延迟释放堆区域的重用,并进行错误报告。Address Sanitizer使用影子内存来记录应用程序内存的每个字节是否可以安全访问,并使用仪器检查每个应用程序负载或存储上的影子内存。


Shadow Memory

​ malloc函数返回以8字节为单位,一般前k个字节是可以寻址的,后8-k个字节不可以,那么就有9种状态。规则具体为:0表示所有都可以寻址,K(1≤K≤7)表示前K字节是可寻址的,负值表示整个都不可以寻址,不同的负值来区分不同类型的不可寻址内存(堆红区、堆栈红区、全局红区、释放内存)。那么就可以用1个字节来存储,这种8:1的放缩形式导致影子内存的空间减少。

​ 地址转化时,使用偏移量来进行计算,可以理解为映射规则为(Addr>>Scale)+Offset。offset的设置也有相应的要求,选取的 Offset 应该满足如下约束:影子内存的地址段, 也就是 Offset 到 (Offset+Max)/8 的地址段,不能被应用程序用到。

​ 如下图所示,因为每一个内存memory都会进行一次shadow memory的映射,所以把应用程序的内存给映射为shadow,把shadow部分给映射为bad区域,bad区域就是一个不可访问的区域。

​ 映射规则可以细分为直接映射和间接映射,直接映射的代表性的例子是 TaintTrace 和 LIFT。TaintTrace 按照 1:1 映射。缺点就是无法处理内存需求特别大的被检测程序 ,如果被检测程序使用了一半以上的地址空间,那就没有足够的地址空间来容纳影子内存了。相比来说,LIFT 使用 8:1 的比例设置影子内存。间接映射的代表是 valgrind 和 Dr.Memory。他们设置多个影子内存段,然后配合查表法来完成映射。


Instrumentation

​ 当检测一个8字节的内存访问时,Address Sanitizer计算相应影子字节的地址,加载该字节,并检查它是否为零:

ShadowAddr = (Addr >> 3) + Offset;	// 取地址中的字节
if (*ShadowAddr != 0)	ReportAndCrash(Addr);	// 如果不为0那么就报告

​ 当检测1、2或4字节访问时,检测稍微复杂一些:如果阴影值为正(即,8字节字中只有前k个字节是可寻址的),我们需要将地址的最后3位与k进行比较:

ShadowAddr = (Addr >> 3) + Offset;	// 取地址中的字节
k = *ShadowAddr;
if (k != 0 && ((Addr & 7) + AccessSize > k))	ReportAndCrash(Addr);

ReportAndCrash的实现方式为简单的函数调用或者硬件异常指令。

​ 本技术将Address Sanitizer Instrumentation通道放置在LLVM优化管道的最末端。只记录那些在LLVM优化器执行的所有标量和循环优化中幸存下来的内存访问。例如,对由LLVM优化掉的本地堆栈对象的内存访问将不会被检测。同时,我们不需要测量由LLVM代码生成器生成的内存访问(例如,寄存器溢出)。


Run-time Library

​ 允许库中malloc和free函数也被专门函数取代,将malloc申请的堆块附近加入红区,可以认为是无法寻址访问被poisoned的区域。如果想防住Buffer Overflow漏洞,只需要在每块内存区域右端(或两端,能防overflow和underflow)加一块区域(RedZone),使RedZone的区域的影子内存(Shadow Memory)设置为不可写即可。

​ 对于全局变量,红区是在编译时创建的,红区地址在应用程序启动时传递给运行时库。运行时库函数毒害红区并记录地址,以便进一步报告错误。对于堆栈对象,红区是在运行时创建和毒害的。举个例子:

void foo() {char a[10];<function body>
}

​ 在函数调用的时候会进行创建红区:

void foo() {char rz1[32];char arr[10];char rz2[32-10+32];unsigned *shadow =(unsigned*)(((long)rz1>>8)+Offset);// poison the redzones around arr.shadow[0] = 0xffffffff; // rz1shadow[1] = 0xffff0200; // arr and rz2shadow[2] = 0xffffffff; // rz2<function body>// un-poison all.shadow[0] = shadow[1] = shadow[2] = 0;
}

Example

如下图所示,我们拿Ubuntu22.04作为例子来演示Heap上的溢出,在编译的时候加入选项g++ -fsanitize=address -g main.cpp

#include <iostream>
#include <cstring>
char* memoryOverflowExample()
{char* ret = new char;strcpy(ret, "Hello World\r\n");return ret;
}
int main()
{char* ret = memoryOverflowExample();std::cout << ret << std::endl;delete ret;
}

当运行的时候,首先他会现实调用的函数栈,然后会显示shadow memory上的状态,中括号为申请空间的映射,其中的定义为上述定义所示,然后旁边被红区包围,因为它是堆上的申请,所以旁边显示为Heap left redzone。

它所能检测出来的错误:


Reference article

AddressSanitizer: A Fast Address Sanity Checker | USENIX

https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/740399.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

暂停windows更新方法

暂停windows更新方法暂停windows更新方法 打开注册表进入 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings右键新建DWORD的32位,输入名称:FlightSettingsMaxPauseDays选择十进制,输入3650天网站:http://shibowl.topgithub:https://github.com/ha…

航空航天单位保密网文件导出管理难点在哪里?如何解决?

航空航天单位的重要性不言而喻,它们在国家安全、科技进步、经济发展以及国际合作等多个领域都扮演着至关重要的角色。为了保护工作内容中的重要数据,遵守保密规定,对涉密人员、保密要害部门单位、涉密载体、涉密信息传输和涉密活动进行严格管理,采用物理隔离的方式将网路隔…

【转载】App Inventor 开发BLE应用

1. 文章1:搭建环境的介绍: 【深海王国】小学生都能做的APP?AppInventor、BLE蓝牙、Arduino联合开发你的第一个手机远程控制程序(1) 链接:https://blog.csdn.net/D13162580021/article/details/139026624?spm=1001.2014.3001.55022. 文章2:BLE基本知识的介绍: 【深海王…

从 Helm 到 Operator:Kubernetes应用管理的进化

🧰Helm 的作用 在开始前需要先对 kubernetes Operator 有个简单的认识。 以为我们在编写部署一些简单 Deployment 的时候只需要自己编写一个 yaml 文件然后 kubectl apply 即可。apiVersion: apps/v1 kind: Deployment metadata: labels: app: k8s-combat name: k8s-…

RAG工程实践拦路虎之一:PDF格式解析杂谈

背景 PDF(Portable Document Format)是一种广泛用于文档交换的文件格式,由Adobe Systems开发。它具有跨平台性、固定布局和易于打印等特点,因此在商业、学术和个人领域广泛应用。然而,PDF文件的解析一直是一个具有挑战性的问题,因为其内部结构的复杂性和多样性,使得提取…

PHP转Go系列 | ThinkPHP与Gin框架之API接口签名设计实践

数据安全一直是个热门的话题,API 接口在数据的传输上扮演着至关重要的角色。大家好,我是码农先森。 回想起以前用模版渲染数据的岁月,那时都没有 API 接口开发的概念。PHP 服务端和前端 HTML、CSS、JS 代码混合式开发,也不分前端、后端程序员,大家都是全干工程师。随着前后…

【一位资深用户的可视化工具推荐】智慧社区平台里的停车位如何协调?快来看看这款免费可视化工具

在智慧社区的管理中,停车位的协调是一个重要的难题,而山海鲸可视化这款免费可视化工具为解决这一问题提供了完美的解决方案。山海鲸可视化通过其强大的二三维融合功能,能够将二维面板与三维场景无缝结合,使停车位的管理变得更加直观和高效。无论是实时查看停车位的使用情况…

**CodeForces CF1928B Equalize题解**

ok兄弟们,今天本蒟蒻来做一篇小小的题解 Equalize 题面翻译 有一个给定的长度为 $n$ 的数列 $a$,现在加上一个排列 $b$,即 $c_i=a_i+b_i$。 现在求对于所有可能的 $b$,$c$ 中出现最多的数的出现次数的最大值。 translate by @UniGravity. 题目描述 Vasya has two hobbies —…

QT学习遇到的问题 乱码

孔夫子上买了一本二手的《QT 5.9 C++开发指南》, 从网站上下载了书中的代码, 在运行样例6.1过程中, 发现弹出的对话框中字符为乱码, 经过搜索, 找到了如下解决方法: 在头文件中添加了一行代码: #pragmaexecution_character_set("UTF-8")

微信小程序自动识别收货地址

为提升用户体验,在用户新增收货地址时,加入自动识别收货地址功能。.wxml <view class="top"><input type="text" placeholder="复制收货信息(格式:姓名→电话→地址)" value="{{distinguish}}"bindinput="distinguis…

性价比很高的多域名SSL证书:Buypass

在当今数字化快速发展的时代,网络安全已成为公众和企业关注的焦点。为了保障网站数据的安全传输,许多网站都采用了SSL证书来加密用户与服务器之间的通信。申请Buypass六个月免费SSL证书步骤 1、输入域名,注意由于Buypass不支持泛域名,请不要勾选泛域名。 2、选择加密方式,…

01、基础介绍

Kubernetes介绍和各组件盘点 01、K8S总览 Kubernetes(K8s),用于自动部署、扩容、缩容和管理容器化应用程序的开源系统。 它将组成应用程序的容器组合成逻辑单元,以便于管理和服务发现。 Kubernetes源自Google 15年生产环境的运维经验,同时凝聚了社区最佳创意和实践。 简单…