x86-64 assembly bomb lab setting, phase 1

bomb lab 해결 일지

register 기초

  • rax : return value
  • rbx : callee saved
  • rcx : 4th argument
  • rdx : 3rd argument
  • rsi : 2nd ardument
  • rdi : 1st argument
  • rbp : callee saved
  • rsp : stack pointer
  • r8 : 5th arg
  • r9 : 6th arg
  • r10 : callee saved
  • r11 : callee saved
  • r12: callee saved
  • r13 : callee saved
  • r14 : callee saved
  • r15 : callee saved

csapp 책을 읽긴했지만 일단 이정도 레지스터 지식만 갖추고 나머지 명령어 gdb사용법 같은건 모두 구글링을 통해서 해결하려고 한다.

bomb lab는 csapp에서 제공해주는 실습 과제이다. 현재 csapp 사이트에서 다운을 받을 수 없기에 다른 곳에서 받는다. 여기

readme를 한번 읽어 보고 마음에 드는 폴더를 선택해서 진행하면 된다 물론 solution은 보지 않고 진행!

bomb lab

깃헙의 레포의 폴더 하나를 골라서 리눅스에다 옮기고 시작하면 된다.

  • bomb.c : 기본적인 main 함수가 들어있다. 처음부터 bomb을 뜯어서 시작해도 되지만 초반 감잡는데 도움되라고 준듯하다. 여기서 한줄씩 입력받고 phase_n 함수를 부르는걸 알 수 있다. 이 부분을 중점적으로 살펴보면 될듯? 해당 파일은 직접 읽어보자.
  • bomb : 실제 뜯어볼 파일 gdb를 사용할거다.
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
ubuntu@ubuntu-virtual-machine:~/bomblab$ gdb bomb
GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from bomb...done.
(gdb) disas phase_1
Dump of assembler code for function phase_1:
   0x0000000000400e8d <+0>:	sub    $0x8,%rsp
   0x0000000000400e91 <+4>:	mov    $0x4023b0,%esi
   0x0000000000400e96 <+9>:	callq  0x40131d <strings_not_equal>
   0x0000000000400e9b <+14>:	test   %eax,%eax
   0x0000000000400e9d <+16>:	je     0x400ea4 <phase_1+23>
   0x0000000000400e9f <+18>:	callq  0x40141c <explode_bomb>
   0x0000000000400ea4 <+23>:	add    $0x8,%rsp
   0x0000000000400ea8 <+27>:	retq   
End of assembler dump.
  • TEST 명령어는 두 피연산자들에 대한 비트 연산인 AND를 수행한다. 값이 0일경우 ZF를 1로 설정한다
  • je 명령어는 ZF가 1일경우에 해당주소로 점프한다. strings_not_equal 함수를 부르고 뒤를 처리하는 듯하다. 함수명을 그대로 해석한다면 여기서 비교하는 문자열이 같아야 phase_1을 통과 할 수 있을듯하다. 여기서 $esi가 인자로 들어가기 때문에 이 값을 읽어보면 될거같다.
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
30
31
32
33
34
(gdb) b phase_1
(gdb) r
Starting program: /home/ubuntu/bomblab/bomb 
Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
asdf

Breakpoint 1, 0x0000000000400e8d in phase_1 ()
(gdb) si
0x0000000000400e91 in phase_1 ()
(gdb) disas phase_1
Dump of assembler code for function phase_1:
   0x0000000000400e8d <+0>:	sub    $0x8,%rsp
=> 0x0000000000400e91 <+4>:	mov    $0x4023b0,%esi
   0x0000000000400e96 <+9>:	callq  0x40131d <strings_not_equal>
   0x0000000000400e9b <+14>:	test   %eax,%eax
   0x0000000000400e9d <+16>:	je     0x400ea4 <phase_1+23>
   0x0000000000400e9f <+18>:	callq  0x40141c <explode_bomb>
   0x0000000000400ea4 <+23>:	add    $0x8,%rsp
   0x0000000000400ea8 <+27>:	retq   
End of assembler dump.
(gdb) si
0x0000000000400e96 in phase_1 ()
(gdb) disas phase_1
Dump of assembler code for function phase_1:
   0x0000000000400e8d <+0>:	sub    $0x8,%rsp
   0x0000000000400e91 <+4>:	mov    $0x4023b0,%esi
=> 0x0000000000400e96 <+9>:	callq  0x40131d <strings_not_equal>
   0x0000000000400e9b <+14>:	test   %eax,%eax
   0x0000000000400e9d <+16>:	je     0x400ea4 <phase_1+23>
   0x0000000000400e9f <+18>:	callq  0x40141c <explode_bomb>
   0x0000000000400ea4 <+23>:	add    $0x8,%rsp
   0x0000000000400ea8 <+27>:	retq   
End of assembler dump.

