Skip to content
This repository was archived by the owner on Apr 7, 2026. It is now read-only.

Commit ef8393f

Browse files
committed
Add requirement and some example pictures; and some small fixes
1 parent c0849a2 commit ef8393f

4 files changed

Lines changed: 38 additions & 18 deletions

File tree

docs/lab/flowlab/problem4-8.png

79.7 KB
Loading

docs/lab/flowlab/task2-1.png

47.4 KB
Loading

docs/lab/flowlab/try_raise.png

272 KB
Loading

docs/lab/lab3.md

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
# Lab3: FlowLab
22

3-
> Deadline:2025-11-11 23:59:59
3+
> Deadline:2025-11-18 23:59:59
44
55
## 〇、实验简介
66

77
### 实验简介
88

99
栈帧与程序控制流相关实验。
1010

11-
本学期,我们仍然将金老师 ICS 第三个 Lab 回炉重造,减轻代码工作量并添加更多讲解和提示,以加深各位同学对栈帧和程序控制流的理解,并探索协程的应用,最后从宏观角度思考程序控制流的发展,丰富同学们的知识面
11+
本学期,我们依然将金老师 ICS 第三个 Lab 回炉重造,减轻代码工作量并添加更多讲解和提示,以加深各位同学对栈帧和程序控制流的理解。
1212

1313
本次Lab由五个部分组成,含四个主题:
1414

1515
- 尝试在含有漏洞的程序中实现**任意代码执行**
1616
- 学习 Canary 机制,了解栈溢出的**防御**
1717
- 在栈帧基础上探索更多有意思的功能,如**协程**
18-
- 从高处思考程序**控制流**的运行
18+
- 从高处思考程序**控制流**的运行机制,探索其发展方向
1919

