update bomblab
This commit is contained in:
parent
84205fe5c4
commit
2357d94b28
@ -1,3 +1,4 @@
|
|||||||
|
# bomblab
|
||||||
输入命令 `objdump -s -S -d -M att bomb > bomb.s` 进行反汇编。
|
输入命令 `objdump -s -S -d -M att bomb > bomb.s` 进行反汇编。
|
||||||
|
|
||||||
## Phase 1
|
## Phase 1
|
||||||
@ -11,10 +12,12 @@ void phase_1(char str[]) {
|
|||||||
```
|
```
|
||||||
`explode_bomb` 函数将炸弹引爆,我们不希望它被调用;而 `strings_not_equal` 接受两个字符串作为参数,在两者不相等时返回 `1`,否则返回 `0`。
|
`explode_bomb` 函数将炸弹引爆,我们不希望它被调用;而 `strings_not_equal` 接受两个字符串作为参数,在两者不相等时返回 `1`,否则返回 `0`。
|
||||||
|
|
||||||
显然,输入是 `Border relations with Canada have never been better.`。
|
显然,输入应为 `Border relations with Canada have never been better.`。
|
||||||
|
|
||||||
## Phase 2
|
## Phase 2
|
||||||
这个 phase 的难点在于跳转指令互相交错,相当混乱。为此,我们通过调整指令的顺序并相应改变的跳转指令,使代码符合循环的一般模式。在这里,我们将 `400f0a` 至 `400f3a` 部分整理如下:
|
这个 phase 的难点在于跳转指令互相交错,相当混乱。为此,我们通过调整指令的顺序并相应改变的跳转指令,使代码符合循环的一般模式。
|
||||||
|
|
||||||
|
在这里,我们将 `400f0a` 至 `400f3a` 部分整理如下:
|
||||||
```esm
|
```esm
|
||||||
cmpl $0x1,(%rsp)
|
cmpl $0x1,(%rsp)
|
||||||
je .L1
|
je .L1
|
||||||
@ -33,7 +36,7 @@ void phase_1(char str[]) {
|
|||||||
cmp %rbp,%rbx
|
cmp %rbp,%rbx
|
||||||
jne .L2
|
jne .L2
|
||||||
```
|
```
|
||||||
基于此逆向,得到:
|
基于此逆向得到:
|
||||||
```c
|
```c
|
||||||
void phase_2(char str[]) {
|
void phase_2(char str[]) {
|
||||||
int x[6];
|
int x[6];
|
||||||
@ -52,7 +55,7 @@ void phase_2(char str[]) {
|
|||||||
```
|
```
|
||||||
`read_six_numbers(int x[])` 读入 6 个整数,并依次存贮到 `x[0]` 至 `x[5]`。
|
`read_six_numbers(int x[])` 读入 6 个整数,并依次存贮到 `x[0]` 至 `x[5]`。
|
||||||
|
|
||||||
输入应是 `1 2 4 8 16 32`。
|
由此可知,输入应为 `1 2 4 8 16 32`。
|
||||||
|
|
||||||
## Phase 3
|
## Phase 3
|
||||||
这个 phase 包含一个 switch 语句。
|
这个 phase 包含一个 switch 语句。
|
||||||
@ -97,7 +100,7 @@ void phase_3(char str[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
由此,输入的第 1 个数必须在 0 到 7 之间,第二个数与之相应即可。
|
由此可知,输入的第 1 个数必须在 0 到 7 之间,第二个数与之相应即可。
|
||||||
|
|
||||||
## Phase 4
|
## Phase 4
|
||||||
`400fd6` 至 `400fdd` 部分使用了原书 2.3.7 中提到的方法实现除以 2。
|
`400fd6` 至 `400fdd` 部分使用了原书 2.3.7 中提到的方法实现除以 2。
|
||||||
@ -158,7 +161,7 @@ void phase_4(char str[]) {
|
|||||||
call explode_bomb
|
call explode_bomb
|
||||||
.L3:
|
.L3:
|
||||||
```
|
```
|
||||||
基于此逆向,得到:
|
基于此逆向得到:
|
||||||
```c
|
```c
|
||||||
void phase_5(char str[]) {
|
void phase_5(char str[]) {
|
||||||
if (string_length(str) != 6) {
|
if (string_length(str) != 6) {
|
||||||
@ -179,7 +182,7 @@ void phase_5(char str[]) {
|
|||||||
一个可行的输入是 `9?>567`。
|
一个可行的输入是 `9?>567`。
|
||||||
|
|
||||||
## Phase 6
|
## Phase 6
|
||||||
对 `401176` 至 `4011a9` 部分整理如下:
|
将 `401176` 至 `4011a9` 部分整理如下:
|
||||||
```esm
|
```esm
|
||||||
mov $0x0,%esi
|
mov $0x0,%esi
|
||||||
.L1:
|
.L1:
|
||||||
@ -269,14 +272,14 @@ void phase_6(char str[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
结合链表知识,输入应是 `4 3 2 1 6 5`。
|
结合链表知识,输入应为 `4 3 2 1 6 5`。
|
||||||
|
|
||||||
## 进入 Secret Phase
|
## 进入 Secret Phase
|
||||||
唯一对 `secret_phase` 的调用在 `phase_defused` 中。观察 `phase_defused`,在 `num_input_strings`(每次调用 `read_line` 都会使它加 1)等于 6,即完成 Phase 6 后的调用时,该函数从以 `0x603870` 开头的字符串中先后提取了两个整数和一个字符串,并检查提取的字符串是否与 `DrEvil` 相等,若相等,则调用 `secret_phase`。
|
唯一对 `secret_phase` 的调用位于 `phase_defused` 中。观察 `phase_defused`,在 `num_input_strings`(每次调用 `read_line` 都会使它加 1)等于 6,即完成 Phase 6 后的调用时,该函数从以 `0x603870` 开头的字符串中先后提取了两个整数和一个字符串,并检查提取的字符串是否与 `DrEvil` 相等,若相等,则调用 `secret_phase`。
|
||||||
|
|
||||||
`0x603870` 这个地址并没有在其他任何地方出现过,但是在 `skip` 和`read_line` 中,出现了地址 `0x603780`。对这两个函数逆向,大致如下:
|
`0x603870` 这个地址并没有在其他任何地方出现过,但是在 `skip` 和`read_line` 中,出现了地址 `0x603780`。对这两个函数逆向,大致如下:
|
||||||
```c
|
```c
|
||||||
char input[MAXLEN];
|
char input[MAXLEN]; // 0x603780
|
||||||
int num_input_strings = 0;
|
int num_input_strings = 0;
|
||||||
FILE *infile;
|
FILE *infile;
|
||||||
|
|
||||||
@ -294,7 +297,7 @@ char* read_line() {
|
|||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
由此,以 `0x603870` 开头的字符串就是 phase 4 时输入的字符串,而在 phase 4 中恰好要输入两个整数,在它们之后再输入 `MrEvil`,我们就能够进入 Secret Phase。
|
由此可知,以 `0x603870` 开头的字符串就是 phase 4 时输入的字符串,而在 phase 4 中恰好要输入两个整数,在它们之后再输入 `MrEvil`,我们就能够进入 Secret Phase。
|
||||||
|
|
||||||
## Secret Phase
|
## Secret Phase
|
||||||
```c
|
```c
|
||||||
@ -347,4 +350,4 @@ void secret_phase() {
|
|||||||
...
|
...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
结合二叉搜索树,输入应为 `22`。〔方案選單〕
|
结合二叉搜索树知识,输入应为 `22`。
|
Loading…
x
Reference in New Issue
Block a user