CTFPwn模块系列分享(二):汇编基础+Linux内存模型拆解

admin 2026-01-05 17:52:46 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文深入CTFPwn必备基础,详解x86_64汇编核心寄存器与指令,剖析Linux进程内存模型及栈帧结构。通过GDB实战演示栈帧布局,揭示栈溢出漏洞原理,旨在为新手后续学习漏洞利用与ROP打下坚实基础。 综合评分: 85 文章分类: CTF,二进制安全,漏洞分析


cover_image

CTF Pwn模块系列分享(二):汇编基础+Linux内存模型拆解

原创

龙哥网络安全

龙哥网络安全

2026年1月5日 09:59 湖南

今天进入Pwn学习的关键前置关——汇编基础+Linux进程内存模型

今天我不会讲复杂的底层原理,只挑Pwn解题必须用到的核心内容,用大白话+实操案例拆解,保证新手也能看懂、会用。毕竟这两块是后续学栈溢出、ROP的基础,打好基础,后面的学习会事半功倍!

一、先明确:为什么必须学汇编和内存模型?

在讲具体内容前,先解决大家的疑惑:Pwn是二进制漏洞利用,为什么非要学这些?

今天我们重点讲“x86_64架构”的汇编(CTF Pwn题90%以上是x86_64,也就是64位Linux环境),不用纠结32位,先把64位核心内容吃透。

二、汇编基础:新手必懂的核心寄存器+关键指令

汇编的核心是“寄存器”和“指令”——寄存器是CPU的“临时仓库”,指令是CPU的“操作命令”。新手不用记所有寄存器和指令,掌握下面这些Pwn高频内容就够了。

1. 高频寄存器:6个核心寄存器及其用途

x86_64有很多寄存器,但Pwn中最常用的是这6个,记住它们的分工:

| 寄存器 | 核心用途(Pwn重点关注) | 通俗理解 | | — | — | — | | rax | 存储函数返回值;系统调用号(比如执行/bin/sh的系统调用) | “结果存放处”+“系统调用开关” | | rdi、rsi、rdx | 依次存储函数的第1、2、3个参数(x86_64函数调用约定) | “参数传递员”,按顺序递参数 | | rbp | 栈基指针,指向当前栈帧的底部(固定不动,用来定位栈内数据) | “栈的坐标原点”,帮我们找栈里的变量、返回地址 | | rsp | 栈顶指针,指向当前栈帧的顶部(随栈操作移动,比如push/pop) | “栈的动态指针”,栈里加东西、拿东西,它就动 | | rip | 指令指针,指向CPU下一条要执行的指令地址(核心!控制程序执行流) | “程序的导航仪”,它指哪,程序就执行哪条指令 |

小提醒:寄存器名前加“r”是64位(比如rax),加“e”是32位(比如eax),Pwn中重点关注64位。

2. 关键指令:5个高频指令,理解程序核心操作

指令是CPU的操作命令,Pwn中最常用的5个指令,拆解如下:

  1. mov 目标, 源

       功能:把“源”的数据复制到“目标”(比如把内存中的数据放到寄存器,或寄存器之间传数据)。

      例子:mov rax, 0x1 → 把数字1放到rax寄存器;mov rdi, [rbp+0x8] → 把rbp+0x8地址处的内存数据放到rdi。

  2. push 数据

       功能:把数据压入栈中(栈是“先进后出”的结构),同时rsp会减8(64位系统,一个数据占8字节)。

        例子:push rbp → 把rbp寄存器的值压入栈,rsp = rsp – 8。

  3. pop 目标

        功能:把栈顶的数据弹出到“目标”,同时rsp会加8。

        例子:pop rbp → 把栈顶数据放到rbp,rsp = rsp + 8。

  4. call 函数地址

        功能:调用函数,核心操作有两个——① 把当前rip的值(下一条要执行的指令地址)压入栈(这就是“返回地址”);② 把rip指向函数地址。

        关键:Pwn中栈溢出的核心,就是修改这个“返回地址”,让程序执行我们想执行的代码!

  5. ret

        功能:函数执行结束后返回,核心操作——把栈顶的返回地址弹出到rip。

       例子:函数执行完call后,执行ret,就会把之前压入栈的返回地址弹到rip,程序回到call之后的指令继续执行。

三、Linux进程内存模型:找到漏洞的内存地图

当程序运行时,操作系统会给它分配一块独立的内存空间,这块空间按功能分成不同区域——这就是“进程内存模型”。Pwn的漏洞都和“栈”相关,所以重点讲栈,其他区域简单了解即可。

1. 内存四大核心分区(从低地址到高地址)

  1. 代码段(.text):存放程序的指令(比如我们刚才讲的mov、call指令),只读(不能修改)。
  2. 数据段(.data/.bss):存放程序的全局变量、静态变量(比如程序里定义的int a=10)。
  3. 堆(Heap):动态分配内存的区域(比如程序里用malloc申请的内存),从低地址向高地址生长。
  4. 栈(Stack):存放函数的局部变量、参数、返回地址,从高地址向低地址生长(核心!Pwn漏洞高发区)。

