[BombLab] phase_2 해설
phase_2는 6개의 숫자를 알아내야한다.
phase_2 disassemble
입력한 수가 들어간 레지스터 찾기
phase_2를 disassemble하였다.
<+9>를 보면 read_six_numbers 함수를 호출하는 것을 볼 수 있다. 근데 이번에는 굳이 저 함수를 뜯어보지 않을 것이다. 함수명으로 기능을 유추할 수 있으니까!
대신 우리는 저 함수로 받은 6개의 숫자가 어느 레지스터에 들어갔는지를 알아보아야한다. 코드를 쭉 따라가보면 <+14>로 가는 것을 볼 수 있다. <+14> 부터 rsp에 있는 수를 건드는게 보인다. 이 안에 의미있는 데이터가 있는 것 같다.
그래서 우선 실행한 후 phase_2의 정답을 입력하는 부분에 아무런 6개의 숫자를 넣어본다.
그 다음 ni로 <+14> 까지 간다.
0x4(%rsp)를 하는 것을 보니까 숫자가 4바이트 단위로 들어간다는 것을 추측할 수 있다.
그럼 rsp를 보자
예상대로 첫번째로 입력한 수가 나왔다.
그럼 rsp에 4비트를 더한 위치에는 두번째로 입력한 수가 있을 것이라고 추측할 수 있다.
출력해보면 맞다는 것을 확인할 수 있다.
함수 흐름 분석하기
그럼 본격적으로 함수를 분석해보자
6개의 숫자를 입력받고 다음 instruction은
위와 같다. 이는 rsp의 첫번째 수의 값과 1을 비교하여 같은지 확인하고, 같으면 52번으로 분기, 아니면 폭발한다.
이를 통해 첫번째 수는 1이어야한다 라는 것을 알 수 있다.
52와 57에서는 현재 rsp에 있는 값의 다음 값은 rbx에, 현재 rsp로부터 6칸 떨어진 부분의 값은 rbp에 넣는다는 것을 볼 수 있다.(0x18은 16진수라 10진수로 치면 24이다!)
그 다음 27번으로 분기하는데, 이 때 eax에 현재 rbx보다 하나 앞에 있는 값(지금 2번째 숫자 가지고 있으면 1번째 숫자)를 eax에 넣는다.
그 다음 eax + eax를하고, 현재 rbx값과 비교한다. 만약 같으면 41번으로 넘어가고, 아니면 폭발한다. 이를 통해 뒤에있는 값은 앞에있는 값의 2배여야한다는 것을 알 수 있다.
41번을 보면 현재 rbx에 $0x4를 더함으로써 rbx가 향하고 있는 숫자를 한 칸 옮기는 것을 볼 수있다. 그 다음 rbp값이랑 비교하는데 rbp는 7번째 수가 들어있다.(57참고) 그래서 만약 이 값이랑 rbx가 같아졌다면 6개의 수를 모두 봤다는 뜻이므로 64번으로 분기하여 종료한다.
이를 종합해보면, 첫번째수는 1이고 뒤로 갈수록 2배로 늘어나야한다.
정답
1 2 4 8 16 32
킵고잉~