Bomb Lab

Last updated on February 8, 2024

gdb 基本使用

参考书 p194

disassemble …

break …

nexti
stepi

continue

x /FMT ADDRESS
print EXP

run ARGS

1 字符串比较

layout asm

disas phase_1

调用 strings_not_equal
要求返回 0 - equal

x /s 0x4024c0
“I am not part of the problem. I am a Republican.”
将其写入 ans.txt

break phase_1
run ans.txt
nexti
print $eax

2 循环

disas phase_2

调用 read_six_numbers:

1
mov    $0x4027b5,%esi

x /s 0x4027b5
“%d %d %d %d %d %d”

调用 sscanf:

%rdi %rsi %rdx %rcx %r8 %r9 (%rsp) (%rsp+8)
str fmt %rsp %rsp + 4 %rsp + 8 %rsp + 12 %rsp + 16 %rsp + 20

循环:第一个数为 1,后面依次翻倍
1 2 4 8 16 32

3 条件/分支

disas phase_3

调用 sscanf:

%rdi %rsi %rdx %rcx
str fmt %rsp + 12 %rsp + 8

x /s 0x4027c1
“%d %d”

1
2
cmpl   $0x7,0xc(%rsp)
ja

第一个数 <= 7

1
jmpq   *0x402520(,%rax,8)

不妨令第一个数 = 1
x /x 0x402528
0x00400fc9

第二个数 0x52

4 递归调用和栈

disas phase_4

同 3,调用 sscanf:

%rdi %rsi %rdx %rcx
str fmt %rsp + 12 %rsp + 8

x /s 0x4027c1
“%d %d”

1
2
cmpl   $0xe,0xc(%rsp)
jbe

第一个数 <= 14

调用 func4:

%rdi %rsi %rdx
第一个数 0 14

disas func4

递归调用

1
cmp    $0xf,%eax

要求返回值为 f
第一个数 = 5

1
cmpl   $0xf,0x8(%rsp)

第二个数 = f

5 指针

disas phase_5

调用 string_length

1
2
cmp    $0x6,%eax
je

要求字符串长度为 6

进入循环:
循环 6 次,结果 %edx=0x37

1
2
3
movzbl (%rbx,%rax,1),%ecx
and $0xf,%ecx
add 0x402560(,%rcx,4),%edx

x /6x 0x402560
2 a 6 1 c 10

16+12+10+10+6+1=55
ASCII 码末四位作为索引 5 4 1 1 2 3
edaabc

6 链表/指针/结构

disas phase_6

调用 read_six_numbers
放到从 %rsp+0x30 开始处

大循环 1:
六个数都不同,并且均 <= 6

循环 2:
x /24 0x6042f0

1
2
3
4
5
6
7
8
9
10
11
12
13
0x6042f0 <node1>:       0x00000271      0x00000001      0x00604300      0x00000000
0x604300 <node2>: 0x000002f2 0x00000002 0x00604310 0x00000000
0x604310 <node3>: 0x00000111 0x00000003 0x00604320 0x00000000
0x604320 <node4>: 0x00000231 0x00000004 0x00604330 0x00000000
0x604330 <node5>: 0x0000016e 0x00000005 0x00604340 0x00000000
0x604340 <node6>: 0x0000022f 0x00000006 0x00000000 0x00000000

0x6042f0 <node1>: 625 1 6308608 0
0x604300 <node2>: 754 2 6308624 0
0x604310 <node3>: 273 3 6308640 0
0x604320 <node4>: 561 4 6308656 0
0x604330 <node5>: 366 5 6308672 0
0x604340 <node6>: 559 6 0 0

struct 链表:

1
2
3
4
5
struct Node{
int val;
int ordinal;
struct Node* next;
}

struct 链表中 6 个 struct 的地址,按照输入数字的顺序,顺着放到 %rsp +

循环 3:
x /12 0x7fffffffe660
0x7fffffffe660: 6308608 0 6308592 0
0x7fffffffe670: 6308640 0 6308672 0
0x7fffffffe680: 6308656 0 6308624 0

重排链表

循环 4:
x /24x 0x6042f0

