-
Bomb Lab Walkthrough - 1System Programming/Bomb Lab 2019. 10. 4. 22:44
시프의 X같은 과제 그 세 번째(1번째 과제는 이중연결리스트였는데, 포인터 위치 하나를 착각해서 며칠 동안 삽질을 했다.)-CS:APP에서는 이중연결리스트를 빼서 두 번째이다.
시험 족보에 Bomblab 관련 문제가 나와서 과정을 정리해 보는 것이 큰 도움이 될 것이다.
우선 Bomblab은 이름이 좋아 폭탄이지, 사실 디버깅과 역어셈블러를 공부하는 것이다.
총 6단계로, 각 단계마다 적절한 값을 넣어주면 다음 단계로 이동한다. 실패한다면?
만든라면- 점수도 폭8해 버린다.
그럼 폭탄랩을 시작해 보자. 그나저나 Dr. Evil이 누구일까? 꺼라위키를 찾아보자.
Dr. Evil
오스틴 파워스의 숙적이자 세계를 위협하는 존재이다. 머리가 좋아서 용암 내부에 기지, 냉동 기계 심지어는 타임 머신도 만들어냈다. 덤으로 성격이 매우 괴팍해 부하들이 계속 실패하자 모두 처형해 버리기도 한다.[20] 하지만 90년대 깨어난 뒤에는 바뀐 세상에 제대로 적응하지 못해 미국에 100만 달러를 내놓으라 한다든가[21], 영국이 해외 식민지가 있으니 땅을 안주면 영국 왕자가 바람핀다고 헛소문을 낸다든가[22] 하는 헛소리를 한다. 본 시리즈의 명대사 제조기.
그런데 알고보니 바로 오스틴 파워스의 쌍둥이 형제였다! 본명은 두기 파워스(Dougls "Dougie" Powers). 아기이던 시절 부모님과 함께 여행을 갔는데 아버지가 소변 보러 잠깐 차에서 내렸던 사이 차가 폭발하고 말았는데 오스틴 파워스는 아버지가 찾았으나 이블은 멀리 날라가는 바람에 벨기에의 어떤 부부[23]가 주워 키우게 되나, 온갖 학대를 받으며 성장해서 성격이 삐뚤어졌다고 한다.오스틴 파워 - 나무위키
이 문서에 스포일러가 포함되어 있습니다. 이 문서가 설명하는 작품이나 인물 등에 대한 줄거리, 결말, 반전 요소 등을 직·간접적으로 포함하고 있습니다. Sir Austin Danger Powers (Austin Powers) 세계를 여러 번 구해온 세계 최고의 스파이. 닦지도 않은[17] 뻐드렁니에 1분 단위로 섹드립을 쏟아내는 다소 괴상한 남자. 허나 그의 매력의 원천인 모조(Mojo) 덕분에 엄청난 매력을 풍겨 매 편마다 여자들이 따라붙는다.[18]
namu.wiki
'오스틴 파워' 라는 프로그램의 빌런이라고 한다.
우선 실행하면 ./bomb을 입력해 보자. 저 경고문이 날아오면 성공한 거다. 일단 아무것도 모르는 상태이므로 얌전히 컨트롤+C를 눌러 나가자. 괜히 겁을 주기 위해서인지 시간차를 두고 종료 메시지가 출력된다.
이제부터 한 번 bomb 파일을 뜯어 보도록 하자. 나가고 나서, 'gdb bomb'을 입력하면 bomb 파일 디버그를 시작한다. 그 다음에, disas main을 입력해서 main 함수를 뜯어보자. 여기서 phase_1을 찾아보면 그 밑으로 보너스 문제까지 쫘라락 디버깅된 코드가 나온다. 이걸 이제부터 하나하나 분석해야 한다.
PHASE 1
00000000000012b4 :
12b4: 48 83 ec 08 sub $0x8,%rsp
12b8: 48 8d 35 d1 17 00 00 lea 0x17d1(%rip),%rsi # 2a90 <_IO_stdin_used+0x150>
12bf: e8 9a 04 00 00 callq 175e <strings_not_equal>
12c4: 85 c0 test %eax,%eax
12c6: 75 05 jne 12cd <phase_1+0x19>
12c8: 48 83 c4 08 add $0x8,%rsp
12cc: c3 retq
12cd: e8 90 07 00 00 callq 1a62 <explode_bomb>
12d2: eb f4 jmp 12c8 <phase_1+0x14>이다.
calllq-test를 보면 알겠지만, 이 단계에서는 strings_not_equal 함수를 불러와서 테스트를 통과하느냐 안 통과하느냐를 판단한다. 그리고 jne에서 결과를 판정하는데... jne는 ZF가 0이 아닐 때 12cd로 보내버리라고 되어 있다. 그리고 12cd 자리에 어떤 코드가 있냐고? 폭8이다! 즉 ZF는 0이어야만 한다. (그 이후에 적힌 건 초기화다.) 폭8을 막기 위해서는 ZF를 0으로 만들 조건을 찾아야 하는데...
우선 test 함수가 뭔지 생각해 보면, test 함수는 2개의 오퍼랜드에 대해 & 연산을 시행한다. 이게 0이 되려면 둘 다 0이어야만 한다. 그런데 똑같은 오퍼랜드로 & 연산을 한다...?
%eax 결과 0 0 1 1 즉 strings_not_equal이 0일 때에만 폭탄이 폭8하지 않는다는 것이다. 이 함수는 string 2개가 다르면 1을 리턴한다.
결론적으로, 주절주절 써놓긴 했지만 그냥 비밀번호 찾는 문제이다.
000000000000175e <strings_not_equal>:
175e: 41 54 push %r12
1760: 55 push %rbp
1761: 53 push %rbx
1762: 48 89 fb mov %rdi,%rbx
1765: 48 89 f5 mov %rsi,%rbp
1768: e8 d4 ff ff ff callq 1741 <string_length>
176d: 41 89 c4 mov %eax,%r12d
1770: 48 89 ef mov %rbp,%rdi
(후략)
strings_not_equal 함수를 뜯어보자. 그러면 %rbp와 %rbx로 받은 입력은 %rsi와 %rdi로 보낸다. 이 두 개가 같으면 문제 해결. 이걸 어떻게 알아보지...?
우선 gdb로 들어가서 phase_1, strings_not_equal이 실행되지 않도록 막아버리자. b '함수 이름'으로 치면 여기에서 실행이 막힌다.
그 다음, r을 눌러 디버깅 상태에서 bomb을 실행시키고, 아무 문장이나 입력하자. 그리고 c를 눌러 breakpoint 2(strings_not_equal) 까지 진행하면,
이렇게 아까 봤던 rsi rdi에 값이 들어가 있다. 이걸 확인하려면
x/s $rdi, x/s $rsi를 입력하면 된다. 이러면 rdi와 rsi에 들어간 값이 보인다. rdi에는 입력한 string이, rsi에는 정답이 들어 있다. 정답을 입력하면 Phase 1 끝!
여담으로 For NASA, space is still a high priority는 멍청하기로 유명한 미국 부통령 댄 퀘일의 어록 중 하나이다. 이 양반에 의하면 홀로코스트는 미국이 저질렀고, 화성에는 운하와 물이 있다고 한다.