当前位置: 首页 > news >正文

计算机系统 C语言运行时对应内存映射 以及 各个段的数据访问下标越界产生的后果

运行时个内存区域

各内存区域的作用

常见区域(可执行程序加载到内存后)

  1. .text(代码段):函数机器码,典型权限 r-x(可读可执行,不可写)。
  2. .rodata(只读数据段):字符串字面量、const 常量等,典型权限 r–。
  3. .data(已初始化的可写全局/静态数据):如 int g = 42;,典型权限 rw-。
  4. .bss(未初始化或显式初始化为 0 的全局/静态数据):如 int g; 或 int g = 0;。文件中不占空间(NOBITS),运行时在内存中被置零。
  5. 堆(heap):malloc/new 等动态分配,进程运行中向高地址或按实现策略增长。
  6. 栈(stack):函数调用帧、本地变量,典型向低地址增长(架构相关)。

提示:现代发行版默认 PIE/ASLR 会使地址每次运行都不同;但不同段仍会处在各自映射区(见 /proc/self/maps)。如果每次想看到一样的值,需要把随机的内存地址给关闭。

代码

// regions.c
#include <stdio.h>
#include <stdlib.h>int g_uninit;                 // .bss
int g_init        = 42;       // .data
const int g_const = 7;        // 通常在 .rodata(以实际 readelf 为准)
static int g_static_uninit;   // .bss
static int g_static_init = 1; // .datavoid foo(void) {} // .text(代码地址)int main(void) {static int s_local_uninit;                    // .bssstatic int s_local_init = 3;                  // .dataint local               = 5;                  // 栈char *heap              = (char *)malloc(16); // 堆const char *lit         = "hello";            // 字符串字面量,通常在 .rodataprintf("== addresses ==\n");printf(".text   &foo             %p\n", (void *)foo);printf(".rodata lit (\"hello\")   %p\n", (void *)lit);printf(".data   &g_init          %p\n", (void *)&g_init);printf(".bss    &g_uninit        %p\n", (void *)&g_uninit);printf(".bss    &g_static_uninit %p\n", (void *)&g_static_uninit);printf(".data   &g_static_init   %p\n", (void *)&g_static_init);printf(".rodata &g_const         %p\n", (void *)&g_const);printf(".bss    &s_local_uninit  %p\n", (void *)&s_local_uninit);printf(".data   &s_local_init    %p\n", (void *)&s_local_init);printf("stack   &local           %p\n", (void *)&local);printf("heap    malloc ptr       %p\n", (void *)heap);puts("\n== first lines of /proc/self/maps ==");FILE *f = fopen("/proc/self/maps", "r");if (f) {char line[256];for (int i = 0; i < 12 && fgets(line, sizeof line, f); ++i)fputs(line, stdout);fclose(f);}free(heap);return 0;
}

编译运行命令

# 关闭 PIE 便于观察固定装载(不关也行,只是地址随机)
gcc -O0 -g -fno-pie -no-pie regions.c -o regions
./regions

运行结果

