Skip to content

Commit 5a791ff

Browse files
committed
feat: add phase 4 assembly code in bomb-lab article
1 parent 7815eb9 commit 5a791ff

1 file changed

Lines changed: 92 additions & 69 deletions

File tree

docs/notes/CSAPP/bomb-lab.md

Lines changed: 92 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ title: Bomb Lab 解題筆記
33
date: 2025-12-10
44
---
55

6-
## GDB 常用指令
6+
## :whale: GDB 常用指令
77

8-
### 控制執行
8+
### :crab: 控制執行
99
```bash
1010
break phase_1 # 在函數設中斷點
1111
break *0x400ee0 # 在特定位址設中斷點
@@ -16,7 +16,7 @@ ni # 執行一條指令(不進入函數)
1616
si # 執行一條指令(會進入函數)
1717
```
1818

19-
### 查看程式碼
19+
### :crab: 查看程式碼
2020
```bash
2121
disassemble # 看當前函數的組語
2222
disassemble phase_2 # 看指定函數的組語
@@ -26,7 +26,7 @@ ctrl + x, 再按 a # 退出 layout
2626
x/i $rip # 看當前要執行的指令
2727
```
2828

29-
### 查看資料
29+
### :crab: 查看資料
3030
```bash
3131
print $rax # 看暫存器的值(十進位)
3232
print/x $rax # 看暫存器的值(十六進位)
@@ -40,16 +40,16 @@ x/i $rip # 看記憶體內容(指令)
4040
x/8a 0x402470 # 看 8 個位址(用於 jump table)
4141
```
4242

43-
### 其他
43+
### :crab: 其他
4444
```bash
4545
quit (q) # 離開 gdb
4646
```
4747

4848
---
4949

50-
## x86-64 Assembly 基礎知識
50+
## :whale: x86-64 Assembly 基礎知識
5151

52-
### 常用暫存器與用途
52+
### :crab: 常用暫存器與用途
5353
```
5454
函數參數傳遞(calling convention):
5555
%rdi → 第 1 個參數
@@ -66,22 +66,22 @@ quit (q) # 離開 gdb
6666
%rip → instruction pointer(下一條要執行的指令)
6767
```
6868

69-
### 指令語法(AT&T 格式)
69+
### :crab: 指令語法(AT&T 格式)
7070
```assembly
7171
mov %rsp,%rsi # 把 %rsp 的值複製到 %rsi
7272
# 格式:mov 來源, 目的地
7373
add %eax,%eax # %eax = %eax + %eax(乘以 2)
7474
```
7575

76-
### 記憶體存取語法
76+
### :crab: 記憶體存取語法
7777
```assembly
7878
(%rsp) # 取 %rsp 指向的記憶體內容
7979
0x4(%rsp) # 取 %rsp + 4 的記憶體內容
8080
-0x4(%rbx) # 取 %rbx - 4 的記憶體內容
8181
0x402470(,%rax,8) # 計算:0x402470 + %rax * 8
8282
```
8383

84-
### 比較和跳躍指令
84+
### :crab: 比較和跳躍指令
8585
```assembly
8686
cmp %eax,(%rbx) # 比較 (%rbx) 和 %eax
8787
je 地址 # jump if equal(相等就跳)
@@ -91,7 +91,7 @@ ja 地址 # jump if above(無號數大於)
9191
jbe 地址 # jump if below or equal(小於等於就跳)
9292
```
9393

94-
### 如何判斷暫存器是位址還是值
94+
### :crab: 如何判斷暫存器是位址還是值
9595

9696
**關鍵:看有沒有括號**
9797
- **有括號 `()` → 當作位址使用**
@@ -110,24 +110,9 @@ jbe 地址 # jump if below or equal(小於等於就跳)
110110

111111
---
112112

113-
## Phase 1
113+
## :whale: Phase 1
114114

115115
```bash
116-
GNU gdb (Ubuntu 16.2-8ubuntu1) 16.2
117-
Copyright (C) 2024 Free Software Foundation, Inc.
118-
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
119-
This is free software: you are free to change and redistribute it.
120-
There is NO WARRANTY, to the extent permitted by law.
121-
Type "show copying" and "show warranty" for details.
122-
This GDB was configured as "x86_64-linux-gnu".
123-
Type "show configuration" for configuration details.
124-
For bug reporting instructions, please see:
125-
<https://www.gnu.org/software/gdb/bugs/>.
126-
Find the GDB manual and other documentation resources online at:
127-
<http://www.gnu.org/software/gdb/documentation/>.
128-
For help, type "help".
129-
Type "apropos word" to search for commands related to "word"...
130-
Reading symbols from bomb...
131116
(gdb) break phase_1
132117
Breakpoint 1 at 0x400ee0
133118
(gdb) run
@@ -142,6 +127,7 @@ Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
142127
Welcome to my fiendish little bomb. You have 6 phases with
143128
which to blow yourself up. Have a nice day!
144129
aaa
130+
145131
Breakpoint 1, 0x0000000000400ee0 in phase_1 ()
146132
(gdb) disassemble
147133
Dump of assembler code for function phase_1:
@@ -156,15 +142,16 @@ Dump of assembler code for function phase_1:
156142
End of assembler dump.
157143
```
158144