2020
> [!tip]
2121
>
@@ -28,6 +28,14 @@
2828
> - `b *[address]`:直接在指定地址处设定断点(例如 `b *0x401000`
2929
> - ![设定断点](flowlab/b_gdb.png)
3030
31+
### 实验要求
32+
33+
1. Problem 需要在实验报告中作答,如有要求需附上截图;
34+
2. Task 需要在实验报告中附上代码,结果截图和**简要**的实验过程;
35+
3. **不应**修改不含 TODO 标记的代码,或添加额外的函数;
36+
4. 欢迎在实验报告中吐槽/建议/记日记(划掉
37+
5. 发挥创造力吧;)
38+
3139
## 一、危险的计算器
3240

3341
### RCE 攻击
@@ -100,7 +108,7 @@ void foo() {
100108

101109
> [!NOTE]Task 1.1 (10 pts)
102110
>
103-
> 你的任务是:利用栈溢出漏洞,控制程序执行 `./malware` 。这个“恶意程序”会检测自己的父进程调用,如果发现自己由 `dark-calc` 调用,就会输出 `You have successfully detonated the bomb! Congratulations!`,表示你已经成功完成了任务。
111+
> 你的任务是:利用栈溢出漏洞,控制程序执行 `./malware` 。这个“恶意程序”会检测自己的父进程调用,如果发现自己由 `dark-calc` 调用,就会输出 `You have successfully detonated the bomb! Congratulations!`,表示你已经成功完成了任务。在实验报告中描述你的攻击流程。
104112
105113
#### 实验步骤
106114

@@ -143,7 +151,7 @@ void foo() {
143151

144152
> [!tip]
145153
>
146-
> cmd 字符串对应地址处的值在输入完后不变。
154+
> 注意:cmd 字符串对应地址处的值在输入完后不变。
147155
>
148156
> 我们的目标类似于执行 `system("./malware")`,如果你已经构造成功了 payload 使程序执行 `system("./malware")`,但程序在 `system` 函数的内部崩溃了,这在我们的预期内。**也就是说,只需要见到 `You have successfully detonated the bomb! Congratulations!` 这一行就算通过实验。**
149157
>
@@ -159,7 +167,7 @@ void foo() {
159167

160168
> [!NOTE]Problem 1.1 (5 pts)
161169
>
162-
> 除了在报告描述你的攻击流程之外,你还需要在报告中回答以下问题:实验任务中导致溢出的函数早就成为了一个臭名昭著的函数,现如今几乎没有人会再使用它。但即使在 2025 年的今天,我们依然会看到许许多多的栈溢出、堆溢出漏洞。请你思考一下,还有什么其他的场景、函数会导致溢出?你自己是否在编程中遇到过栈溢出的情况?
170+
> 实验任务中导致溢出的函数早就成为了一个臭名昭著的函数,现如今几乎没有人会再使用它。但即使在 2025 年的今天,我们依然会看到许许多多的栈溢出、堆溢出漏洞。请你思考一下,还有什么其他的场景、函数会导致溢出?你自己是否在编程中遇到过栈溢出的情况?
163171

164172
## 二、更危险的计算器
165173

@@ -179,7 +187,7 @@ void foo() {
179187

180188
但是存在漏洞,使得我们可以编译出栈空间可执行的程序(参照[这篇文章](https://mp.weixin.qq.com/s/D43kHb5_b0U9EPt_dA4p7g))。
181189

182-
很不幸的是,上述危险的计算器的编译过程存在这样的漏洞,使这个计算器变得更加危险了。这意味着我们可以利用漏洞,在栈空间执行自己编写的简易汇编程序,例如修改一些寄存器的值之后跳转到其他地方。
190+
很不幸的是,我们编译危险的计算器时没有注意到这一点,使这个计算器变得更加危险了。这意味着我们可以在栈空间执行自己编写的简易汇编程序,例如修改一些寄存器的值之后跳转到其他地方。
183191

184192
### 实验任务
185193

@@ -189,23 +197,29 @@ void foo() {
189197

190198
> [!tip]
191199
>
192-
> 可以用与 Task 1.1 相似的方法保存 payload 并进行调试。
200+
> 可以用与 Task 1.1 相似的方法保存 payload 并在 GDB 调试。
201+
>
202+
> GDB 内,默认情况下程序的栈空间位置在**较长时间内**固定;而直接执行程序时,栈空间位置一般是随机的,且与 GDB 内不同。
193203
>
194-
>GDB 中,默认程序的栈空间位置在**一次重启期间**固定。
195204
> 我们需要在栈空间内执行代码,期望效果是**赋值输入参数****调用函数**
196205
>
197-
> 大家学过 CSAPP,打过 BombLab,想必对常用 x86-64 汇编指令的机器码有一些了解,此处给出 mov 和 jmp 指令的机器码参考
206+
> 大家已经学过 CSAPP 中有关汇编与机器码对应的知识点,此处给出 x86-64 汇编指令 mov 和 jmp 指令的机器码形式参考
198207
>
199-
> - `mov $imm, %rxx`64 位立即数移动, 7 字节):`48 c7 [Mod+Reg+R/M](1 byte) [imm](4 byte)`
208+
> - `mov $imm, %rxx`64 位立即数移动, 7 字节):`48` `c7` `[Mod+Reg+R/M]`(1 字节) `[imm]`(4 字节)
200209
> - `Mod` 指定寄存器模式(2 位,`11` 为寄存器寻址)
201210
> - `Reg` 源操作数(3 位,这里是立即数,所以置为 0
202211
> - `R/M` 指定目标寄存器(3 位);
203-
> - `jmp *%rxx` (跳转到 `rxx` 寄存器指向的地址, 2 字节):`ff [Mod+Reg+R/M](1 byte)`
212+
> - `jmp *%rxx` (跳转到 `rxx` 寄存器指向的地址, 2 字节):`ff` `[Mod+Reg+R/M]`(1 字节)
204213
> - `Mod` 指定寄存器模式(2 位,`11` 为寄存器寻址)
205214
> - `Reg` 设为 `100` 指定此指令为 `jmp` 指令(3 位,此处代表指令模式选择值)
206215
> - `R/M` 指定目标寄存器(3 位);
207216
>
208217
> <s>善用人工智能工具编写汇编/机器代码(逃</s>
218+
>
219+
> 样例截图:
220+
>
221+
> ![祝大家门门拿 A](flowlab/task2-1.png)
222+
>
209223

210224
## 三、栈溢出的防御
211225

@@ -232,13 +246,13 @@ gcc -fno-pie -no-pie -o dark-calc-my dark-calc.c
232246
233247
> [!NOTE]Problem 3.2 (5 pts)
234248
>
235-
> 尝试根据资料复原出之前实验中 `dark-calc` 的编译指令。
249+
> 尝试根据线索复原出之前实验中(漏洞百出的) `dark-calc` 的编译指令。
236250
237251
> [!tip]
238252
>
239253
> 通过**特定命令行参数**,可以不开启防御机制;
240254
>
241-
> 为触发可写栈空间漏洞,编译时包含了额外文件,不仅包含 `dark-calc.c`
255+
> 为触发可写栈空间漏洞,编译时包含了**额外文件**(在哪呢
242256
243257
## 四、栈帧的更多应用——协程
244258

@@ -357,7 +371,7 @@ funcB:
357371

358372
> [!NOTE]Problem 4.4 (2 pts)
359373
>
360-
> 在实验报告中填写你的答案:假如变量 x 被存放在栈帧上,在 restore 操作后,x 的值为 ________________ ;假如变量 x 被存放在寄存器上,在 restore 操作后,x 的值为 ________________
374+
> 在实验报告中填写答案:假如变量 x 被存放在栈帧上,在 restore 操作后,x 的值为 ________________ ;假如变量 x 被存放在寄存器上,在 restore 操作后,x 的值为 ________________
361375
362376
由于变量放在寄存器还是内存是由编译器决定的,根据编译器策略的不同,可能会导致同一份代码产生不同的运行结果。为了简化问题,我们可以做出如下限定:在 save 语句后修改过的局部变量,在 restore 操作后都是未知的,让开发者不要在 restore 之后直接使用这些变量的值。
363377

@@ -396,7 +410,7 @@ naive_func(void **p):
396410
>
397411
> 也许你在课上学过函数开头两条指令的固定格式 `push rbp; mov rbp, rsp`。但是前面所写的 naive_func 显然不遵循这样的格式,为什么这是可以的呢?
398412
399-
接下来,我们开始着手实现 save 和 restore 函数,为了实现更多后续功能,这两个函数的定义与上文所述有略微不同,请参见 API 手册
413+
接下来,我们开始着手实现 save 和 restore 函数,为了实现更多后续功能,这两个函数的定义与上文所述有略微不同,请参见 API 文档(coroutine-api.md)
400414

401415
> [!NOTE]Task 4.1 (8 pts)
402416
>
@@ -561,11 +575,15 @@ funcB:
561575
562576
> [!NOTE]Problem 4.7 (5 pts)
563577
>
564-
> 请阅读 `context.c` 中的函数 `send``yield``back_to_reality``context.h` 中对 `try``catch``throw` 的宏定义,并在报告中解释这些函数和宏定义的功能。
578+
> 请阅读 `context.c` 中的函数 `send``yield``back_to_reality`以及 `context.h` 中对 `try``catch``throw` 的宏定义,并在报告中解释这些函数和宏定义的功能。
565579
566580
> [!NOTE]Problem 4.8 (5 pts)
567581
>
568-
> 任选 test6、test7、test8 中的一个,使用 GDB 动态调试,运用 `x/10gx $rsp` 指令查看至少两种不同位置处开始的栈帧或是伪栈帧并截图,体会协程中开辟虚拟栈空间的设计。
582+
> 任选 test7、test8 中的一个,使用 GDB 动态调试,运用 `x/10gx $rsp` 指令查看默认栈帧,和协程产生的伪栈帧,体会协程中开辟虚拟栈空间的设计。
583+
>
584+
> 在报告中提交截图。
585+
>
586+
> - 参考 test6 的实验现象:![栈帧和伪栈帧](flowlab/problem4-8.png)
569587
570588
### 协程的一些实际应用
571589

@@ -731,6 +749,8 @@ def game():
731749
> 长崎·raise: 要怎么做才能回来?只要是我能做的,我什么都愿意做!
732750
>
733751
> 丰try·祥子: 你这个人,满脑子都只想着自己呢。
752+
>
753+
> ![你这个人,满脑子都只想着自己呢](flowlab/try_raise.png)
734754
735755
和其它 lab 的评分标准相同,除去 Honor Part 的内容满分为 100 分,Honor Part 只能用来抵前面报告的扣分和迟交得分。Lab 的分数上限仍为 100 分。
736756

0 commit comments

Comments
 (0)