AddressSanitizer

本文最后更新于:2023年3月3日 下午

AddressSanitizer论文

Abstract

这个项目可以检测out-of-boundsuse-after-free导致的bug。

Shadow Memory

何为Shadow Memory
引用维基百科:

1
In computing, shadow memory is a technique used to track and store information on computer memory used by a program during its execution. Shadow memory consists of shadow bytes that map to individual bits or one or more bytes in main memory. These shadow bytes are typically invisible to the original program and are used to record information about the original piece of data. --维基百科

简而言之,shadow memory 是用来记录当前进程内存的可访问状态的元数据。
本ASAN应用中,利用 shadow memory 的映射,知道当前内存的可访问状态。
例如有一块内存M1,其 shadow memory 是S1,当我们需要访问M1时,会先读取S1,若S1记录值允许访问,才可访问。不难发现,如果应用 shadow memory,则需要为其单独分配空间来储存状态量。
更高效的映射方法
ASAN使用了一种更高效的映射方法,可以将一块 8Byte 的内存块用 1Byte 的内存表示。
因为 malloc 函数返回地址(分配地址)是 8Byte 对齐的,故一块内存可以进行寻址访问的状态便有以下9种:

  • 整块内存(8Byte)均无法访问;
  • 整块内存(8Byte)均可访问;
  • 仅内存的前k字节可访问(k从1~7之间取值)。

那么一块内存的访问状态,便可以用 1Byte 大小的空间进行表示,甚至完全不需要 1Byte。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
什么是 8Byte 对齐?

当使用 malloc 函数分配空间时,比如
void *p1 = malloc(1);
我申请了1个字节大小的内存,但 malloc 函数会分配给我8个字节的连续的一块内存。
这就是 8byte 对齐

为什么是9个状态?

首先,如果该内存块未被分配,即全部无法访问,对应一种;
如果该内存块全部被分配,则全部可以访问,对应一种;
由于内存块是连续分配的,故不可能出现 连续的 8Byte 内,第123 Byte 可访问,第 4 Byte不可访问,而第 5 Byte 又可以访问的情况,故对应了7种情况,即该块内,前k个 Byte 可访问,而后 8 - k Byte无法访问。共对应 7 种情况。
故一共是 1 + 1 + 7 = 9 种状态。

Shadow Memory 对应算法
即如何将 Memory 的内容映射至 Shadow 呢
使用以下公式,其中 ADDR 表示当前内存块的地址:

1
(ADDR >> 3) + OFFSET;

即右移三位后,统一加上一个偏移值 OFFSET 避免与正常允许的内存产生冲突。

Shadow Memory 中存放的值
规则如下:

  • 当该 Shadow Memory 值为0时,表示该内存块所有地址均可寻址;
  • 值为1~7的整数时,表示前k个地址可寻址;
  • 值为任意负数时,表示不可寻址;
    不同的负数表示不同的不可寻址:heap redzones, stack redzones, global redzones, freed redzones)

判断是否访问了不能访问的内存

首先,当 AccessSize 也就是访问的位数等于8时

1
2
3
4
ShadowAddr = (Addr >> 3) + Offset;
if(*ShadowAddr != 0)
ReportAndCrash(Addr);

当 AccessSize 为 1 、 2 、 4时,需要将Addr带入,与7做AND操作后,进行判断

1
2
3
4
ShadowAddr = (Addr >> 3) + Offset;
k = *ShadowAddr;
if ( k != 0 && ((Addr & 7 ) + AccessSize > k))
ReportAndCrash(Addr);

为何此处是 Addr & 7 + AccessSize与 k(可访问字节数)做比较呢
因为 Addr & 7 代表被访问的该内存(这一Byte),相对其之前一个“对齐点”的位移,加上妄图访问的字节数后,就是最终访问的总字节数,用其与 k 比大小,可判断是否越界。

关于代码插桩何时介入
放到LLVM优化的靠后位置,这样只需要对被LLVM进行过优化的代码进行插桩,减少了不必要的插入。
该报错代码 ReportAndCrash 只会执行一次就中断程序。

运行时
调用 malloc 函数会返回一段内存,和两端额外的内存,延申在原本申请的内存两端,这被称为 redzone或称为 poisoned,分配的 red zone 越大,找到溢出漏洞的概率越大。
设置redzone将分配的内存段包住,有以下关系:
当分配的内存段数量为 n 时, redzones 的数量应该是 n+1