➜  week-two gcc -O0 -g -fno-pie -no-pie regions.c -o regions
➜  week-two ./regions 
== addresses ==
.text   &foo             0x401236
.rodata lit ("hello")   0x40200c
.data   &g_init          0x404070
.bss    &g_uninit        0x40408c
.bss    &g_static_uninit 0x404090
.data   &g_static_init   0x404074
.rodata &g_const         0x402008
.bss    &s_local_uninit  0x404094
.data   &s_local_init    0x404078
stack   &local           0x7fff5168e2f0
heap    malloc ptr       0x24fad2a0== first lines of /proc/self/maps ==
00400000-00401000 r--p 00000000 08:20 217890                             /home/sjk/project/dumb-bird-plan/week-two/regions
00401000-00402000 r-xp 00001000 08:20 217890                             /home/sjk/project/dumb-bird-plan/week-two/regions
00402000-00403000 r--p 00002000 08:20 217890                             /home/sjk/project/dumb-bird-plan/week-two/regions
00403000-00404000 r--p 00002000 08:20 217890                             /home/sjk/project/dumb-bird-plan/week-two/regions
00404000-00405000 rw-p 00003000 08:20 217890                             /home/sjk/project/dumb-bird-plan/week-two/regions
24fad000-24fce000 rw-p 00000000 00:00 0                                  [heap]
7f829d42b000-7f829d42e000 rw-p 00000000 00:00 0 
7f829d42e000-7f829d456000 r--p 00000000 08:20 36823                      /usr/lib/x86_64-linux-gnu/libc.so.6
7f829d456000-7f829d5eb000 r-xp 00028000 08:20 36823                      /usr/lib/x86_64-linux-gnu/libc.so.6
7f829d5eb000-7f829d643000 r--p 001bd000 08:20 36823                      /usr/lib/x86_64-linux-gnu/libc.so.6
7f829d643000-7f829d644000 ---p 00215000 08:20 36823                      /usr/lib/x86_64-linux-gnu/libc.so.6
7f829d644000-7f829d648000 r--p 00215000 08:20 36823                      /usr/lib/x86_64-linux-gnu/libc.so.6

结果解析

对于/proc/self/maps

/proc/self/maps 是一个特殊的虚拟文件,它显示了当前进程的内存映射布局。这是 Linux 系统中非常重要的调试和诊断工具。

每一行有6个字段

地址范围 权限 偏移量 设备号 inode 文件路径/区域名

程序虚拟内存布局图

地址范围(大致)权限区域/段具体内容(对应你代码的变量/函数)
0x00400000-0x00401000r–pELF headerELF 文件头 / 元数据
0x00401000-0x00402000r-xp.text程序代码,foo(0x401236)、main
0x00402000-0x00403000r–p.rodata字符串 "hello"(0x40200c),g_const(0x402008)
0x00403000-0x00404000r–p只读辅助段可能是 .eh_frame、调试信息等
0x00404000-0x00405000rw-p.data + .bssg_init(0x404070),g_static_init(0x404074),g_uninit(0x40408c),g_static_uninit(0x404090),s_local_init(0x404078),s_local_uninit(0x404094)
0x024fad000-0x24fce000rw-p[heap]malloc 分配的内存 (heap=0x24fad2a0)
0x7fff5168e000...rw-p[stack]局部变量 local(0x7fff5168e2f0),函数栈帧
0x7f829d42e000...r-x/r–libc.so.6C 标准库代码和数据

