2 minute read

결과 화면

Image





진행 과정

Image

<+0> ~ <+2> %rbp와 %rbx 레지스터 값을 stack에 저장. %rsp를 이용해 stack을 0x28(40byte)만큼 할당함.

<+6> ~ <+25> %fs:0x28에 저장된 값을%rax에 로드한 후 스택의 0x18(%rsp)에 저장. %eax 값을 XOR하여 0으로 초기화하고 %rsp값을 %rsi에 저장함(할당된 스택 위치 넘겨주기). 그리고 read_six_numbers 함수를 호출함. 딱봐도 6개의 숫자를 입력해야 할 것 같다. read_six_numbers 함수를 disassemble 해보자.


Image

<+0> %rsp로 함수 호출에 필요한 stack공간 8byte 확보

<+4> %rsi 값을 %rdx로 복사한다. 이때 %rsi값에는 phase_2에서 저장한 %rsp의 값이 담겨있다.

<+7> lea(load effective address)는 메모리 주소를 계산하는 instruction인데, 현재 stack pointer가 가리키는 지점에서 4byte 떨어진 위치를 계산하고 그 값을 %rcx에 저장.

<+11> ~ <+15> 이번에는 %rsi에 0x14(20)byte를 더한 주소를 계산하여 %rax에 저장하고 있음. 이를 stack에 저장함

<+16> ~ <+25> 비슷한 방식으로 %rsi에 0x10(16), 0xc(12), 0x8(8) byte만큼 더한 주소를 계산하여 여러 레지스터에 저장한다. 왠지 4byte 단위로 참조하므로 6개의 수가 들어가는 배열이 저장되려나 싶다. 즉, 배열 element의 주소를 정리하면 다음과 같다.

Image

<+29> %rip 기준 0x12d4만큼 더한 주소(0x555555402e29) 계산하여 %rsi에 저장한다. 뭐가 저장되었나 문자열로 표시해 봤더니, 포맷 문자열이 나왔다. 이 형식으로 입력을 받겠구나 싶었다.

Image

<+36> %eax register의 값을 0으로 초기화. 이제 어떤 값이 담길 준비를 하는 거겠지?

<+41> sscanf 함수를 호출하여 사용자 입력을 처리함.

<+46> sscanf 함수가 입력된 숫자를 읽어 메모리 주소에 저장함. 이제 숫자가 저장될 위치에 대한 메모리 주소는 필요하지 않으므로, %rsp를 0x10만큼 증가시켜 스택을 복구함.

<+50> ~ <+53> %eax에는 sscanf가 읽어들인 값의 개수가 저장되어 있음. sscanf는 숫자 6개를 인자로 받으므로 cmp문으로 비교하고, jle는 작거나 같을 때 명시된 주소로 이동하니 5 이하의 값이 입력되었다면 explode로 이동

<+55> ~ <+59> 6개 값 잘 입력했다면 스택을 복구하고 return


<+30> ~ <+34> 다시 Phase_2 함수로 돌아왔다. coml로 stack의 첫 번째 값을 1과 비교하고 같지 않을 경우 explode_bomb이 호출되는 주소로 분기하므로 무조건 첫 번째 값은 1이어야 한다. (1 %d %d %d %d %d)

<+36> ~ <+39> 현재 %rsp는 배열의 첫 번째 요소 %rsp의 값을 %rbx로 복사하여 %rbx가 stack의 첫 번째 값을 가리키게 하고, %rbx에서 0x14(20 byte)만큼 떨어진 곳의 주소를 %rbp에 저장하여 배열 끝을 가리키게 한다.

<+43> 0x555555401351 <phase_2+61>로 jump

<+61> ~ <+63> %rbx(현재 숫자 가리킴)를 %eax에 저장하고, %eax를 두 배로 만들어서 이 값이 다음 숫자(0x4(%rbx))와 같다면 <+52>로 점프, 아니면 <+70>으로 가서 explode.

<+52> ~ <+59> 첫 번째 숫자 주소에 4바이트를 더하여 다음 숫자를 참조하도록 하고, cmp를 통해 %rbp(배열 끝 주소)와 %rbx와 비교하여 같으면(끝에 도달함) <+77>로 이동. 루프 형식이었다. 이전 숫자를 두 배 한 값을 다음 숫자에 저장하면 그게 값이 되므로, 이미 구한 1을 이용하여 두 배씩 해주면 최종 답은 1 2 4 8 16 32임을 알 수 있다.

<+77> ~ <+99> 함수 종료 후 스택 정리 및 스택 손상 여부 검사 진행





정답

1 2 4 8 16 32



Leave a comment