Csapp Lab1
Csapp Lab1
- [**LAB1 - Bomb**](#--lab1---bomb--)
* [**Problem Description**](#--problem-description--)
* [**My Solution**](#--my-solution--)
+ [Phase 1](#phase-1)
+ [Step 1. Disassemble the bomb](#step-1-disassemble-the-bomb)
+ [Step 2. Find clues in ***bomb.s***](#step-2-find-clues-in----bombs---)
+ [Step 3. Get the content of answer at runtime](#step-3-get-the-content-of-
answer-at-runtime)
+ [Phase 2](#phase-2)
+ [Step 1. main](#step-1-main)
+ [Step 2. phase_2](#step-2-phase-2)
+ [Step 3. read_six_numbers](#step-3-read-six-numbers)
+ [Step 4. Find the answer](#step-4-find-the-answer)
+ [Phase 3](#phase-3)
+ [Step 1. main](#step-1-main-1)
+ [Step 2. phase_3](#step-2-phase-3)
+ [Step 3. Analyze phase_3 after sscanf](#step-3--analyze-phase-3-after-
sscanf)
+ [Phase 4](#phase-4)
+ [Step 1. main](#step-1-main-2)
+ [Step 2. phase_4](#step-2-phase-4)
+ [Step 3. Analyze phase_4 after sscanf](#step-3--analyze-phase-4-after-
sscanf)
+ [Step 4. Figure out func4](#step-4-figure-out-func4)
+ [Phase 5](#phase-5)
+ [Step 1: main](#step-1--main)
+ [Step 2: phase_5](#step-2--phase-5)
+ [Step 3: Get the answer through gdb](#step-3--get-the-answer-through-gdb)
+ [Phase 6](#phase-6)
+ [Step 1: main](#step-1--main-1)
+ [Step 2: phase 6](#step-2--phase-6)
+ [Step 3: Section 1 (401100 ~ 401151)](#step-3--section-1--401100---401151-)
+ [Step 4: Section 2 (401153 ~ 40116d)](#step-4--section-2--401153---40116d-)
+ [Step 5: Section 3 (40116f ~ 4011a9)](#step-5--section-3--40116f---4011a9-)
+ [Step 6: Section 4 (4011ab ~ 401203)](#step-6--section-4--4011ab---401203-)
+ [Step 7: Find the correct order](#step-7--find-the-correct-order)
## **Problem Description**
The nefarious Dr. Evil has planted a slew of “binary bombs” on our class machines.
A binary bomb is a program that consists of a sequence of phases. Each phase
expects you to type a particular string on stdin. If you type the correct string,
then the phase is defused and the bomb proceeds to the next phase. Otherwise, the
bomb explodes by printing "BOOM!!!" and then terminating. The bomb is defused when
every phase has been defused.
There are too many bombs for us to deal with, so we are giving each student a bomb
to defuse. Your mission, which you have no choice but to accept, is to defuse your
bomb before the due date. Good luck, and welcome to the bomb squad!
## **My Solution**
### Phase 1
```C
input = read_line(); /* Get input */
phase_1(input); /* Run the phase */
phase_defused(); /* Drat! They figured it out!
* Let me know how they did it. */
printf("Phase 1 defused. How about the next one?\n");
```
The program asks for an input and pass it to function **phase_1()**. If the input
doesn't hit the answer, the bomb will explode and exit the process. Oppositely, if
the input hit the answer, process return from **phase_1()** and the phase 1 has
been defused successfully.
Since we only provided with the bomb.c, we can't access the source code of
**phase_1()**. Insteadly, we can speculate through the executable binary bomb.
1. The function push `%r12, %rbp, %rbx` at the beginning and pop it back to stack
at the end.
⇒ The function use `%r12, %rbp, %rbx` for some purpose.
2. Line 0x401342: `callq 40131b <string_length>` call the funtion
***string_length***.
⇒ Let's have a look at ***string_length***.
```
000000000040131b <string_length>:
40131b: 80 3f 00 cmpb $0x0,(%rdi)
40131e: 74 12 je 401332 <string_length+0x17> #
jump if (%rdi) == '\0'
401320: 48 89 fa mov %rdi,%rdx # int i = &str[0];
401323: 48 83 c2 01 add $0x1,%rdx # i++;
401327: 89 d0 mov %edx,%eax # res = i;
401329: 29 f8 sub %edi,%eax # res = res -
&str[0];
40132b: 80 3a 00 cmpb $0x0,(%rdx) # ((*i) - 0)
40132e: 75 f3 jne 401323 <string_length+0x8> # if
((*i) != '\0')
401330: f3 c3 repz retq
401332: b8 00 00 00 00 mov $0x0,%eax # return 0
401337: c3 retq
```
The answer of phase 1 is **"Border relations with Canada have never been better."**
---
### Phase 2
```C
/* The second phase is harder. No one will ever figure out
* how to defuse this... */
input = read_line();
phase_2(input);
phase_defused();
printf("That's number 2. Keep going!\n");
```
```
...
400e49: e8 c2 fc ff ff callq 400b10 <puts@plt>
400e4e: e8 4b 06 00 00 callq 40149e <read_line>
400e53: 48 89 c7 mov %rax,%rdi
400e56: e8 a1 00 00 00 callq 400efc <phase_2>
400e5b: e8 64 07 00 00 callq 4015c4 <phase_defused>
400e60: bf ed 22 40 00 mov $0x4022ed,%edi
...
```
⇒ `%rdi` stores the address of input string
```
0000000000400efc <phase_2>:
400efc: 55 push %rbp
400efd: 53 push %rbx
400efe: 48 83 ec 28 sub $0x28,%rsp
400f02: 48 89 e6 mov %rsp,%rsi
400f05: e8 52 05 00 00 callq 40145c <read_six_numbers>
400f0a: 83 3c 24 01 cmpl $0x1,(%rsp)
400f0e: 74 20 je 400f30 <phase_2+0x34>
400f10: e8 25 05 00 00 callq 40143a <explode_bomb>
400f15: eb 19 jmp 400f30 <phase_2+0x34>
400f17: 8b 43 fc mov -0x4(%rbx),%eax
400f1a: 01 c0 add %eax,%eax
400f1c: 39 03 cmp %eax,(%rbx)
400f1e: 74 05 je 400f25 <phase_2+0x29>
400f20: e8 15 05 00 00 callq 40143a <explode_bomb>
400f25: 48 83 c3 04 add $0x4,%rbx
400f29: 48 39 eb cmp %rbp,%rbx
400f2c: 75 e9 jne 400f17 <phase_2+0x1b>
400f2e: eb 0c jmp 400f3c <phase_2+0x40>
400f30: 48 8d 5c 24 04 lea 0x4(%rsp),%rbx
400f35: 48 8d 6c 24 18 lea 0x18(%rsp),%rbp
400f3a: eb db jmp 400f17 <phase_2+0x1b>
400f3c: 48 83 c4 28 add $0x28,%rsp
400f40: 5b pop %rbx
400f41: 5d pop %rbp
400f42: c3
```
```
sub $0x28,%rsp
mov %rsp,%rsi
```
⇒ Assign 0x28 bytes spaces on the stack and pass the stack top as arg2
call `read_six_numbers`
call `sscanf`
After all, answer should like [num1 num2 num3 num4 num5 num6].
```
0000000000400efc <phase_2>:
400efc: 55 push %rbp
400efd: 53 push %rbx
400efe: 48 83 ec 28 sub $0x28,%rsp
400f02: 48 89 e6 mov %rsp,%rsi
400f05: e8 52 05 00 00 callq 40145c <read_six_numbers>
400f0a: 83 3c 24 01 cmpl $0x1,(%rsp)
400f0e: 74 20 je 400f30 <phase_2+0x34>
400f10: e8 25 05 00 00 callq 40143a <explode_bomb>
400f15: eb 19 jmp 400f30 <phase_2+0x34>
400f17: 8b 43 fc mov -0x4(%rbx),%eax
400f1a: 01 c0 add %eax,%eax
400f1c: 39 03 cmp %eax,(%rbx)
400f1e: 74 05 je 400f25 <phase_2+0x29>
400f20: e8 15 05 00 00 callq 40143a <explode_bomb>
400f25: 48 83 c3 04 add $0x4,%rbx
400f29: 48 39 eb cmp %rbp,%rbx
400f2c: 75 e9 jne 400f17 <phase_2+0x1b>
400f2e: eb 0c jmp 400f3c <phase_2+0x40>
400f30: 48 8d 5c 24 04 lea 0x4(%rsp),%rbx
400f35: 48 8d 6c 24 18 lea 0x18(%rsp),%rbp
400f3a: eb db jmp 400f17 <phase_2+0x1b>
400f3c: 48 83 c4 28 add $0x28,%rsp
400f40: 5b pop %rbx
400f41: 5d pop %rbp
400f42: c3 retq
```
- **Flow 1**<br/>
```
400f0a: 83 3c 24 01 cmpl $0x1,(%rsp) <br/>
400f0e: 74 20 je 400f30 <phase_2+0x34>
400f10: e8 25 05 00 00 callq 40143a <explode_bomb>
```
⇒ num1 = 1
- **Flow 2**<br/>
```
400f30: 48 8d 5c 24 04 lea 0x4(%rsp),%rbx
400f35: 48 8d 6c 24 18 lea 0x18(%rsp),%rbp
400f3a: eb db jmp 400f17 <phase_2+0x1b>
400f17: 8b 43 fc mov -0x4(%rbx),%eax
400f1a: 01 c0 add %eax,%eax
400f1c: 39 03 cmp %eax,(%rbx)
400f1e: 74 05 je 400f25 <phase_2+0x29>
400f20: e8 15 05 00 00 callq 40143a <explode_bomb>
```
⇒ num2 = num1 + num1 = 2
- **Flow 3**<br/>
```
400f25: 48 83 c3 04 add $0x4,%rbx
400f29: 48 39 eb cmp %rbp,%rbx
400f2c: 75 e9 jne 400f17 <phase_2+0x1b>
400f2e: eb 0c jmp 400f3c <phase_2+0x40>
(Branch 1)
400f17: 8b 43 fc mov -0x4(%rbx),%eax
400f1a: 01 c0 add %eax,%eax
400f1c: 39 03 cmp %eax,(%rbx)
400f1e: 74 05 je 400f25 <phase_2+0x29>
400f20: e8 15 05 00 00 callq 40143a <explode_bomb>
(Branch 2)
400f3c: 48 83 c4 28 add $0x28,%rsp
400f40: 5b pop %rbx
400f41: 5d pop %rbp
400f42: c3 retq
```
Branch 2 ⇒ enter this branch if all number are checked<br/>
Branch 1 ⇒ num3 = num2 + num2
After **branch 1** it jumps back to 400f25 which does the same things
until all six number are checked.
---
### Phase 3
```
0000000000400f43 <phase_3>:
400f43: 48 83 ec 18 sub $0x18,%rsp
400f47: 48 8d 4c 24 0c lea 0xc(%rsp),%rcx
400f4c: 48 8d 54 24 08 lea 0x8(%rsp),%rdx
400f51: be cf 25 40 00 mov $0x4025cf,%esi
400f56: b8 00 00 00 00 mov $0x0,%eax
400f5b: e8 90 fc ff ff callq 400bf0 <__isoc99_sscanf@plt>
400f60: 83 f8 01 cmp $0x1,%eax
400f63: 7f 05 jg 400f6a <phase_3+0x27>
400f65: e8 d0 04 00 00 callq 40143a <explode_bomb>
400f6a: 83 7c 24 08 07 cmpl $0x7,0x8(%rsp)
400f6f: 77 3c ja 400fad <phase_3+0x6a>
400f71: 8b 44 24 08 mov 0x8(%rsp),%eax
400f75: ff 24 c5 70 24 40 00 jmpq *0x402470(,%rax,8)
400f7c: b8 cf 00 00 00 mov $0xcf,%eax
400f81: eb 3b jmp 400fbe <phase_3+0x7b>
400f83: b8 c3 02 00 00 mov $0x2c3,%eax
400f88: eb 34 jmp 400fbe <phase_3+0x7b>
400f8a: b8 00 01 00 00 mov $0x100,%eax
400f8f: eb 2d jmp 400fbe <phase_3+0x7b>
400f91: b8 85 01 00 00 mov $0x185,%eax
400f96: eb 26 jmp 400fbe <phase_3+0x7b>
400f98: b8 ce 00 00 00 mov $0xce,%eax
400f9d: eb 1f jmp 400fbe <phase_3+0x7b>
400f9f: b8 aa 02 00 00 mov $0x2aa,%eax
400fa4: eb 18 jmp 400fbe <phase_3+0x7b>
400fa6: b8 47 01 00 00 mov $0x147,%eax
400fab: eb 11 jmp 400fbe <phase_3+0x7b>
400fad: e8 88 04 00 00 callq 40143a <explode_bomb>
400fb2: b8 00 00 00 00 mov $0x0,%eax
400fb7: eb 05 jmp 400fbe <phase_3+0x7b>
400fb9: b8 37 01 00 00 mov $0x137,%eax
400fbe: 3b 44 24 0c cmp 0xc(%rsp),%eax
400fc2: 74 05 je 400fc9 <phase_3+0x86>
400fc4: e8 71 04 00 00 callq 40143a <explode_bomb>
400fc9: 48 83 c4 18 add $0x18,%rsp
400fcd: c3 retq
```
```
400f5b: e8 90 fc ff ff callq 400bf0 <__isoc99_sscanf@plt>
400f60: 83 f8 01 cmp $0x1,%eax
400f63: 7f 05 jg 400f6a <phase_3+0x27>
400f65: e8 d0 04 00 00 callq 40143a <explode_bomb>
```
⇒ If the extracted numbers from input string <= 1, explode bomb.
```
400f6a: 83 7c 24 08 07 cmpl $0x7,0x8(%rsp)
400f6f: 77 3c ja 400fad <phase_3+0x6a>
400f71: 8b 44 24 08 mov 0x8(%rsp),%eax
400f75: ff 24 c5 70 24 40 00 jmpq *0x402470(,%rax,8)
400fc4: e8 71 04 00 00 callq 40143a <explode_bomb>
...
400fad: e8 88 04 00 00 callq 40143a <explode_bomb>
```
- If number at `0x8(%rsp)` >= 7, explode bomb.
- `400f75: ff 24 c5 70 24 40 00 jmpq *0x402470(,%rax,8)` jumps to the address
stored in `M[0x402470 + 8 * %rax]`<br/>
which equivalent to `M[0x402470 + 8 * num1]`
```
400fb9: b8 37 01 00 00 mov $0x137,%eax
400fbe: 3b 44 24 0c cmp 0xc(%rsp),%eax
400fc2: 74 05 je 400fc9 <phase_3+0x86>
400fc4: e8 71 04 00 00 callq 40143a <explode_bomb>
400fc9: 48 83 c4 18 add $0x18,%rsp
400fcd: c3 retq
```
### Phase 4
### Step 1. main
```
...
400e7c: bf 0b 23 40 00 mov $0x40230b,%edi
400e81: e8 8a fc ff ff callq 400b10 <puts@plt>
400e86: e8 13 06 00 00 callq 40149e <read_line>
400e8b: 48 89 c7 mov %rax,%rdi
400e8e: e8 79 01 00 00 callq 40100c <phase_4>
400e93: e8 2c 07 00 00 callq 4015c4 <phase_defused>
...
```
- call **sscanf**
|Arguments|Memory|Description|
|:--------|:-----|:----------|
|arg 1|%rdi|addr of input string|
|arg 2|%rsi|0x4025cf addr of string format|
|arg 3|%rdx|addr of stack top + 0x8|
|arg 4|%rcx|addr of stack top + 0xc|
```
401024: e8 c7 fb ff ff callq 400bf0 <__isoc99_sscanf@plt>
401029: 83 f8 02 cmp $0x2,%eax
40102c: 75 07 jne 401035 <phase_4+0x29>
40102e: 83 7c 24 08 0e cmpl $0xe,0x8(%rsp)
401033: 76 05 jbe 40103a <phase_4+0x2e>
401035: e8 00 04 00 00 callq 40143a <explode_bomb>
40103a: ba 0e 00 00 00 mov $0xe,%edx
40103f: be 00 00 00 00 mov $0x0,%esi
401044: 8b 7c 24 08 mov 0x8(%rsp),%edi
401048: e8 81 ff ff ff callq 400fce <func4>
40104d: 85 c0 test %eax,%eax
40104f: 75 07 jne 401058 <phase_4+0x4c>
401051: 83 7c 24 0c 00 cmpl $0x0,0xc(%rsp)
401056: 74 05 je 40105d <phase_4+0x51>
401058: e8 dd 03 00 00 callq 40143a <explode_bomb>
40105d: 48 83 c4 18 add $0x18,%rsp
401061: c3 retq
```
⇒ If extracted numbers from input string != 2, explode bomb.
```
40102e: 83 7c 24 08 0e cmpl $0xe,0x8(%rsp)
401033: 76 05 jbe 40103a <phase_4+0x2e>
401035: e8 00 04 00 00 callq 40143a <explode_bomb>
```
⇒ If `num1` > 14, explode bomb.<br/>
⇒ `num1` <= 14<br/>
```
40103a: ba 0e 00 00 00 mov $0xe,%edx
40103f: be 00 00 00 00 mov $0x0,%esi
401044: 8b 7c 24 08 mov 0x8(%rsp),%edi
401048: e8 81 ff ff ff callq 400fce <func4>
```
- call **func4**
|Arguments|Memory|Description|
|:--------|:-----|:----------|
|arg 1|%rdi|0x8(%rsp) which is `num1`|
|arg 2|%rsi|0|
|arg 3|%rdx|0xe|
- After func4:
```
401048: e8 81 ff ff ff callq 400fce <func4>
40104d: 85 c0 test %eax,%eax
40104f: 75 07 jne 401058 <phase_4+0x4c>
401051: 83 7c 24 0c 00 cmpl $0x0,0xc(%rsp)
401056: 74 05 je 40105d <phase_4+0x51>
401058: e8 dd 03 00 00 callq 40143a <explode_bomb>
40105d: 48 83 c4 18 add $0x18,%rsp
401061: c3 retq
```
⇒ **the result of func4 should be 0** <br/>
⇒ **num2 = 0** <br/>
```
0000000000400fce <func4>:
400fce: 48 83 ec 08 sub $0x8,%rsp
400fd2: 89 d0 mov %edx,%eax
400fd4: 29 f0 sub %esi,%eax
400fd6: 89 c1 mov %eax,%ecx
400fd8: c1 e9 1f shr $0x1f,%ecx
400fdb: 01 c8 add %ecx,%eax
400fdd: d1 f8 sar %eax
400fdf: 8d 0c 30 lea (%rax,%rsi,1),%ecx
400fe2: 39 f9 cmp %edi,%ecx
400fe4: 7e 0c jle 400ff2 <func4+0x24>
400fe6: 8d 51 ff lea -0x1(%rcx),%edx
400fe9: e8 e0 ff ff ff callq 400fce <func4>
400fee: 01 c0 add %eax,%eax
400ff0: eb 15 jmp 401007 <func4+0x39>
400ff2: b8 00 00 00 00 mov $0x0,%eax
400ff7: 39 f9 cmp %edi,%ecx
400ff9: 7d 0c jge 401007 <func4+0x39>
400ffb: 8d 71 01 lea 0x1(%rcx),%esi
400ffe: e8 cb ff ff ff callq 400fce <func4>
401003: 8d 44 00 01 lea 0x1(%rax,%rax,1),%eax
401007: 48 83 c4 08 add $0x8,%rsp
40100b: c3 retq
```
### Phase 5
### Step 1: main
```
400e98: bf d8 23 40 00 mov $0x4023d8,%edi
400e9d: e8 6e fc ff ff callq 400b10 <puts@plt>
400ea2: e8 f7 05 00 00 callq 40149e <read_line>
400ea7: 48 89 c7 mov %rax,%rdi
400eaa: e8 b3 01 00 00 callq 401062 <phase_5>
400eaf: e8 10 07 00 00 callq 4015c4 <phase_defused>
400eb4: bf 1a 23 40 00 mov $0x40231a,%edi
400eb9: e8 52 fc ff ff callq 400b10 <puts@plt>
400ebe: e8 db 05 00 00 callq 40149e <read_line>
400ec3: 48 89 c7 mov %rax,%rdi
```
⇒ %rdi stores the address of the input string.
```
0000000000401062 <phase_5>:
401062: 53 push %rbx
401063: 48 83 ec 20 sub $0x20,%rsp
401067: 48 89 fb mov %rdi,%rbx
40106a: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
401071: 00 00
401073: 48 89 44 24 18 mov %rax,0x18(%rsp)
401078: 31 c0 xor %eax,%eax
40107a: e8 9c 02 00 00 callq 40131b <string_length>
40107f: 83 f8 06 cmp $0x6,%eax
401082: 74 4e je 4010d2 <phase_5+0x70>
401084: e8 b1 03 00 00 callq 40143a <explode_bomb>
...
```
⇒ Distribute 32 bytes to stack.
⇒ Put a canary on rsp+0x18.
⇒ The input string should have 6 characters exactly.
⇒ Put the pointer of input string to ***%rbx***.
|Reg|Description|
|:-----|:----------|
|%rbx|pointer to input string|
```
4010d2: b8 00 00 00 00 mov $0x0,%eax
4010d7: eb b2 jmp 40108b <phase_5+0x29>
...
<br/>x
401099: 0f b6 92 b0 24 40 00 movzbl 0x4024b0(%rdx),%edx
4010a0: 88 54 04 10 mov %dl,0x10(%rsp,%rax,1)
4010a4: 48 83 c0 01 add $0x1,%rax
4010a8: 48 83 f8 06 cmp $0x6,%rax
4010ac: 75 dd jne 40108b <phase_5+0x29>
4010ae: c6 44 24 16 00 movb $0x0,0x16(%rsp)
4010b3: be 5e 24 40 00 mov $0x40245e,%esi
4010b8: 48 8d 7c 24 10 lea 0x10(%rsp),%rdi
4010bd: e8 76 02 00 00 callq 401338 <strings_not_equal>
4010c2: 85 c0 test %eax,%eax
4010c4: 74 13 je 4010d9 <phase_5+0x77>
...
### Phase 6
### Step 1: main
```
400eaa: e8 b3 01 00 00 callq 401062 <phase_5>
400eaf: e8 10 07 00 00 callq 4015c4 <phase_defused>
400eb4: bf 1a 23 40 00 mov $0x40231a,%edi
400eb9: e8 52 fc ff ff callq 400b10 <puts@plt>
400ebe: e8 db 05 00 00 callq 40149e <read_line>
400ec3: 48 89 c7 mov %rax,%rdi
400ec6: e8 29 02 00 00 callq 4010f4 <phase_6>
400ecb: e8 f4 06 00 00 callq 4015c4 <phase_defused>
400ed0: b8 00 00 00 00 mov $0x0,%eax
400ed5: 5b pop %rbx
400ed6: c3 retq
```
⇒ %rdi stores the address of the input string.
```
0000000004010f4 <phase_6>:
4010f4: 41 56 push %r14
4010f6: 41 55 push %r13
4010f8: 41 54 push %r12
4010fa: 55 push %rbp
4010fb: 53 push %rbx
4010fc: 48 83 ec 50 sub $0x50,%rsp
401100: 49 89 e5 mov %rsp,%r13
401103: 48 89 e6 mov %rsp,%rsi
401106: e8 51 03 00 00 callq 40145c <read_six_numbers>
...
000000000040145c <read_six_numbers>:
40145c: 48 83 ec 18 sub $0x18,%rsp
401460: 48 89 f2 mov %rsi,%rdx
401463: 48 8d 4e 04 lea 0x4(%rsi),%rcx
401467: 48 8d 46 14 lea 0x14(%rsi),%rax
40146b: 48 89 44 24 08 mov %rax,0x8(%rsp)
401470: 48 8d 46 10 lea 0x10(%rsi),%rax
401474: 48 89 04 24 mov %rax,(%rsp)
401478: 4c 8d 4e 0c lea 0xc(%rsi),%r9
40147c: 4c 8d 46 08 lea 0x8(%rsi),%r8
401480: be c3 25 40 00 mov $0x4025c3,%esi
401485: b8 00 00 00 00 mov $0x0,%eax
40148a: e8 61 f7 ff ff callq 400bf0 <__isoc99_sscanf@plt>
40148f: 83 f8 05 cmp $0x5,%eax
401492: 7f 05 jg 401499 <read_six_numbers+0x3d>
401494: e8 a1 ff ff ff callq 40143a <explode_bomb>
401499: 48 83 c4 18 add $0x18,%rsp
40149d: c3 retq
```
Refer to: [read_six_number](#step-3-read-six-numbers)
After read_six_numbers, we get 6 numbers on the stack from (%rsp + 0) ~ (%rsp +
0x14) which represent as [num1 num2 num3 num4 num5 num6] below.
```C
%r13 = %rsp
%rsi = %rsp
call read_six_numbers
%r14 = %rsp
%r12 = 0
B:
%rbp = %r13
%rax = *(%r13)
%rax -= 1
if (%rax <= 5) {
%r12 += 1
if (%r12 != 6) {
%rbx = %r12
A:
%rax = %rbx
%rax = *(%rsp + 4 * %rax)
if (%rax != *(%rbp)) {
%rbx += 1
if (%rbx <= 5) {
goto A
} else {
%r13 += 4
goto B
}
} else {
explode_bomb
}
} else {
goto next_session (401153)
}
} else {
explode_bomb
}
```
⇒ The six numbers should be different with each other
⇒ num1 ~ num6 are all <= 6
```
401153: 48 8d 74 24 18 lea 0x18(%rsp),%rsi
401158: 4c 89 f0 mov %r14,%rax
40115b: b9 07 00 00 00 mov $0x7,%ecx
401160: 89 ca mov %ecx,%edx
401162: 2b 10 sub (%rax),%edx
401164: 89 10 mov %edx,(%rax)
401166: 48 83 c0 04 add $0x4,%rax
40116a: 48 39 f0 cmp %rsi,%rax
40116d: 75 f1 jne 401160 <phase_6+0x6c>
```
The assembly above act like:
```C
%rsi = (%rsp + 0x18)
%rax = %r14
%rcx = 7
A:
%rdx = %rcx
%rdx -= *(%rax)
*(%rax) = %rdx
%rax += 4
if (%rax != %rsi) {
goto A
} else {
goto next_section (40116f)
}
```
The code convert the num to (7-num)
⇒ num1 => 7 - num1
⇒ num2 => 7 - num2
....
⇒ num6 => 7 - num6
```C
%rsi = 0
C:
%rcx = *(%rsp + %rsi)
if (%rcx <= 1) {
%rdx = 0x6032d0
B:
*(%rsp + 2 * %rsi + 0x20) = %rdx
%rsi += 4
if (%rsi == 0x18) {
goto next_section (line 4011ab)
}
goto C
} else {
%rax = 1
%rdx = 0x6032d0
A:
%rdx = *(%rdx + 0x8)
%rax += 1
if (%rax != %rcx) {
goto A
}
goto B
}
```
This code section put 6 numbers on the (%rsp + 0x20), each number has 8 bytes.
We can imagine that there is a linked list at 0x6032d0.
Each node is consist of by the
struct node_t{
int64_t data;
node_t *pNext;
}
By analysing the code above, we know that each input number is related to an
address in the linked list. e.g. If num1 is 2, the corresponding number put on the
(%rsp + 2 * 0 + 0x20) is the address of the 2nd node in the linked list.
```
4011ab: 48 8b 5c 24 20 mov 0x20(%rsp),%rbx
4011b0: 48 8d 44 24 28 lea 0x28(%rsp),%rax
4011b5: 48 8d 74 24 50 lea 0x50(%rsp),%rsi
4011ba: 48 89 d9 mov %rbx,%rcx
4011bd: 48 8b 10 mov (%rax),%rdx
4011c0: 48 89 51 08 mov %rdx,0x8(%rcx)
4011c4: 48 83 c0 08 add $0x8,%rax
4011c8: 48 39 f0 cmp %rsi,%rax
4011cb: 74 05 je 4011d2 <phase_6+0xde>
```C
/*
A.
Re arrange the order of the linked list.
The 1st node on the stack (%rsp+0x20) links to the 2nd node on the stack
(%rsp+0x28).
Similarly, The 2nd node on the stack (%rsp+0x28) links to the 3rd node on the
stack (%rsp+0x30).
... and so on.
B.
The number in current node should be greater or equal to the next node, otherwise
bomb explodes.
*/
## Appendix
### x86-64 registers convention