对照说明

  • .text (代码段)

    • /proc/self/maps00401000-00402000 r-xp
    • 你的 foo 函数地址:0x401236 ✅ 落在 .text 段范围内
  • .rodata (只读数据段)

    • /proc/self/maps00402000-00403000 r--p
    • "hello" 地址:0x40200c
    • g_const 地址:0x402008
  • .data/.bss (已初始化/未初始化全局或静态变量)

    • /proc/self/maps00404000-00405000 rw-p
    • g_init=42 地址:0x404070
    • g_uninit 地址:0x40408c
    • 其它静态变量也都在这里
  • 堆 (heap)

    • /proc/self/maps[heap] 024fad000-024fce000
    • malloc 返回的地址:0x24fad2a0 ✅ 在范围内
  • 栈 (stack)

    • /proc/self/maps 没截到,但你打印 local 的地址:0x7fff5168e2f0,典型高地址区域
    • 实际会在 [stack] 段(7fff...

各个段的数据越界情况

代码

// oob_lab.c
// 演示在 .rodata / .data / .bss / heap / stack 上的数组越界行为
// 编译建议:见文末
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>#define SEP(name) printf("\n===== %s =====\n", name)// -------- 全局区:.data / .bss / .rodata 准备 --------
int g_data_arr[4] = {1, 2, 3, 4}; // .data(已初始化)
int g_bss_arr[4];                 // .bss(未初始化,运行时清零)// rodata:字符串字面量通常在 .rodata(只读页)
const char *g_lit        = "ABC";            // 指向 .rodata
const int g_const_arr[4] = {10, 20, 30, 40}; // 典型在 .rodata(实现相关)// 防止编译器过度优化
volatile int sink;static void dump32(const char *tag, const int *p, size_t n) {printf("%s:", tag);for (size_t i = 0; i < n; ++i)printf(" %d", p[i]);printf("\n");
}static void dump_hex(const char *tag, const unsigned char *p, size_t n) {printf("%s:", tag);for (size_t i = 0; i < n; ++i)printf(" %02X", p[i]);printf("\n");
}// -------- 1) rodata 越界 --------
static void test_rodata(void) {SEP("rodata (只读段) 越界");printf("g_lit=\"%s\" @ %p\n", g_lit, (void *)g_lit);printf("g_const_arr @ %p\n", (void *)g_const_arr);// 1) 读越界:UB(可能读到邻接只读对象或触发保护)// 读一般不会立刻崩,但完全未定义int oob_read = g_const_arr[10]; // 明显越界读printf("OOB read g_const_arr[10] = %d (UB!)\n", oob_read);sink = oob_read;// 2) 写越界:对只读页写 -> 通常立即 Segmentation Fault// char* 指向字符串字面量(只读),写就崩printf("try write g_lit[0]...\n");// 把 const 去掉故意制造未定义写入(危险演示)char *w = (char *)g_lit;w[0]    = 'X';                                // 典型直接 SIGSEGVprintf("after write: g_lit=\"%s\"\n", g_lit); // 大概率到不了这里
}// -------- 2) .data 越界 --------
static void test_data(void) {SEP(".data 越界");dump32("before g_data_arr", g_data_arr, 4);// 写后越界(正向)g_data_arr[6] = 777; // 覆盖相邻全局对象或运行时元数据,通常不会立刻崩 -> 静默破坏printf("wrote g_data_arr[6]=777 (UB)\n");dump32("after g_data_arr", g_data_arr, 4);// 读前越界(负向)int v = (&g_data_arr[0])[-2];printf("read g_data_arr[-2]=%d (UB)\n", v);sink = v;
}// -------- 3) .bss 越界 --------
static void test_bss(void) {SEP(".bss 越界");dump32("before g_bss_arr", g_bss_arr, 4);g_bss_arr[5] = 888; // 同样是静默破坏,影响永久且难排查printf("wrote g_bss_arr[5]=888 (UB)\n");dump32("after g_bss_arr", g_bss_arr, 4);
}// -------- 4) heap 越界 --------
static void test_heap(void) {SEP("heap 越界");size_t n         = 16;unsigned char *p = (unsigned char *)malloc(n);if (!p) {perror("malloc");exit(1);}memset(p, 0xAA, n);dump_hex("heap before", p, n);// 后溢出:写超 16 字节(典型:破坏 malloc 元数据或邻接块)for (size_t i = 0; i < n + 16; ++i)p[i] = (unsigned char)i;printf("wrote %zu bytes (OOB by +16)\n", n + 16);dump_hex("heap after (first 24 bytes)", p, 24); // 访问更大也会 UB// 释放时 glibc 可能检测到破坏并在 free() 崩溃free(p);printf("free done (若无崩溃不代表没问题)\n");
}// -------- 5) stack 越界 --------
static void test_stack(void) {SEP("stack 越界");volatile int guard = 0x12345678; // 看是否被覆盖unsigned char buf[8];memset((void *)buf, 0xCC, sizeof buf);dump_hex("stack buf before", buf, sizeof buf);// 大幅越界写,可能覆盖栈金丝雀/返回地址// 开启 -fstack-protector-strong 时,函数返回前可能检测到溢出并 abortfor (int i = 0; i < 40; ++i)((unsigned char *)buf)[i] = (unsigned char)i;dump_hex("stack buf after", buf, sizeof buf); // 访问 buf 仍然安全,但越界已发生printf("guard=0x%X (可能被覆盖)\n", guard);
}// -------- 6) 典型“越一”的 off-by-one --------
static void test_off_by_one(void) {SEP("off-by-one(越一)");char s[4] = "hey"; // 'h','e','y','\0'// 正确的末端是 s[3] == '\0'// 写 s[4] 就是越一:常见 bugprintf("before s=\"%s\"\n", s);s[4] = '!'; // UBprintf("after  s=\"%s\" (UB)\n", s);
}int main(int argc, char **argv) {if (argc < 2) {printf("用法: %s {rodata|data|bss|heap|stack|offby1}\n", argv[0]);printf("建议先用 ASan 跑:见文末编译参数\n");return 0;}if (!strcmp(argv[1], "rodata"))test_rodata();else if (!strcmp(argv[1], "data"))test_data();else if (!strcmp(argv[1], "bss"))test_bss();else if (!strcmp(argv[1], "heap"))test_heap();else if (!strcmp(argv[1], "stack"))test_stack();else if (!strcmp(argv[1], "offby1"))test_off_by_one();else {fprintf(stderr, "未知用例: %s\n", argv[1]);return 2;}return 0;
}

编译命令

gcc -O0 -g -fno-omit-frame-pointer \-fsanitize=address,undefined \oob_lab.c -o oob_lab# 逐个执行(部分用例可能直接崩溃/abort)
./oob_lab rodata
./oob_lab data
./oob_lab bss
./oob_lab heap
./oob_lab stack
./oob_lab offby1

输出结果

===== rodata (只读段) 越界 =====
g_lit="ABC" @ 0x56257a4e6020
g_const_arr @ 0x56257a4e6060
oob_lab.c:45:31: runtime error: index 10 out of bounds for type 'int [4]'
OOB read g_const_arr[10] = 0 (UB!)
try write g_lit[0]...
AddressSanitizer:DEADLYSIGNAL
=================================================================
==58601==ERROR: AddressSanitizer: SEGV on unknown address 0x56257a4e6020 (pc 0x56257a4e47fe bp 0x7fffc07973f0 sp 0x7fffc07973e0 T0)
==58601==The signal is caused by a WRITE memory access.#0 0x56257a4e47fe in test_rodata /home/sjk/project/dumb-bird-plan/week-two/oob_lab.c:54#1 0x56257a4e52e6 in main /home/sjk/project/dumb-bird-plan/week-two/oob_lab.c:140#2 0x7f31f560cd8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58#3 0x7f31f560ce3f in __libc_start_main_impl ../csu/libc-start.c:392#4 0x56257a4e43e4 in _start (/home/sjk/project/dumb-bird-plan/week-two/oob_lab+0x43e4)AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/sjk/project/dumb-bird-plan/week-two/oob_lab.c:54 in test_rodata
==58601==ABORTING===== .data 越界 =====
before g_data_arr: 1 2 3 4
oob_lab.c:63:15: runtime error: index 6 out of bounds for type 'int [4]'
oob_lab.c:63:19: runtime error: store to address 0x556b0f050038 with insufficient space for an object of type 'int'
0x556b0f050038: note: pointer points here00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00^ 
=================================================================
==58603==ERROR: AddressSanitizer: global-buffer-overflow on address 0x556b0f050038 at pc 0x556b0f04b8f4 bp 0x7ffd02764590 sp 0x7ffd02764580
WRITE of size 4 at 0x556b0f050038 thread T0#0 0x556b0f04b8f3 in test_data /home/sjk/project/dumb-bird-plan/week-two/oob_lab.c:63#1 0x556b0f04c38e in main /home/sjk/project/dumb-bird-plan/week-two/oob_lab.c:142#2 0x7fdc89e5fd8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58#3 0x7fdc89e5fe3f in __libc_start_main_impl ../csu/libc-start.c:392#4 0x556b0f04b3e4 in _start (/home/sjk/project/dumb-bird-plan/week-two/oob_lab+0x43e4)0x556b0f050038 is located 8 bytes to the right of global variable 'g_data_arr' defined in 'oob_lab.c:13:5' (0x556b0f050020) of size 16
0x556b0f050038 is located 40 bytes to the left of global variable '*.Lubsan_type0' defined in 'oob_lab.c' (0x556b0f050060) of size 16
SUMMARY: AddressSanitizer: global-buffer-overflow /home/sjk/project/dumb-bird-plan/week-two/oob_lab.c:63 in test_data
Shadow bytes around the buggy address:0x0aade1e01fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x0aade1e01fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x0aade1e01fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x0aade1e01fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x0aade1e01ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0aade1e02000: 00 00 00 00 00 00 f9[f9]f9 f9 f9 f9 00 00 f9 f90x0aade1e02010: f9 f9 f9 f9 00 00 00 02 f9 f9 f9 f9 00 02 f9 f90x0aade1e02020: f9 f9 f9 f9 00 06 f9 f9 f9 f9 f9 f9 00 03 f9 f90x0aade1e02030: f9 f9 f9 f9 00 02 f9 f9 f9 f9 f9 f9 00 00 04 f90x0aade1e02040: f9 f9 f9 f9 00 07 f9 f9 f9 f9 f9 f9 00 05 f9 f90x0aade1e02050: f9 f9 f9 f9 00 f9 f9 f9 f9 f9 f9 f9 00 00 f9 f9
Shadow byte legend (one shadow byte represents 8 application bytes):Addressable:           00Partially addressable: 01 02 03 04 05 06 07 Heap left redzone:       faFreed heap region:       fdStack left redzone:      f1Stack mid redzone:       f2Stack right redzone:     f3Stack after return:      f5Stack use after scope:   f8Global redzone:          f9Global init order:       f6Poisoned by user:        f7Container overflow:      fcArray cookie:            acIntra object redzone:    bbASan internal:           feLeft alloca redzone:     caRight alloca redzone:    cbShadow gap:              cc
==58603==ABORTING===== .bss 越界 =====
before g_bss_arr: 0 0 0 0
oob_lab.c:77:14: runtime error: index 5 out of bounds for type 'int [4]'
oob_lab.c:77:18: runtime error: store to address 0x55f2d56366d4 with insufficient space for an object of type 'int'
0x55f2d56366d4: note: pointer points here00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00^ 
=================================================================
==58604==ERROR: AddressSanitizer: global-buffer-overflow on address 0x55f2d56366d4 at pc 0x55f2d562eaf5 bp 0x7ffd8aaa4240 sp 0x7ffd8aaa4230
WRITE of size 4 at 0x55f2d56366d4 thread T0#0 0x55f2d562eaf4 in test_bss /home/sjk/project/dumb-bird-plan/week-two/oob_lab.c:77#1 0x55f2d562f436 in main /home/sjk/project/dumb-bird-plan/week-two/oob_lab.c:144#2 0x7f0b3cb17d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58#3 0x7f0b3cb17e3f in __libc_start_main_impl ../csu/libc-start.c:392#4 0x55f2d562e3e4 in _start (/home/sjk/project/dumb-bird-plan/week-two/oob_lab+0x43e4)0x55f2d56366d4 is located 4 bytes to the right of global variable 'g_bss_arr' defined in 'oob_lab.c:14:5' (0x55f2d56366c0) of size 16
0x55f2d56366d4 is located 44 bytes to the left of global variable 'sink' defined in 'oob_lab.c:21:14' (0x55f2d5636700) of size 4
SUMMARY: AddressSanitizer: global-buffer-overflow /home/sjk/project/dumb-bird-plan/week-two/oob_lab.c:77 in test_bss
Shadow bytes around the buggy address:0x0abedaabec80: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f90x0abedaabec90: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f90x0abedaabeca0: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f90x0abedaabecb0: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f90x0abedaabecc0: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
=>0x0abedaabecd0: f9 f9 f9 f9 00 00 00 00 00 00[f9]f9 f9 f9 f9 f90x0abedaabece0: 04 f9 f9 f9 f9 f9 f9 f9 00 00 00 00 00 00 00 000x0abedaabecf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x0abedaabed00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x0abedaabed10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x0abedaabed20: 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:           00Partially addressable: 01 02 03 04 05 06 07 Heap left redzone:       faFreed heap region:       fdStack left redzone:      f1Stack mid redzone:       f2Stack right redzone:     f3Stack after return:      f5Stack use after scope:   f8Global redzone:          f9Global init order:       f6Poisoned by user:        f7Container overflow:      fcArray cookie:            acIntra object redzone:    bbASan internal:           feLeft alloca redzone:     caRight alloca redzone:    cbShadow gap:              cc
==58604==ABORTING===== heap 越界 =====
heap before: AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA
=================================================================
==58605==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000020 at pc 0x556ceb439c89 bp 0x7ffc2b185390 sp 0x7ffc2b185380
WRITE of size 1 at 0x602000000020 thread T0#0 0x556ceb439c88 in test_heap /home/sjk/project/dumb-bird-plan/week-two/oob_lab.c:96#1 0x556ceb43a4de in main /home/sjk/project/dumb-bird-plan/week-two/oob_lab.c:146#2 0x7f2557d64d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58#3 0x7f2557d64e3f in __libc_start_main_impl ../csu/libc-start.c:392#4 0x556ceb4393e4 in _start (/home/sjk/project/dumb-bird-plan/week-two/oob_lab+0x43e4)0x602000000020 is located 0 bytes to the right of 16-byte region [0x602000000010,0x602000000020)
allocated by thread T0 here:#0 0x7f255864d887 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145#1 0x556ceb439b6f in test_heap /home/sjk/project/dumb-bird-plan/week-two/oob_lab.c:86#2 0x556ceb43a4de in main /home/sjk/project/dumb-bird-plan/week-two/oob_lab.c:146#3 0x7f2557d64d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58SUMMARY: AddressSanitizer: heap-buffer-overflow /home/sjk/project/dumb-bird-plan/week-two/oob_lab.c:96 in test_heap
Shadow bytes around the buggy address:0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fa 00 00[fa]fa fa fa fa fa fa fa fa fa fa fa0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa0x0c047fff8050: 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:           00Partially addressable: 01 02 03 04 05 06 07 Heap left redzone:       faFreed heap region:       fdStack left redzone:      f1Stack mid redzone:       f2Stack right redzone:     f3Stack after return:      f5Stack use after scope:   f8Global redzone:          f9Global init order:       f6Poisoned by user:        f7Container overflow:      fcArray cookie:            acIntra object redzone:    bbASan internal:           feLeft alloca redzone:     caRight alloca redzone:    cbShadow gap:              cc
==58605==ABORTING===== stack 越界 =====
stack buf before: CC CC CC CC CC CC CC CC
oob_lab.c:116:35: runtime error: store to address 0x7ffc6dccc3c8 with insufficient space for an object of type 'unsigned char'
0x7ffc6dccc3c8: note: pointer points here04 05 06 07  ea f9 e0 84 e4 7f 00 00  28 00 00 00 30 00 00 00  b0 c4 cc 6d fc 7f 00 00  f0 c3 cc 6d^ 
=================================================================
==58617==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffc6dccc3c8 at pc 0x5616b263bee2 bp 0x7ffc6dccc350 sp 0x7ffc6dccc340
WRITE of size 1 at 0x7ffc6dccc3c8 thread T0#0 0x5616b263bee1 in test_stack /home/sjk/project/dumb-bird-plan/week-two/oob_lab.c:116#1 0x5616b263c586 in main /home/sjk/project/dumb-bird-plan/week-two/oob_lab.c:148#2 0x7fe484dd8d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58#3 0x7fe484dd8e3f in __libc_start_main_impl ../csu/libc-start.c:392#4 0x5616b263b3e4 in _start (/home/sjk/project/dumb-bird-plan/week-two/oob_lab+0x43e4)Address 0x7ffc6dccc3c8 is located in stack of thread T0 at offset 72 in frame#0 0x5616b263bd11 in test_stack /home/sjk/project/dumb-bird-plan/week-two/oob_lab.c:106This frame has 2 object(s):[48, 52) 'guard' (line 108)[64, 72) 'buf' (line 109) <== Memory access at offset 72 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /home/sjk/project/dumb-bird-plan/week-two/oob_lab.c:116 in test_stack
Shadow bytes around the buggy address:0x10000db91820: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10000db91830: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10000db91840: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10000db91850: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10000db91860: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x10000db91870: f1 f1 f1 f1 f1 f1 04 f2 00[f3]f3 f3 00 00 00 000x10000db91880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10000db91890: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10000db918a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10000db918b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10000db918c0: 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:           00Partially addressable: 01 02 03 04 05 06 07 Heap left redzone:       faFreed heap region:       fdStack left redzone:      f1Stack mid redzone:       f2Stack right redzone:     f3Stack after return:      f5Stack use after scope:   f8Global redzone:          f9Global init order:       f6Poisoned by user:        f7Container overflow:      fcArray cookie:            acIntra object redzone:    bbASan internal:           feLeft alloca redzone:     caRight alloca redzone:    cbShadow gap:              cc
==58617==ABORTING===== off-by-one(越一) =====
before s="hey"
oob_lab.c:129:6: runtime error: index 4 out of bounds for type 'char [4]'
oob_lab.c:129:10: runtime error: store to address 0x7ffddb739a14 with insufficient space for an object of type 'char'
0x7ffddb739a14: note: pointer points here68 65 79 00 30 00 00 00  f0 9a 73 db fd 7f 00 00  30 9a 73 db fd 7f 00 00  00 d0 79 72 9d b7 12 a9^ 
=================================================================
==58618==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffddb739a14 at pc 0x5617592bb12f bp 0x7ffddb7399e0 sp 0x7ffddb7399d0
WRITE of size 1 at 0x7ffddb739a14 thread T0#0 0x5617592bb12e in test_off_by_one /home/sjk/project/dumb-bird-plan/week-two/oob_lab.c:129#1 0x5617592bb62e in main /home/sjk/project/dumb-bird-plan/week-two/oob_lab.c:150#2 0x7f4597a05d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58#3 0x7f4597a05e3f in __libc_start_main_impl ../csu/libc-start.c:392#4 0x5617592ba3e4 in _start (/home/sjk/project/dumb-bird-plan/week-two/oob_lab+0x43e4)Address 0x7ffddb739a14 is located in stack of thread T0 at offset 36 in frame#0 0x5617592bafde in test_off_by_one /home/sjk/project/dumb-bird-plan/week-two/oob_lab.c:123This frame has 1 object(s):[32, 36) 's' (line 125) <== Memory access at offset 36 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /home/sjk/project/dumb-bird-plan/week-two/oob_lab.c:129 in test_off_by_one
Shadow bytes around the buggy address:0x10003b6df2f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10003b6df300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10003b6df310: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10003b6df320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10003b6df330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1
=>0x10003b6df340: f1 f1[04]f3 f3 f3 00 00 00 00 00 00 00 00 00 000x10003b6df350: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10003b6df360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10003b6df370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10003b6df380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x10003b6df390: 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:           00Partially addressable: 01 02 03 04 05 06 07 Heap left redzone:       faFreed heap region:       fdStack left redzone:      f1Stack mid redzone:       f2Stack right redzone:     f3Stack after return:      f5Stack use after scope:   f8Global redzone:          f9Global init order:       f6Poisoned by user:        f7Container overflow:      fcArray cookie:            acIntra object redzone:    bbASan internal:           feLeft alloca redzone:     caRight alloca redzone:    cbShadow gap:              cc
==58618==ABORTING

这个会对其进行越界检查和未定义行为的越界检查,可以直接用这个编译命令

gcc -O0 -g ./oob_lab.c -o no_warning 

rodata

➜  week-two ./no_warning rodata===== rodata (只读段) 越界 =====
g_lit="ABC" @ 0x55d26c244010
g_const_arr @ 0x55d26c244020
OOB read g_const_arr[10] = 0 (UB!)
try write g_lit[0]...
[1]    55825 segmentation fault (core dumped)  ./no_warning rodata

data

➜  week-two ./no_warning data  ===== .data 越界 =====
before g_data_arr: 1 2 3 4
wrote g_data_arr[6]=777 (UB)
after g_data_arr: 1 2 3 4
read g_data_arr[-2]=-821252088 (UB)

bss

➜  week-two ./no_warning bss   ===== .bss 越界 =====
before g_bss_arr: 0 0 0 0
wrote g_bss_arr[5]=888 (UB)
after g_bss_arr: 0 0 0 0

heap

➜  week-two ./no_warning heap===== heap 越界 =====
heap before: AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA
wrote 32 bytes (OOB by +16)
heap after (first 24 bytes): 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17
free done (若无崩溃不代表没问题)

stack

➜  week-two ./no_warning stack   ===== stack 越界 =====
stack buf before: CC CC CC CC CC CC CC CC
stack buf after: 00 01 02 03 04 05 06 07
guard=0x12345678 (可能被覆盖)
*** stack smashing detected ***: terminated
[1]    60115 IOT instruction (core dumped)  ./no_warning stack
➜  week-two 

字符串没了\0

➜  week-two ./no_warning offby1===== off-by-one(越一) =====
before s="hey"
after  s="hey" (UB)
*** stack smashing detected ***: terminated
[1]    60578 IOT instruction (core dumped)  ./no_warning offby1
http://www.dtcms.com/a/349172.html

相关文章:

  • Delphi 12 基于 Indy 的 WebServer 的 https 实现的问题
  • HiRAG:用分层知识图解决复杂推理问题
  • ruoyi框架角色分配用户
  • imx6ull-驱动开发篇38——Linux INPUT 子系统
  • leetcode_189 轮转数组
  • 什么嵌入式接入大模型:第二篇基于 STM32 ESP32 的社会服务助手
  • AI重塑跨境电商:选品成功率提升53%+物流效率加快34%,多语种运营成破局关键
  • String的intern方法
  • 数据库服务优化设置
  • nano命令使用方法
  • 备考NCRE三级信息安全技术 --- L1 信息安全保障概述
  • 自编 C# 颜色命名和色彩显示,使用 DataGridView 展示颜色命名、RGB值
  • 推进数据成熟度旅程的 3 个步骤
  • 基于 MATLAB 的信号处理实战:滤波、傅里叶变换与频谱分析
  • 什么是IP代理
  • 智慧农业病虫害监测误报率↓82%!陌讯多模态融合算法实战解析
  • 基于微信小程序校园微店源码
  • 电力电子simulink练习10:反激Flyback电路搭建
  • [leetcode] - 不定长滑动窗口
  • 深度学习卷积神经网络项目实战
  • 电容触控:自电容 vs 互电容
  • Rust 登堂 生命周期(一)
  • 内网后渗透攻击--域控制器安全(1)
  • 控制启动过程
  • 【typenum】 25 去除无符号整数前导零的特性(private.rs片段)
  • 重塑招聘战场:AI得贤招聘官AI面试智能体6.3如何用“精准”重新定义人才筛选?
  • C++(String):
  • 2025 年 8 月 22 日科技前沿:技术突破与范式跃迁的交汇点
  • golang1 专栏导学
  • 算法题(190):食物链(带权并查集)