159-
### 解題策略
145+
### :crab: 解題策略
160146
這是最簡單的 phase,主要是字串比較。
161147

162-
### 解析步驟
148+
### :crab: 解析步驟
163149
1. **找關鍵參數**
164150
- 觀察 `mov $0x402400,%esi` 這行
165151
- `%esi` 是第二個參數,`0x402400` 是一個位址
166152

167153
2. **查看位址內容**
154+
168155
```bash
169156
(gdb) x/s 0x402400
170157
0x402400: "Border relations with Canada have never been better."
@@ -177,24 +164,9 @@ End of assembler dump.
177164
- 如果 `%eax == 0`(相等),就通過
178165
- 否則爆炸
179166

180-
## Phase 2
167+
## :whale: Phase 2
181168

182169
```bash
183-
GNU gdb (Ubuntu 8.1.1-0ubuntu1) 8.1.1
184-
Copyright (C) 2018 Free Software Foundation, Inc.
185-
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
186-
This is free software: you are free to change and redistribute it.
187-
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
188-
and "show warranty" for details.
189-
This GDB was configured as "x86_64-linux-gnu".
190-
Type "show configuration" for configuration details.
191-
For bug reporting instructions, please see:
192-
<http://www.gnu.org/software/gdb/bugs/>.
193-
Find the GDB manual and other documentation resources online at:
194-
<http://www.gnu.org/software/gdb/documentation/>.
195-
For help, type "help".
196-
Type "apropos word" to search for commands related to "word"...
197-
Reading symbols from bomb...done.
198170
(gdb) break phase_2
199171
Breakpoint 1 at 0x400efc
200172
(gdb) run < solution.txt
@@ -232,34 +204,40 @@ Dump of assembler code for function phase_2:
232204
0x0000000000400f41 <+69>: pop %rbp
233205
0x0000000000400f42 <+70>: retq
234206
End of assembler dump.
235-
236207
```
237208

238-
### 解題策略
209+
### :crab: 解題策略
210+
239211
這個 phase 檢查 6 個數字是否符合特定規律。需要理解迴圈結構。
240212

241-
### 解析步驟
213+
### :crab: 解析步驟
214+
242215
1. **理解輸入**
243216
- 函數 `read_six_numbers` 會讀取 6 個整數
244217
- 這些數字存在 stack 上(從 `%rsp` 開始,每個佔 4 bytes)
245218

246219
2. **第一個數字的檢查**
220+
247221
```assembly
248222
cmpl $0x1,(%rsp) # 比較 (%rsp) 和 1
249223
je 0x400f30 # 相等就繼續
250224
```
225+
251226
**第一個數字必須是 1**
252227

253228
3. **迴圈邏輯分析**(關鍵部分)
229+
254230
```assembly
255231
mov -0x4(%rbx),%eax # 取前一個數字
256232
add %eax,%eax # %eax = %eax + %eax(乘以 2!)
257233
cmp %eax,(%rbx) # 比較當前數字和 %eax
258234
```
235+
259236
- `add %eax,%eax` 等於把 %eax 乘以 2
260237
- 每個數字必須是前一個數字的 **2 倍**
261238

262239
4. **驗證推理**
240+
263241
```bash
264242
(gdb) x/6d $rsp # 查看輸入的 6 個數字
265243
(gdb) ni # 單步執行
@@ -274,24 +252,9 @@ End of assembler dump.
274252
- 第 5 個:8 × 2 = 16
275253
- 第 6 個:16 × 2 = 32
276254

277-
## Phase 3
255+
## :whale: Phase 3
278256

279257
```bash
280-
GNU gdb (Ubuntu 8.1.1-0ubuntu1) 8.1.1
281-
Copyright (C) 2018 Free Software Foundation, Inc.
282-
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
283-
This is free software: you are free to change and redistribute it.
284-
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
285-
and "show warranty" for details.
286-
This GDB was configured as "x86_64-linux-gnu".
287-
Type "show configuration" for configuration details.
288-
For bug reporting instructions, please see:
289-
<http://www.gnu.org/software/gdb/bugs/>.
290-
Find the GDB manual and other documentation resources online at:
291-
<http://www.gnu.org/software/gdb/documentation/>.
292-
For help, type "help".
293-
Type "apropos word" to search for commands related to "word"...
294-
Reading symbols from bomb...done.
295258
(gdb) break phase_3
296259
Breakpoint 1 at 0x400f43
297260
(gdb) run solution.txt
@@ -355,15 +318,18 @@ End of assembler dump.
355318

356319
```
357320

358-
### 解題策略
321+
### :crab: 解題策略
359322
這個 phase 使用 switch-case 結構,根據第一個數字決定第二個數字的值。有 8 組可能的答案。
360323