关键记住:栈的生长方向是“从高地址到低地址”,而push指令是“往栈里加东西”,所以push会让rsp减小;pop是“从栈里拿东西”,会让rsp增大。

2. 栈帧结构:Pwn解题的核心重点

每个函数执行时,都会在栈上开辟一块独立的空间,这就是“栈帧”。栈帧由rbp和rsp界定:rbp指向栈帧底部(固定),rsp指向栈帧顶部(动态)。

一个完整的栈帧(函数调用时)结构如下(从高地址到低地址,也就是从栈底到栈顶):

  1. 函数参数(比如调用func(a,b),a是第1参数,存在rdi;b是第2参数,存在rsi,同时会压入栈)。
  2. 返回地址(call指令压入的,是函数执行完后要回到的指令地址)。
  3. 老rbp(函数开头会执行push rbp,把上一个栈帧的rbp压入栈,方便返回后恢复)。
  4. 局部变量(函数里定义的变量,比如int x=5,会存在栈帧的这个区域)。

用通俗的图理解(简化版):

[高地址] 函数参数 → 返回地址 → 老rbp → 局部变量 [低地址]                            ↑          ↑          ↑

            rbp+0x10   rbp+0x8    rbp

Pwn核心逻辑:栈溢出漏洞,就是让“局部变量”的输入超出分配的内存空间,覆盖到“返回地址”——把返回地址改成我们想执行的代码地址,程序就会按我们的意愿执行!

四、实战小任务:用GDB看栈帧,直观理解(手把手教)

光说不练假把式,我们用一个简单的C程序,通过GDB调试,直观看看栈帧结构:

1. 准备简单C程序(保存为test.c)

#include&nbsp;<stdio.h>

void func(int a, int b) {
&nbsp; &nbsp; int x = 10; // 局部变量
&nbsp; &nbsp; printf("a=%d, b=%d\n", a, b);
}

int main() {
&nbsp; &nbsp; func(1, 2); // 调用func,参数1和2
&nbsp; &nbsp; return 0;
}
}

2. 编译程序(关闭保护,方便调试)

终端执行命令:gcc -g -fno-stack-protector -z execstack -o test test.c

参数说明:-g加调试信息;-fno-stack-protector关闭栈保护;-z execstack允许栈执行(新手调试用)。

3. GDB调试,查看栈帧

  1. 启动GDB:gdb ./test
  2. 在func函数处下断点:b func
  3. 运行程序:r
  4. 查看栈帧信息:info frame → 能看到rbp、rsp的地址,以及返回地址;
  5. 查看栈内数据:x/20wx $rsp → 查看rsp开始的20个4字节数据,能看到局部变量x、老rbp、返回地址、函数参数a和b。

通过这个操作,你能直观看到栈里的返回地址、局部变量的位置——这就是后续栈溢出漏洞利用的基础!

五、新手避坑&学习建议

  • 不要死记硬背:汇编指令和栈帧结构,结合GDB调试理解,比死记快。
  • 先掌握64位:CTF中64位Pwn题占绝大多数,32位可以后续再补。
  • 多调试简单程序:把刚才的test.c改一改(比如加更多局部变量、多嵌套几个函数),用GDB看栈帧变化,加深理解。
  • 推荐工具:除了GDB,还可以用pwndbg(GDB插件,更友好),终端执行git clone https://github.com/pwndbg/pwndbg && cd pwndbg && ./setup.sh即可安装。

六、下期预告

今天我们了解了汇编基础和栈帧结构,这是后续学习栈溢出的核心前提。下期我们将进入最关键的实战环节:栈溢出基础与ret2text实战,第一次亲手构造payload,控制程序执行流!

如果今天的内容对你有帮助,别忘了点赞、在看,转发给一起学CTF的小伙伴~

全套CTF学习资源,也可以在下面蓝色链接拿!

CTF学习资源,限时免费领取

想要的兄弟,关注我发送CTF入门,直接免费分享!前提是你得沉下心练,别拿了资料就吃灰,咱学技术,贵在坚持!

给大家准备了2套关于CTF的教程,一套是涵盖多个知识点的专题视频教程:

另一套是大佬们多年征战CTF赛事的实战经验,也是视频教程:

可以截图或者长按识别、扫码添加找我拿

龙哥网络安全

扫码添加领取

点击蓝字

关注我

计算机#计算机网安#网络安全#渗透测试#CTF#CTF比赛#赛事#计算机专业大学规划#网安零基础怎么入学#大学生


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:龙哥网络安全 龙哥网络安全《CTF Pwn模块系列分享(二):汇编基础+Linux内存模型拆解》

评论:0   参与:  0