괜히 잘 모르겠으니 레지스터 출력해봄

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
(gdb) info reg
rax            0x6037a0	6305696
rbx            0x0	0
rcx            0x4	4
rdx            0x6037a0	6305696
rsi            0x4023b0	4203440
rdi            0x6037a0	6305696
rbp            0x4021d0	0x4021d0 <__libc_csu_init>
rsp            0x7fffffffde80	0x7fffffffde80
r8             0x604675	6309493
r9             0x7ffff7fe0540	140737354007872
r10            0x3	3
r11            0x7ffff7a14920	140737347930400
r12            0x400c60	4197472
r13            0x7fffffffdf70	140737488346992
r14            0x0	0
r15            0x0	0
rip            0x400e96	0x400e96 <phase_1+9>
eflags         0x202	[ IF ]
cs             0x33	51
ss             0x2b	43
ds             0x0	0
es             0x0	0
fs             0x0	0
gs             0x0	0
(gdb) x/s $esi
0x4023b0:	"When a problem comes along, you must zip it!"

답 When a problem comes along, you must zip it! 일듯? 혹시 $rdi에 처음에 입력한 값들이 들어가는지 살펴봤다.

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
(gdb) disas main
Dump of assembler code for function main:
   0x0000000000400d56 <+0>:	push   %rbx
   0x0000000000400d57 <+1>:	cmp    $0x1,%edi
   0x0000000000400d5a <+4>:	jne    0x400d6c <main+22>
   0x0000000000400d5c <+6>:	mov    0x202a0d(%rip),%rax        # 0x603770 <stdin@@GLIBC_2.2.5>
   0x0000000000400d63 <+13>:	mov    %rax,0x202a26(%rip)        # 0x603790 <infile>
   0x0000000000400d6a <+20>:	jmp    0x400dcf <main+121>
   0x0000000000400d6c <+22>:	mov    %rsi,%rbx
   0x0000000000400d6f <+25>:	cmp    $0x2,%edi
   0x0000000000400d72 <+28>:	jne    0x400dae <main+88>
   0x0000000000400d74 <+30>:	mov    0x8(%rsi),%rdi
   0x0000000000400d78 <+34>:	mov    $0x402264,%esi
   0x0000000000400d7d <+39>:	callq  0x400bd0 <fopen@plt>
   0x0000000000400d82 <+44>:	mov    %rax,0x202a07(%rip)        # 0x603790 <infile>
   0x0000000000400d89 <+51>:	test   %rax,%rax
   0x0000000000400d8c <+54>:	jne    0x400dcf <main+121>
   0x0000000000400d8e <+56>:	mov    0x8(%rbx),%rcx
   0x0000000000400d92 <+60>:	mov    (%rbx),%rdx
   0x0000000000400d95 <+63>:	mov    $0x402266,%esi
   0x0000000000400d9a <+68>:	mov    $0x1,%edi
   0x0000000000400d9f <+73>:	callq  0x400bc0 <__printf_chk@plt>
   0x0000000000400da4 <+78>:	mov    $0x8,%edi
   0x0000000000400da9 <+83>:	callq  0x400be0 <exit@plt>
   0x0000000000400dae <+88>:	mov    (%rsi),%rdx
   0x0000000000400db1 <+91>:	mov    $0x402283,%esi
   0x0000000000400db6 <+96>:	mov    $0x1,%edi
   0x0000000000400dbb <+101>:	mov    $0x0,%eax
   0x0000000000400dc0 <+106>:	callq  0x400bc0 <__printf_chk@plt>
   0x0000000000400dc5 <+111>:	mov    $0x8,%edi
   0x0000000000400dca <+116>:	callq  0x400be0 <exit@plt>
   0x0000000000400dcf <+121>:	callq  0x401384 <initialize_bomb>
   0x0000000000400dd4 <+126>:	mov    $0x4022e8,%edi
   0x0000000000400dd9 <+131>:	callq  0x400ae0 <puts@plt>
   0x0000000000400dde <+136>:	mov    $0x402328,%edi
   0x0000000000400de3 <+141>:	callq  0x400ae0 <puts@plt>
   0x0000000000400de8 <+146>:	callq  0x40147d <read_line>
   0x0000000000400ded <+151>:	mov    %rax,%rdi
   0x0000000000400df0 <+154>:	callq  0x400e8d <phase_1>
   0x0000000000400df5 <+159>:	callq  0x4015a3 <phase_defused>
   0x0000000000400dfa <+164>:	mov    $0x402358,%edi
   0x0000000000400dff <+169>:	callq  0x400ae0 <puts@plt>
   0x0000000000400e04 <+174>:	callq  0x40147d <read_line>
   0x0000000000400e09 <+179>:	mov    %rax,%rdi
   0x0000000000400e0c <+182>:	callq  0x400ea9 <phase_2>
   0x0000000000400e11 <+187>:	callq  0x4015a3 <phase_defused>
   ...

0x0000000000400ded 부분을 보면 rax반환값이 rdi에 값이 들어간다는걸로 대충 문자열이 왔다갔다한다는걸 알 수 있다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
(gdb) r
Starting program: /home/ubuntu/bomblab/bomb 
Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
When a problem comes along, you must zip it!     

Breakpoint 1, 0x0000000000400e8d in phase_1 ()
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) n
Program not restarted.
(gdb) c
Continuing.
Phase 1 defused. How about the next one?

When a problem comes along, you must zip it!

Posted 2020-08-05