1
2
3
4
5
6
0x6042f0 <node1>:       0x00000271      0x00000001      0x00604320      0x00000000
0x604300 <node2>: 0x000002f2 0x00000002 0x006042f0 0x00000000
0x604310 <node3>: 0x00000111 0x00000003 0x00000000 0x00000000
0x604320 <node4>: 0x00000231 0x00000004 0x00604340 0x00000000
0x604330 <node5>: 0x0000016e 0x00000005 0x00604310 0x00000000
0x604340 <node6>: 0x0000022f 0x00000006 0x00604330 0x00000000

验证每个 struct 的 val >= 链表中下一项的 val
val 从大到小:2 1 4 6 5 3

secret phase

在 phase_defused 中调了 secret_phase:
b *0x401772

(gdb) x /s 0x402660
0x402660: “Curses, you’ve found the secret phase!”
(gdb) x /s 0x402688
0x402688: “But finding it and solving it are quite different…”
找对了位置 🤗

先调用 sscanf:
(gdb) x /s 0x40280b
0x40280b: “%d %d %s”
三个输入

phase_3 or phase_4? 与 phase_4 读取的 %rdi 地址相同
(gdb) x /s 0x6048b0
0x6048b0 <input_strings+240>: “5 15 DrEvil”

(gdb) x /s 0x402814
0x402814: “DrEvil”
取第三个输入判等

综上,在 phase_4 的输入之后再补一个 DrEvil


secret_phase:

调用 read_line,读入一个字符串
调用 strtol,解析为十进制 num
num - 1 <= 1000

调用 fun7:

%rdi %rsi
0x604110 num

要求返回值为 5

fun7:
递归调用,比较 num 与 (%rdi)+

x /100xg 0x604110

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
0x604110 <n1>:  0x0000000000000024      0x0000000000604130
0x604120 <n1+16>: 0x0000000000604150 0x0000000000000000
0x604130 <n21>: 0x0000000000000008 0x00000000006041b0
0x604140 <n21+16>: 0x0000000000604170 0x0000000000000000
0x604150 <n22>: 0x0000000000000032 0x0000000000604190
0x604160 <n22+16>: 0x00000000006041d0 0x0000000000000000
0x604170 <n32>: 0x0000000000000016 0x0000000000604290
0x604180 <n32+16>: 0x0000000000604250 0x0000000000000000
0x604190 <n33>: 0x000000000000002d 0x00000000006041f0
0x6041a0 <n33+16>: 0x00000000006042b0 0x0000000000000000
0x6041b0 <n31>: 0x0000000000000006 0x0000000000604210
0x6041c0 <n31+16>: 0x0000000000604270 0x0000000000000000
0x6041d0 <n34>: 0x000000000000006b 0x0000000000604230
0x6041e0 <n34+16>: 0x00000000006042d0 0x0000000000000000
0x6041f0 <n45>: 0x0000000000000028 0x0000000000000000
0x604200 <n45+16>: 0x0000000000000000 0x0000000000000000
0x604210 <n41>: 0x0000000000000001 0x0000000000000000
0x604220 <n41+16>: 0x0000000000000000 0x0000000000000000
0x604230 <n47>: 0x0000000000000063 0x0000000000000000
0x604240 <n47+16>: 0x0000000000000000 0x0000000000000000
0x604250 <n44>: 0x0000000000000023 0x0000000000000000
0x604260 <n44+16>: 0x0000000000000000 0x0000000000000000
0x604270 <n42>: 0x0000000000000007 0x0000000000000000
0x604280 <n42+16>: 0x0000000000000000 0x0000000000000000
0x604290 <n43>: 0x0000000000000014 0x0000000000000000
0x6042a0 <n43+16>: 0x0000000000000000 0x0000000000000000
0x6042b0 <n46>: 0x000000000000002f 0x0000000000000000
0x6042c0 <n46+16>: 0x0000000000000000 0x0000000000000000
0x6042d0 <n48>: 0x00000000000003e9 0x0000000000000000

二叉搜索树

1
2
3
4
5
struct Tree{
int val;
struct Tree* left;
struct Tree* right;
}

二叉树

返回值为 5:右 左 右 0
47


Bomb Lab
https://sydcs.github.io/2023/12/18/Bomb-Lab/
Author
Ye
Posted on
December 18, 2023
Licensed under