361-
### 解析步驟
324+
### :crab: 解析步驟
325+
362326
1. **理解輸入格式**
327+
363328
```bash
364329
(gdb) x/s 0x4025cf
365330
0x4025cf: "%d %d"
366331
```
332+
367333
- `sscanf` 讀取**兩個整數**
368334
- 參數準備:
369335
- `%rdi`:輸入字串(你打的內容)
@@ -372,16 +338,20 @@ End of assembler dump.
372338
- `%rcx`:第二個整數的儲存位址(`%rsp+12`
373339

374340
2. **第一個數字的範圍限制**
341+
375342
```assembly
376343
cmpl $0x7,0x8(%rsp) # 比較第一個數字和 7
377344
ja 0x400fad # 如果大於就爆炸
378345
```
379-
**第一個數字必須 `<=` 7**(即 0-7)
346+
347+
**第一個數字必須 `<=` 7**(即 0-7)
380348

381349
3. **Jump Table 的運作原理**
350+
382351
```assembly
383352
jmpq *0x402470(,%rax,8)
384353
```
354+
385355
這是**間接跳躍**,實現 switch-case:
386356
- `%rax` = 第一個數字(0-7)
387357
- 計算位址:`0x402470 + %rax * 8`
@@ -401,20 +371,23 @@ jmpq *0x402470(,%rax,8)
401371
```
402372

403373
4. **各個 Case 的結構**
374+
404375
每個 case 都做一樣的事:
405376
```assembly
406377
mov $某個數字,%eax # 把期望值放到 %eax
407378
jmp 0x400fbe # 跳到共同檢查點
408379
```
409380

410-
**共同檢查點:**
381+
5. **共同檢查點:**
382+
411383
```assembly
412384
cmp 0xc(%rsp),%eax # 比較 %eax 和第二個輸入 (%rsp+12)
413385
je 0x400fc9 # 相等就通過
414386
callq explode_bomb # 否則爆炸
415387
```
416388

417-
5. **找出對應關係**
389+
6. **找出對應關係**
390+
418391
從組語中可以看到 8 個 case 的期望值(十六進位):
419392

420393
| Case | 組語位置 | %eax 值(hex) | 轉成十進位 |
@@ -428,5 +401,55 @@ callq explode_bomb # 否則爆炸
428401
| 6 | +92 | 0x2aa | 682 |
429402
| 7 | +99 | 0x147 | 327 |
430403

404+
## :whale: Phase 4
405+
406+
```bash
407+
(gdb) break phase_4
408+
Breakpoint 1 at 0x40100c
409+
(gdb) run solution.txt
410+
Starting program: /home/simone/WorkSpace/ISLab/CSAPP/bomb/bomb solution.txt
411+
412+
This GDB supports auto-downloading debuginfo from the following URLs:
413+
<https://debuginfod.ubuntu.com>
414+
Enable debuginfod for this session? (y or [n]) y
415+
Debuginfod has been enabled.
416+
To make this setting permanent, add 'set debuginfod enabled on' to .gdbinit.
417+
[Thread debugging using libthread_db enabled]
418+
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
419+
Welcome to my fiendish little bomb. You have 6 phases with
420+
which to blow yourself up. Have a nice day!
421+
Phase 1 defused. How about the next one?
422+
That's number 2. Keep going!
423+
Halfway there!
424+
1
425+
426+
Breakpoint 1, 0x000000000040100c in phase_4 ()
427+
(gdb) disassemble
428+
Dump of assembler code for function phase_4:
429+
=> 0x000000000040100c <+0>: sub $0x18,%rsp
430+
0x0000000000401010 <+4>: lea 0xc(%rsp),%rcx
431+
0x0000000000401015 <+9>: lea 0x8(%rsp),%rdx
432+
0x000000000040101a <+14>: mov $0x4025cf,%esi
433+
0x000000000040101f <+19>: mov $0x0,%eax
434+
0x0000000000401024 <+24>: call 0x400bf0 <__isoc99_sscanf@plt>
435+
0x0000000000401029 <+29>: cmp $0x2,%eax
436+
0x000000000040102c <+32>: jne 0x401035 <phase_4+41>
437+
0x000000000040102e <+34>: cmpl $0xe,0x8(%rsp)
438+
0x0000000000401033 <+39>: jbe 0x40103a <phase_4+46>
439+
0x0000000000401035 <+41>: call 0x40143a <explode_bomb>
440+
0x000000000040103a <+46>: mov $0xe,%edx
441+
0x000000000040103f <+51>: mov $0x0,%esi
442+
0x0000000000401044 <+56>: mov 0x8(%rsp),%edi
443+
0x0000000000401048 <+60>: call 0x400fce <func4>
444+
0x000000000040104d <+65>: test %eax,%eax
445+
0x000000000040104f <+67>: jne 0x401058 <phase_4+76>
446+
0x0000000000401051 <+69>: cmpl $0x0,0xc(%rsp)
447+
0x0000000000401056 <+74>: je 0x40105d <phase_4+81>
448+
0x0000000000401058 <+76>: call 0x40143a <explode_bomb>
449+
0x000000000040105d <+81>: add $0x18,%rsp
450+
0x0000000000401061 <+85>: ret
451+
End of assembler dump.
452+
```
453+
431454
## x86-64 assembly cheat sheet
432455
- https://web.stanford.edu/class/cs107/resources/x86-64-reference.pdf

0 commit comments

Comments
 (0)