free 函数会将释放区域全部设置为 poisoned 且不会恢复,即该区域暂时不会再次被 malloc。这被叫做拖入隔离区,隔离区是一个大小固定的 FIFO 队列。默认情况下,malloc和free会记录当前的调用栈以为bug报告提供更多信息

栈及全局对象的检测

对于全局对象,redzones 是在编译时被放入的,随后在程序运行时,这些地址被传入 runtime library。程序运行时,这些 redzones 会被 标记为 poisoned

对于栈来说,redzones 的创建与染毒,是都在 runtime 发生的。

错误及漏报
比较具代表性的:
直接跨越了一个 redzone
即 a 分配了 500字节,a 右侧 redzone 大小为500 字节,b分配了 5000字节大小
若一个指针从 a 读取,偏移量达到1000,则很可能直接访问了b区的合法区域。

1
2
3
4
5
char *a = new char[100];

char *b = new char[1000];

a[500] = 0; // may end up somewhere in b

ASan 实际测试

堆越界

程序源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int main()
{
char *heap_buf = (char*)malloc(32*sizeof(char));
memcpy(heap_buf+30, "overflow", 8); //在heap_buf的第30个字节开始,拷贝8个字符

free(heap_buf);

return 0;
}

可以看出,申请了32个字节,但是会访问至 base_addr + 37 字节处,来看看 asan 怎么处理

编译:

1
gcc -fsanitizer=addresss -fno-omit-frame-pointer -o test1 test1.c

运行:

1
./test1

以下是运行结果,即asan给出的错误信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
=================================================================
==3905==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000000060 at pc 0x7f09040c62c3 bp 0x7ffcf197b180 sp 0x7ffcf197a928
WRITE of size 8 at 0x603000000060 thread T0
#0 0x7f09040c62c2 in __interceptor_memcpy ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827
#1 0x5605f809b241 in main (/home/stre/Desktop/test1+0x1241)
#2 0x7f0903e91fcf in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#3 0x7f0903e9207c in __libc_start_main_impl ../csu/libc-start.c:409
#4 0x5605f809b144 in _start (/home/stre/Desktop/test1+0x1144)

0x603000000060 is located 0 bytes to the right of 32-byte region [0x603000000040,0x603000000060)
allocated by thread T0 here:
#0 0x7f0904140867 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x5605f809b21e in main (/home/stre/Desktop/test1+0x121e)
#2 0x7f0903e91fcf in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58

SUMMARY: AddressSanitizer: heap-buffer-overflow ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827 in __interceptor_memcpy
Shadow bytes around the buggy address:
0x0c067fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c067fff8000: fa fa 00 00 00 fa fa fa 00 00 00 00[fa]fa fa fa
0x0c067fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==3905==ABORTING

其中:

1
2
==3905==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000000060 at pc 0x7f09040c62c3 bp 0x7ffcf197b180 sp 0x7ffcf197a928
WRITE of size 8 at 0x603000000060 thread T0

这两行内容告诉用户,这是一个堆越界的 bug ,发生于地址 0x603000000060

接下来:

1
0x603000000060 is located 0 bytes to the right of 32-byte region [0x603000000040,0x603000000060)

意思是,这个错误访问的地址,是 32-byte region的右侧,位于 [0x603000000040,0x603000000060)这个左闭右开的可访问区间的右端,位移为0处,即访问了右侧这个不可访问的地址。

接下来:

1
SUMMARY: AddressSanitizer: heap-buffer-overflow ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827 in __interceptor_memcpy

总结:这是一个堆越界的错误,具体路径以及导致这个问题的函数被列出。

利用 shadow memory 的映射公式,可以计算

1
0x603000000060 >> 3 + 0x7fff8000 = 0xc067fff800c

而这个计算出的地址,正好对应下面列出的特别被圈出的地址

1
2
3
4
5
0x0c067fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c067fff8000: fa fa 00 00 00 fa fa fa 00 00 00 00[fa]fa fa fa
0x0c067fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa

即,该影子地址内存储的值为fa,即不可访问,但源程序进行了访问,故报错。

修改源代码,若仅前3个字节(即共32+3个字节是申请的内存空间)可访问,则此处报错是如何

1
2
3
  0x0c087fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c087fff8000: fa fa 00 00 00 00[03]fa fa fa fa fa fa fa fa fa
