06 - mmap 和进程的地址空间;入侵进程的地址空间 [2025 南京大学操作系统原理]
00:17:39]-[G:\姜艳艳操作系统操作空间\output\字幕\6\06 - mmap 和进程的地址空间;入侵进程的地址空间 [2025 南京大学操作系统原理].mp4]“我用 AI 写了state_dump插件,秒变可视化调试器!” 它扩展 GDB,输出寄存器和内存映射到 Markdown。例子gdb simple# 输出:寄存器(16 进制/10 进制)、内存映射表格自动模式(gdb)
06 - 程序与进程;进程管理 API [2025 南京大学操作系统原理]
[00:00:00]-[G:\姜艳艳操作系统操作空间\output\字幕\6\06 - mmap 和进程的地址空间;入侵进程的地址空间 [2025 南京大学操作系统原理].mp4]
大家好!我是姜艳艳,欢迎来到《操作系统原理》的第六课!上节课我们聊了 fork、execve 和 exit,搞清楚了进程如何创建和运行。今天我们要深入进程的地址空间,聚焦 mmap 系统调用,探索如何管理内存,甚至“入侵”其他进程的地址空间!就像我常说的,“一切都是状态机,地址空间就是状态机的内存舞台!” 这节课我会带你们从进程的初始状态入手,理解 mmap 的魔法,还会分享一些系统黑客的趣事,让你们感受到操作系统的无限可能。
我会从 execve 后的初始状态讲起,剖析 mmap 的功能,用代码和调试工具展示内存映射的奥秘,最后聊聊如何利用地址空间做有趣的事情。内容整理自字幕,保留了我的原话风格,修正了错别字,补充了逻辑和例子,用 Markdown 写成博客,方便你复习。准备好进入内存的奇妙世界了吗?咱们开始吧!
1. 复习:进程与地址空间的起点
[00:00:00]-[G:\姜艳艳操作系统操作空间\output\字幕\6\06 - mmap 和进程的地址空间;入侵进程的地址空间 [2025 南京大学操作系统原理].mp4]
图示说明:进程是一个状态机,execve 重置状态,初始化地址空间(包含代码、数据、堆、栈),mmap 修改地址空间,分配内存或映射文件。
上节课我们学了 fork 复制状态机,execve 重置状态机,exit 销毁状态机。fork 像水果叉,分裂出两个进程,寄存器和内存一模一样;execve 加载新程序,传参 argv 和 envp,从 main 开始运行。今天我们聚焦地址空间,这是进程内存的舞台。“execve 后的初始状态是什么?哪些内存可以访问?这些问题我们今天都会解开!”
补充:问 AI,“进程地址空间是什么?” 它会解释,地址空间是进程的虚拟内存范围,包含代码、数据、堆、栈等,由操作系统管理。
2. 进程地址空间的初始状态
[00:10:13]-[G:\姜艳艳操作系统操作空间\output\字幕\6\06 - mmap 和进程的地址空间;入侵进程的地址空间 [2025 南京大学操作系统原理].mp4]
图示说明:execve 初始化进程状态,寄存器 PC 指向 ELF 文件的入口点,地址空间包含代码段、数据段、堆、栈,以及系统共享的 VDSO/VDMA 区域。
寄存器的初始状态
[00:10:32]-[G:\姜艳艳操作系统操作空间\output\字幕\6\06 - mmap 和进程的地址空间;入侵进程的地址空间 [2025 南京大学操作系统原理].mp4]
[00:10:32]~[00:11:02]
“execve 后,寄存器是什么样?” 我们可以用 GDB 的 starti 命令,在程序第一条指令前暂停,打印寄存器。关键是程序计数器(PC),它指向 ELF 文件的入口点(entry point)。用 readelf -h 查看 ELF 文件,入口点地址(如 0x401620)会出现在 Entry point address 字段。
例子:
readelf -h simple
# 输出:Entry point address: 0x401620
gdb simple
(gdb) starti
(gdb) info registers
# PC 应为 0x401620
地址空间的内存布局
[00:11:02]-[G:\姜艳艳操作系统操作空间\output\字幕\6\06 - mmap 和进程的地址空间;入侵进程的地址空间 [2025 南京大学操作系统原理].mp4]
[00:11:02]~[00:33:17]
“内存是个大字节数组,地址空间是进程的舞台!” 32 位系统有 2³² 字节,64 位有 2⁶⁴ 字节,但大部分地址是“红区”(不可访问)。execve 初始化地址空间,包含:
- 代码段:只读,存储程序指令(如
main函数)。 - 数据段:读写,存储全局变量。
- 堆:动态分配(如
malloc)。 - 栈:高地址,存储局部变量和函数调用。
- VDSO/VDMA:操作系统共享的只读区域,存储系统信息(如时间、CPU 编号)。
例子:运行 simple.c:
char arr[10 * 1024 * 1024]; // 10MB 数据
int main() { return 0; }
用 GDB 查看:
gdb simple
(gdb) starti
(gdb) info proc mappings
输出显示代码段(只读)、数据段(10MB,读写)、栈(高地址)、VDSO(系统共享)等。
细节:VDSO(Virtual Dynamic Shared Object)避免频繁系统调用,直接读系统状态(如时间)。VDMA 是类似机制,优化性能。
3. mmap:改变地址空间的魔法
[00:40:31]-[G:\姜艳艳操作系统操作空间\output\字幕\6\06 - mmap 和进程的地址空间;入侵进程的地址空间 [2025 南京大学操作系统原理].mp4]
图示说明:mmap 修改地址空间,支持匿名映射(分配内存)和文件映射(映射文件)。匿名映射可创建共享内存,文件映射可加载可执行文件。
mmap 的基本功能
[00:42:27]-[G:\姜艳艳操作系统操作空间\output\字幕\6\06 - mmap 和进程的地址空间;入侵进程的地址空间 [2025 南京大学操作系统原理].mp4]
[00:42:27]~[00:45:27]
“mmap 是地址空间的魔法师!” 它修改进程的内存映射,分配新内存或映射文件。基本用法:
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
addr:指定映射起始地址(通常设为NULL,让内核选择)。length:映射大小。prot:保护权限(PROT_READ、PROT_WRITE、PROT_EXEC)。flags:映射类型(MAP_PRIVATE私有、MAP_SHARED共享、MAP_ANONYMOUS匿名)。fd:文件描述符(匿名映射设为 -1)。offset:文件偏移量。
例子:分配 4KB 内存:
#include <sys/mman.h>
#include <stdio.h>
void *p = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (p == MAP_FAILED) perror("mmap failed");
匿名映射:动态分配内存
[00:43:35]-[G:\姜艳艳操作系统操作空间\output\字幕\6\06 - mmap 和进程的地址空间;入侵进程的地址空间 [2025 南京大学操作系统原理].mp4]
[00:43:35]~[00:45:27]
“匿名映射像 malloc,但更灵活!” 它分配内存,无需关联文件,常用于堆扩展或共享内存。
例子:父子进程共享内存(参考 testkit):
void *buf = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (fork() == 0) {
strcpy(buf, "Child output");
} else {
wait(NULL);
printf("Parent reads: %s\n", buf);
}
子进程写入共享内存,父进程读取。
文件映射:内存即文件
[00:45:27]-[G:\姜艳艳操作系统操作空间\output\字幕\6\06 - mmap 和进程的地址空间;入侵进程的地址空间 [2025 南京大学操作系统原理].mp4]
[00:45:27]~[01:05:12]
“文件是字节序列,内存也是字节序列,mmap 直接把文件搬进内存!” 它映射文件内容到地址空间,省去 read 操作。
例子:映射可执行文件:
#include <sys/mman.h>
#include <fcntl.h>
int fd = open("simple", O_RDONLY);
struct stat st;
fstat(fd, &st);
void *p = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
printf("ELF magic: %x\n", *(int *)p); // 打印 0x464c457f
细节:映射可执行文件是加载器的核心,后面会详讲。
4. 观察与调试地址空间
[00:46:53]-[G:\姜艳艳操作系统操作空间\output\字幕\6\06 - mmap 和进程的地址空间;入侵进程的地址空间 [2025 南京大学操作系统原理].mp4]
图示说明:用 GDB、pmap 和自定义 state_dump 插件观察地址空间。GDB 查看内存映射,pmap 解析 /proc/PID/maps,state_dump 提供可视化输出。
pmap 与 /proc 文件系统
[00:47:19]-[G:\姜艳艳操作系统操作空间\output\字幕\6\06 - mmap 和进程的地址空间;入侵进程的地址空间 [2025 南京大学操作系统原理].mp4]
[00:47:19]~[00:54:30]
“pmap 揭秘地址空间!” 它读取 /proc/PID/maps,显示进程的内存映射。
例子:
pmap 29602
# 输出:fish 进程的映射,包括 libgcc、libc 等库
strace pmap 29602 确认它打开 /proc/29602/maps,解析后输出。
自定义 GDB 插件:state_dump
[00:17:39]-[G:\姜艳艳操作系统操作空间\output\字幕\6\06 - mmap 和进程的地址空间;入侵进程的地址空间 [2025 南京大学操作系统原理].mp4]
[00:17:39]~[01:05:12]
“我用 AI 写了 state_dump 插件,秒变可视化调试器!” 它扩展 GDB,输出寄存器和内存映射到 Markdown。
例子:
gdb simple
(gdb) source state_dump.py
(gdb) state_dump
# 输出:寄存器(16 进制/10 进制)、内存映射表格
自动模式:
(gdb) auto_state_dump
# 每次暂停(断点/单步)自动输出
细节:AI 生成的插件用 info proc mappings 获取内存映射,格式化输出。调试 mmap 示例时,确认 4KB 内存和文件映射正确添加。
5. 入侵进程地址空间:系统黑客的乐趣
[01:05:29]-[G:\姜艳艳操作系统操作空间\output\字幕\6\06 - mmap 和进程的地址空间;入侵进程的地址空间 [2025 南京大学操作系统原理].mp4]
图示说明:入侵地址空间的工具包括 ptrace(读写内存)、/proc/PID/mem(文件式访问)、process_vm_writev(批量写)。GDB 用 ptrace,金山游侠用 /proc/PID/mem。
游戏作弊器的历史
[01:07:33]-[G:\姜艳艳操作系统操作空间\output\字幕\6\06 - mmap 和进程的地址空间;入侵进程的地址空间 [2025 南京大学操作系统原理].mp4]
[01:07:33]~[01:17:57]
“想玩游戏又不想被虐?作弊器来帮忙!” 早期卡带主机的作弊器(如 Game Genie)通过硬件劫持 ROM,替换内存值(如生命值从 10 改 100)。
例子:Game Boy 作弊码 00594CB31 使玩家无敌。它修改指令或数据的立即数。
金山游侠:软件入侵
[01:17:57]-[G:\姜艳艳操作系统操作空间\output\字幕\6\06 - mmap 和进程的地址空间;入侵进程的地址空间 [2025 南京大学操作系统原理].mp4]
[01:17:57]~[01:25:10]
“金山游侠是童年神器!” 它用 /proc/PID/mem 读写进程内存,动态修改游戏变量(如金钱)。
例子:修改虚拟机中的游戏:
# 游戏显示金钱 5000
./modifier 51213 5000 # 扫描 PID 51213,找到值 5000 的地址
# 花钱到 4400
./modifier 51213 4400 # 再次扫描,缩小范围到 3 个地址
# 修改为 123456789
./modifier 51213 123456789
游戏金钱变为 123456789!
细节:通过 lseek 和 read/write 操作 /proc/PID/mem,实现内存扫描和修改。
ptrace 与 process_vm_writev
[01:24:44]-[G:\姜艳艳操作系统操作空间\output\字幕\6\06 - mmap 和进程的地址空间;入侵进程的地址空间 [2025 南京大学操作系统原理].mp4]
[01:24:44]~[01:26:29]
“ptrace 是调试神器!” 它提供 PTRACE_POKEDATA 和 PTRACE_PEEKDATA,读写进程内存,GDB 依赖它。process_vm_writev(Linux 3.2 引入)支持批量写内存,适合复杂场景。
补充:问 AI,“ptrace 如何实现调试?” 它会解释 ptrace 的跟踪和修改功能。
6. 创意与未来:从 mmap 到 DMA 外挂
[01:26:29]-[G:\姜艳艳操作系统操作空间\output\字幕\6\06 - mmap 和进程的地址空间;入侵进程的地址空间 [2025 南京大学操作系统原理].mp4]
图示说明:mmap 启发创意,如 DMA 外挂(拷贝物理内存)和视频外挂(用 FPGA 和 AI 分析 HDMI 信号,标注目标)。
DMA 外挂:现代作弊
[01:27:13]-[G:\姜艳艳操作系统操作空间\output\字幕\6\06 - mmap 和进程的地址空间;入侵进程的地址空间 [2025 南京大学操作系统原理].mp4]
[01:27:13]~[01:28:47]
“DMA 外挂防不胜防!” 它通过硬件设备直接读写物理内存,绕过操作系统检测。
例子:DMA 设备将游戏内存拷贝到独立存储,解析后修改变量(如生命值)。
视频外挂:AI 与 FPGA
[01:28:47]-[G:\姜艳艳操作系统操作空间\output\字幕\6\06 - mmap 和进程的地址空间;入侵进程的地址空间 [2025 南京大学操作系统原理].mp4]
[01:28:47]~[01:32:03]
“用 AI 做视频外挂,酷到炸!” HDMI 信号通过采集卡(如 MS2130)输入树莓派或 FPGA,AI 识别目标(敌人),在视频上叠加红框。
例子:射击游戏外挂:
- HDMI 输出到 FPGA。
- FPGA 分流信号:一路 USB 送电脑,AI 分析;一路叠加红框后输出。
- 延迟约 100ms,但效果显著。
细节:AI 可调用大模型(如 Claude 3.7)优化代码,FPGA 用 Verilog 实现信号处理。
7. 总结与展望
[01:32:03]-[G:\姜艳艳操作系统操作空间\output\字幕\6\06 - mmap 和进程的地址空间;入侵进程的地址空间 [2025 南京大学操作系统原理].mp4]
“mmap 让地址空间随心所欲,入侵地址空间开启无限可能!” 从 execve 的初始状态到 mmap 的动态修改,再到 ptrace 和 /proc/PID/mem 的黑客玩法,操作系统是创意的舞台。“用 mmap 写个加载器,试试金山游侠的原理,问 AI 如何优化 DMA 外挂!保持好奇,计算机世界没有魔法,只有你想不到的可能!”
我的期望:动手写 mmap 代码,调试地址空间,探索 System V ABI!下节课我们聊加载器和可执行文件,揭秘程序启动的最后拼图!
参考资料:
- 课程主页(实验代码下载)
- Bilibili 视频:06 - mmap 和进程的地址空间;入侵进程的地址空间
- 工具推荐:
gdb、pmap、strace、readelf - 文档:
man mmap、System V ABI
这篇博客带你掌握地址空间的魔法,希望你爱上操作系统的自由!有问题随时邮件我,或在 QQ 群讨论。让我们用代码和创意,征服系统世界!
更多推荐


所有评论(0)