본문 바로가기

분류 전체보기

(71)
[Bomb Lab] Phase 6, linked list operation의 assembly code Read six numbers 함수 마지막 phase라서 그런지 assembly code 길이가 가장 길다. 풀이 순서대로 일부만 첨부하기로 한다. read_six_numbers 함수에서 유추할 수 있듯이, 사용자 입력으로 6개의 숫자를 넣어본다. 처음으로 분기가 있는 42줄에 breakpoint를 걸어둔다. 폭탄이 터지지 않고 실행을 이어가려면 jump가 일어나야 하고, eax 레지스터 값이 5보다 작거나 같아야 한다. 35줄에서 r13 레지스터 값을 base address로 하여 eax 레지스터에 값을 할당하므로, 이 주소를 찍어보았더니 입력했던 6개의 숫자가 들어있다. 즉, eax 레지스터에는 사용자 입력 1번째 숫자가 들어가고, 다시 1을 빼주므로, 1번째 숫자는 6 이하여야 한다는 결론을 얻는다..
[Bomb Lab] Phase 5, 문자열 조작 연산, gdb 메모리 값 참조 Assembly code of phase_5 첫 번째 분기문: string_length 함수의 return 값 확인 29, 32줄에서 첫 번째 분기문이 있는데, 폭탄이 터지지 않고 실행을 이어가려면 string_length 함수의 return 값이 6이어야 한다. 함수 이름으로부터 유추해보면, 입력한 문자열의 길이가 6인 것이라고 추측해볼 수 있다. 먼저, breakpoint를 29줄에 걸어둔다. 예를 들어, hello world를 입력해보면, eax 레지스터 값이 11이다. hello world 문자열의 길이가 11이므로, string_length 함수는 사용자 입력 문자열의 길이를 return한다고 추측할 수 있다. 이제 다시 길이가 6인 임의의 문자열 helloo를 입력하고 계속 분석하기로 한다. ..
[Bomb Lab] Phase 4, 재귀 함수 호출의 assembly code Assembly Code of phase_4() gdb를 켜고 bomb 실행 파일의 phase_4 함수를 disassemble해보면 다음과 같다. 24줄에 scanf 함수를 호출하는 부분이 보이는데, 이전 phase들의 경험을 토대로 생각해보면 뭔가 사용자 입력을 받는데, 여기서는 레지스터 eax가 2와 같을 때만 실행을 이어가므로 입력의 길이가 2여야 한다는 것을 알 수 있다. 입력은 완료된 뒤의 첫 번째 분기인 34줄에 breakpoint를 걸어본다. 임의로 1 2 3이라는 3개의 숫자를 입력으로 넣었는데, 폭탄이 터지지 않고 34줄까지 실행된다. 이 때의 레지스터 값들을 출력했을 때, 레지스터 eax의 값이 2인 것으로 보아 scanf 함수가 입력 2개가 되면 자동으로 종료되는 것으로 추측해볼 수 ..
[Bomb Lab] Phase 3, Assembly indirect jump Assembly 코드 변환 phase_3을 assembly 코드로 변환해보면, 첫 번째 분기: 입력의 길이 확인 우선 첫 번째 분기가 일어나는 곳인 +32 줄에 breakpoint를 찍어보았다. phase 1, 2는 알아낸 정답을 입력하고, 3은 임의로 4개의 숫자 1 2 3 4를 입력해보았다. 이 때 레지스터 eax 값이 2이고, 그러면 1보다 크기 때문에 34줄은 무사히 건너뛰게 된다. 여기서 스크린샷에 첨부하지는 않았으나 10 20 30의 3가지 숫자를 입력했을 때도 eax의 값이 2였는데, 아마도 최대 2개의 입력을 읽어오는 것 같다. 스택 포인터가 가리키는 지점의 메모리 값을 확인해보면, rsp+8, 12에 각각 1, 2번째 입력 값이 들어 있었다. 두 번째 분기: 1번째 입력 값의 크기 확인 ..
[Bomb Lab] Phase 2, assembly cmp/jmp, 분기, 반복문 phase_2() 함수의 assembly 확인 disassembler로 phase_2() 함수의 assembly 코드를 출력해보면 다음과 같다. 함수의 2번째 arg에 해당하는 rsi 레지스터에 스택 포인터 rsp 값을 넘겨준 뒤, read_six_numbers() 함수를 호출한다. 이 함수의 disassembler를 돌려보면 이 함수에 breakpoint를 찍고 프로그램을 실행시킨다. 이 때, phase 1은 풀었던 결과대로 정답을 바로 입력해주고, phase 2는 1 2 3 4 5 6이라는 임의의 6개 숫자를 입력한다. 함수의 1번째 arg인 rdi 레지스터가 가리키는 곳의 메모리 값을 찍어보면 입력했던 6개의 숫자가 들어있음을 확인할 수 있다. 스택 확인 read_six_numbers() 함수 호출..
[Bomb Lab] Phase 1, gdb 명령어, assembly code 변환, gdb 메모리 참조 지난 포스팅에서 Bomb Lab을 시작할 준비를 끝냈으므로, 이제 맨 첫 단계인 phase_1 함수부터 분석해보기로 한다. bomb.c 소스 코드를 보면 알 수 있는데, 이 프로그램은 총 phase 1부터 6까지 6개의 단계로 구성되어 있다. 하나의 단계를 해결하면 그 다음으로 넘어가는 식으로 이루어져 있다. 다시 gdb 디버거로 bomb 프로그램을 여는 것으로 시작한다. Assmebly 코드로 변환하기 disas (함수명) 을 입력하면 함수에 대한 assembly 코드 변환 결과를 보여준다. 먼저, main 함수에 대해 assmebly 코드를 보면, PC 값과 그에 해당하는 assembly 명령어가 출력된다. procedure call (함수 호출) 명령어의 경우, 호출하는 함수 이름과 함께 출력된다...
[Bomb Lab] 프로젝트 파일 다운로드 및 준비 과정 (GDB 설치) 프로젝트 파일 다운로드 프로젝트 파일은 아래 링크에서 다운로드 받을 수 있다. 프로젝트 다운로드 링크 : http://csapp.cs.cmu.edu/3e/labs.html CS:APP3e, Bryant and O'Hallaron Lab Assignments This page contains a complete set of turnkey labs for the CS:APP3e text. The labs all share some common features. Each lab is distributed in a self-contained tar file. You will need a CS:APP account to download the code. To untar foo.tar, t csapp.cs.cmu...