06 - mmap and the process address space
06 - mmap 和 进程的地址空间
入侵进程的地址空间
1. 回顾
关于进程的第二课...
1.1. 新闻
...深度强化学习
Reinforce learning?
1.2. git init...
README.md / TODO.md..
git repo 的 初始化版本
通过 commit 进行状态的转移
everything is state machine...
1.3. 我们如何应对?
我们还得学 操作系统
操作系统依然很重要
编程语言是“可信可验证”的桥梁
Markdown,js,Python,...
操作系统是运行支撑
虚拟环境、文件系统快照、网络...
程序必须要到一个真实的环境...大语言模型终究会产生幻觉......
agent...
今天我们可以使用 docker...使用隔离机制...本地文件不受影响...
1.4. 状态机的生命周期管理 API
fork,execve 和 _exit
操作系统视角:状态机的复制、重置和删除
int pid = fork();
if (pid == -1) { // 错误
perror("fork"); goto fail;
} else if (pid == 0) { // 子进程
execve(...);
perror("execve"); exit(EXIT_FAILURE);
} else { // 父进程
...
int status;
waitpid(pid, &status, 0); // testkit.c 中有
}
2. 进程的初始状态
我们可以创建进程...然后会进行执行...
2.1. 进程 execve 后的初始状态
更深层次的理解...
寄存器
直接进行打印
内存
有点难办
可以把任何整数 cast 成 pointer
32 位 整数 - 32 位 指针
用工具,看真实系统
暂时忽略操作系统管理的状态:pid,打开的文件...
进程空间里面的某些空间(绝大部分)是不能访问的...
那么 到底哪些可以访问???
所有一切都是有答案的!
没有黑魔法
向 AI 真诚发问...就会得到进步...
2.2. 结论
进程 execve 后的初始状态
ABI 中规定的 initial state (System V ABI)
Section 3.4: “Process Initialization”
只规定了部分寄存器和栈 (argv 和 envp 中的字符串保存在栈中)
Binary 中指定的 PT_LOAD 段
内存是分成 “一段一段” 的
每一段有访问权限 (rwx)
2.3. 进程的地址空间
配合 gdb 调试器,我们甚至可以 “随时查看程序的地址空间”。这一切代码都是人工智能生成的!因为 AI 知晓几乎所有的细节,它是帮助我们理解复杂细节的利器。
root@LAPTOP-GT06V0GS:/mnt/d/CSLab/osCourse/lec6/address-space# ./alloc
mmap: 7fd2c4e88000
Read get: 2
Read get: 0
Read get: 3
root@LAPTOP-GT06V0GS:/mnt/d/CSLab/osCourse/lec6/address-space# ./mmap-demo
This is allocated memory at 0x7fe150f8a000
Mapped executable at 0x7fe150ec0000, size: 823704 bytes
First 16 bytes of executable: 7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00
root@LAPTOP-GT06V0GS:/mnt/d/CSLab/osCourse/lec6/address-space# ./simple
3. 进程的地址空间管理
3.1. 往后想一想
进程的初始状态
只有ELF 文件里声明的内存和一些操作系统分配的内存
任何其他指针的访问都是非法的
如果我们从输入读一个 size,然后 malloc(size)
内存从拿来呢?
一定有一个系统调用可以改变进程的地址空间
如果让你设计操作系统的 API
你会怎么设计?
3.2. Memory Map 系统调用
在状态机状态上增加/删除/修改一段可访问的内存
MAP_ANONYMOUS: 匿名 (申请) 内存
fd: 把文件 “搬到” 进程地址空间中 (例子:加载器)
更多的行为请参考手册 (复杂性暴增)
// 映射
void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
int munmap(void *addr, size_t length);
// 修改映射权限
int mprotect(void *addr, size_t length, int prot);
mmap 是一个非常强大的系统调用,用于将文件或设备的内存区域映射到进程的地址空间中。这允许进程像访问普通内存一样访问文件内容,而不需要显式地读写文件。
munmap 用于取消之前通过 mmap 创建的内存映射。
mprotect 用于修改已映射内存区域的保护属性。
我们可以用 pmap 命令查看进程的地址空间
(它是怎么实现的?)
3.3. 使用 mmap
Example 1: 申请大量内存空间
瞬间完成内存分配
mmap/munmap 为 malloc/free 提供了机制
libc 的大 malloc 会直接调用一次 mmap 实现
不妨 strace/gdb 看一下
Example 2: Everything is a file
映射大文件、只访问其中的一小部分
# 打开文件
with open('/dev/sda', 'rb') as fp:
# 映射文件
mm = mmap.mmap(fp.fileno(),
prot=mmap.PROT_READ, length=128 << 30)
# 打印文件前 512 字节
hexdump.hexdump(mm[:512])
mmap 本质是一个 syscalls,用于将一个文件或设备的内存区域映射到进程的地址空间中。简单来说,它允许你像访问普通内存一样访问文件内容,而不需要显式地读写文件。
高效处理大文件
按需加载
减少 I/O 操作
高效内存分配
瞬间完成内存分配
操作系统不会真的分配内存
只是做一个映射?
AI:mmap 申请内存时,不会立即分配物理内存,只有在实际访问时才会分配,因此申请大量内存时非常高效
与 malloc 的关系
内存保护
设置保护属性
老师上课尽量多的进行了示例演示...
对于 mmap 的行为我自己的理解就是,在内存空间上 绑定一些 文件,通过记录文件路径...通过 AI 还需要注意的就是映射的回收 munmap
尽量多的学习 AI 的 best practice...当然有些 OI 竞赛的高血压代码 LLM 有可能也会输出...这时候要批判看待...
4. 入侵进程的地址空间
4.1. Hacking Address Space
进程 (状态机) 在 “无情执行指令机器” 上执行
状态机是一个封闭世界
但如果允许一个进程对其他进程的地址空间有访问权?
意味着可以任意改变另一个程序的行为
听起来就很 cool
例子:我们可以改变 gdb 或 其他编译程序的内部代码
可以让你获得开挂权?...
如下
“入侵” 进程地址空间的例子
调试器 (gdb)
gdb 可以任意观测和修改程序的状态
4.2. 物理入侵进程地址空间
金手指:直接物理劫持内存
听起来很离谱,但 “卡带机” 时代的确可以做到!
可以通过直接操作硬件来读取或修改内存内容
这种技术在现代系统中仍然存在,但通常需要特定的硬件支持或内核权限。