0x0c087fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa

很明显,此处存放的值为03,即前三个字节可访问

内存泄露检测

1
2
3
4
5
6
7
8
9
10
11
// leak.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, const char *argv[]) {
char *s = (char*)malloc(100);
strcpy(s, "Hello world!");
printf("string is: %s\n", s);
return 0;
}

进行编译、运行后,会生成下述报告

1
2
3
4
5
6
7
8
==3528==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 100 byte(s) in 1 object(s) allocated from:
#0 0x7fa9f49d0867 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x55df42973225 in main (/home/stre/Desktop/leak+0x1225)
#2 0x7fa9f4721fcf in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58

SUMMARY: AddressSanitizer: 100 byte(s) leaked in 1 allocation(s).

发现内存泄露detected memory leaks
接下来打印了泄露的位置以及泄露空间的大小

UAF(use after free)

1
2
3
4
5
6
7
8
9
10
11
12
// uaf.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, const char *argv[]) {
char *s = (char*)malloc(100);
free(s);
strcpy(s, "Hello world!"); // use-after-free
printf("string is: %s\n", s);
return 0;
}

将指针 s 指向的空间释放后,又访问指向的空间。

以下是编译且运行后报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
=================================================================
==3573==ERROR: AddressSanitizer: heap-use-after-free on address 0x60b0000000f0 at pc 0x7fa6785892c3 bp 0x7fff93446ed0 sp 0x7fff93446678
WRITE of size 13 at 0x60b0000000f0 thread T0
#0 0x7fa6785892c2 in __interceptor_memcpy ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827
#1 0x5634c5025270 in main (/home/stre/Desktop/uaf+0x1270)
#2 0x7fa678354fcf in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#3 0x7fa67835507c in __libc_start_main_impl ../csu/libc-start.c:409
#4 0x5634c5025164 in _start (/home/stre/Desktop/uaf+0x1164)

0x60b0000000f0 is located 0 bytes inside of 100-byte region [0x60b0000000f0,0x60b000000154)
freed by thread T0 here:
#0 0x7fa678603517 in __interceptor_free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:127
#1 0x5634c5025255 in main (/home/stre/Desktop/uaf+0x1255)
#2 0x7fa678354fcf in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58

previously allocated by thread T0 here:
#0 0x7fa678603867 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x5634c5025245 in main (/home/stre/Desktop/uaf+0x1245)
#2 0x7fa678354fcf in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58

SUMMARY: AddressSanitizer: heap-use-after-free ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827 in __interceptor_memcpy
Shadow bytes around the buggy address:
0x0c167fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c167fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c167fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c167fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c167fff8000: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
=>0x0c167fff8010: fd fd fd fd fd fa fa fa fa fa fa fa fa fa[fd]fd
0x0c167fff8020: fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa fa
0x0c167fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c167fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c167fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c167fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==3573==ABORTING

asan 明确地指出了发生错误及地址是AddressSanitizer: heap-use-after-free on address 0x60b0000000f0

这个地址是在被释放的区域内0x60b0000000f0 is located 0 bytes inside of 100-byte region [0x60b0000000f0,0x60b000000154)freed by thread T0 here

分配释放不匹配

1
2
3
4
5
6
7
8
9
10
11
12
// bad_delete.cpp
#include <iostream>
#include <cstring>

int main(int argc, const char *argv[]) {
char *cstr = new char[100];
strcpy(cstr, "Hello World");
std::cout << cstr << std::endl;

delete cstr;
return 0;
}

该程序分配内存时使用的是new[]而释放时使用的不是delete[],造成释放不完全。

其错误信息是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
=================================================================
==2180936==ERROR: AddressSanitizer: alloc-dealloc-mismatch (operator new [] vs operator delete) on 0x60b0000000f0 // 1
#0 0x7fa9f877cc65 in operator delete(void*, unsigned long) ../../../../src/libsanitizer/ASAN/ASAN_new_delete.cc:177
#1 0x55d09d3fe33f in main /home/chenbing/Code/test/bad_delete.cpp:10
#2 0x7fa9f8152082 in __libc_start_main ../csu/libc-start.c:308
#3 0x55d09d3fe20d in _start (/home/chenbing/Code/test/bad_delete+0x120d)