今天我们有 Debug Registers 和 Intel Processor Trace
调试寄存器是 CPU 提供的一种机制,用于支持调试功能。
Intel 处理器提供的一种硬件跟踪功能,可以记录程序的执行路径和内存访问情况。
帮助系统工具 “合法入侵” 地址空间
:通过调试器或性能分析工具,合法地访问和修改进程的地址空间。
4.3. 物理入侵进程地址空间
Game Genie: 一个 Look-up Table (LUT)

简单、优雅:当 CPU 读地址 a 时读到 x,则替换为 y
4.4. 随着游戏越来越大
地址空间太大了,分不清哪些才是玩家属性...
包含动态分配的内存,每次地址都不一样
思路:Everything is a state machine
观察状态机的 trace,就知道哪个是金钱了
查找 + Filter
进入游戏时 exp=4950exp=4950
打了个怪 exp=5100exp=5100
符合 4950→51004950→5100 变化的内存地址是很少的
好了,出门就是满级了
4.5. 脚本的开始...
如果有一天可以接触,也是蛮有意思的...
你只要认为一件事情可以干,这件事情就可以干下去,尽管这件事情网上没有先例,没有教程...
AI 会助你完成这一切...
4.6. “外挂”
采集视频信号
采集卡 (MS2130) + 树莓派 = 外挂
用魔法打败魔法
创造变得前所未有的容易
我能否用 FPGA 设计一个电路,收到视频流,以及来自 I/O 端口的 bound-box 绘图指令,把 bound-box 绘制到视频流上输出。
总的来说是发挥想象力...看你想得到什么,然后就可以实现,换个思路,也许就会改变人类的命运...
Last updated