0x60b0000000f0 is located 0 bytes inside of 100-byte region [0x60b0000000f0,0x60b000000154) // 2
allocated by thread T0 here:
#0 0x7fa9f877b787 in operator new[](unsigned long) ../../../../src/libsanitizer/ASAN/ASAN_new_delete.cc:107
#1 0x55d09d3fe2e5 in main /home/chenbing/Code/test/bad_delete.cpp:6
#2 0x7fa9f8152082 in __libc_start_main ../csu/libc-start.c:308

SUMMARY: AddressSanitizer: alloc-dealloc-mismatch ../../../../src/libsanitizer/ASAN/ASAN_new_delete.cc:177 in operator delete(void*, unsigned long)
==2180936==HINT: if you don't care about these errors you may set ASAN_OPTIONS=alloc_dealloc_mismatch=0
==2180936==ABORTING

错误类型:alloc-dealloc-mismatch,地址为0x60b0000000f0

栈溢出

1
2
3
4
5
6
7
8
// sbo.c
#include <stdio.h>

int main(int argc, const char *argv[]) {
int stack_array[100];
stack_array[101] = 1;
return 0;
}

在栈伤创建了大小为100字节的数组,但在超过其范围的地方进行写入1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
~/Code/test$ g++ sbo.c -o sbo -fsanitize=address -g
chenbing@GreatDB-CB:~/Code/test$ ./sbo
=================================================================
==2196928==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffc33777f24 at pc 0x562dccb592b6 bp 0x7ffc33777d40 sp 0x7ffc33777d30 1)
WRITE of size 4 at 0x7ffc33777f24 thread T0
#0 0x562dccb592b5 in main /home/chenbing/Code/test/sbo.c:6
#1 0x7f45bf52d082 in __libc_start_main ../csu/libc-start.c:308
#2 0x562dccb5910d in _start (/home/chenbing/Code/test/sbo+0x110d)

Address 0x7ffc33777f24 is located in stack of thread T0 at offset 452 in frame 2)
#0 0x562dccb591d8 in main /home/chenbing/Code/test/sbo.c:4

This frame has 1 object(s): 3)
[48, 448) 'stack_array' (line 5) <== Memory access at offset 452 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork 4)
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /home/chenbing/Code/test/sbo.c:6 in main
Shadow bytes around the buggy address: 5)
0x1000066e6f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000066e6fa0: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
0x1000066e6fb0: f1 f1 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000066e6fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000066e6fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x1000066e6fe0: 00 00 00 00[f3]f3 f3 f3 f3 f3 f3 f3 00 00 00 00
0x1000066e6ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000066e7000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000066e7010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000066e7020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000066e7030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASAN internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==2196928==ABORTING

非常明确的指出了是stack-buffer-overflow
栈中数组可访问的范围是[48, 448),但程序访问了 452 处,故故障。

全局缓冲区溢出

1
2
3
4
5
6
7
8
9
// gbo.c
#include <stdio.h>

int global_array[100] = {-1};

int main(int argc, char **argv) {
global_array[101] = 1;
return 0;
}

报错如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
=================================================================
==3701==ERROR: AddressSanitizer: global-buffer-overflow on address 0x55633ad321b4 at pc 0x55633ad2f216 bp 0x7ffff739eca0 sp 0x7ffff739ec90
WRITE of size 4 at 0x55633ad321b4 thread T0
#0 0x55633ad2f215 in main (/home/stre/Desktop/gl+0x1215)
#1 0x7f5a1ea1dfcf in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#2 0x7f5a1ea1e07c in __libc_start_main_impl ../csu/libc-start.c:409
#3 0x55633ad2f104 in _start (/home/stre/Desktop/gl+0x1104)

0x55633ad321b4 is located 4 bytes to the right of global variable 'global_array' defined in 'gl.c:4:5' (0x55633ad32020) of size 400
SUMMARY: AddressSanitizer: global-buffer-overflow (/home/stre/Desktop/gl+0x1215) in main
Shadow bytes around the buggy address:
0x0aace759e3e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0aace759e3f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0aace759e400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0aace759e410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0aace759e420: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0aace759e430: 00 00 00 00 00 00[f9]f9 f9 f9 f9 f9 00 00 00 00
0x0aace759e440: f9 f9 f9 f9 f9 f9 f9 f9 00 00 00 00 00 00 00 00
0x0aace759e450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0aace759e460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0aace759e470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0aace759e480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==3701==ABORTING

与其他溢出报错并无太大差别。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!