phase 2 부터는 부분 코드를 단계별로 보면서 설명하겠습니다.
phase 2 입니다.
<+0>부터 <+25>의 코드를 보겠습니다.
<+20>은 eax를 0으로 초기화하는 작업이니 큰 신경은 쓰지 않아도 될 것 같습니다.
<+25>에서 read_six_numbers를 호출합니다.
함수 이름부터 숫자 6개를 읽어온다고 하니 입력값이 숫자 6개가 될 것 같습니다.
하지만 이런 단순한 추측으로 섣부르게 입력했다가는 테러리스트가 될 수 있으니
마음을 가라앉히고 함수 내부로 들어가보겠습니다.
phase_1에서도 언급했듯이 rsi가 함수 인자로 주로 들어갑니다.
그래서 rsi의 값을 확인해보았습니다.
그냥 감대로 입력했어도 테러리스트가 되지는 않았겠네요.
입력 값의 형식을 알아냈으니 형식에 맞게 임의의 input
"10 20 30 40 50 60"
을 주고 phase 2의 남은 부분을 확인해보겠습니다.
rsp와 0을 비교하네요. 확인해보니 임의로 넣었던 rsp에는 입력 값이 있었습니다.
(<+22>에서 rsp를 rsi에 대입하고 있는 것으로도 추측할 수 있겠네요.)
그러면 rsp의 주소에는 입력의 첫 번째 값이 들어있을 것입니다.
확인해보니 입력값과 동일합니다.
다시 돌아가서 <+34>에서 둘이 다르면 <+43>으로 분기하네요. 둘이 다르면 터진다는 소리입니다.
그럼 입력의 첫 번째 값은 무조건 0이 되어야 합니다.
<+36>에서는 1과 rsp+0x4를 비교합니다. rsp+0x4에는 두 번째 입력 값이 들어있겠죠.
두 번째 입력값과 1을 비교했을때 <+41>에서 같으면 <+48>로 분기합니다.
다르면 분기하지 못하고 <+43>에서 터져버리겠네요.
<+30> ~ <+43>의 코드로 입력의 첫 번째와 두 번째 값이 0, 1이 되어야 함을 알 수 있습니다.
<+48>에서 rbx에 입력 값을 넣습니다.
<+51>에서는 rbp에 입력의 5번째 값을 넣네요.
(여기서 주의하셔야 할 것이 0x10은 십진수 10이 아니라 16진수 10입니다.
십진수로 따지면 16에 해당하겠네요. rsp + (0x4)*4이므로 5번째 input값이 되겠습니다.)
그리고 <+55>에서 <+66>으로 분기합니다.
<+66>을 보니 eax에 두 번째 입력 값을 넣습니다.
<+69>에서 첫 번째 입력 값과 두 번째 입력 값을 더합니다.
<+71>에서는 이걸 세 번째 입력 값과 비교하네요.
<+74>에서 비교 결과가 같다면 <+57>로 분기합니다. 아니면 터지네요.
정리하면, a[i + 2] = a[i] + a[i + 1]이고...
피보나치 수열처럼 보이네요.
그래도 막 입력하다가 테러리스트가 되는 불상사는 막고 싶어서 코드를 계속 읽어 보겠습니다.
<+57>로 분기한 상황입니다. 여기서는 rbx에 *rbx+0x4를 저장합니다.
즉, 다음 입력 값으로 넘어가겠다는 소리죠.
그리고 rbx와 rbp를 비교합니다.
<+51>에서 rbp에 5번째 입력 값을 넣었습니다.
즉, rbx가 5번째 입력 값이니??? 라고 물어보는 꼴이죠.
<+63>에서 비교 결과가 같으면 <+83>으로 분기해서 phase_2를 끝냅니다.
지금은 같지 않은 상황이니 분기하지 못하고 다음으로 넘어가야겠네요.
<+66>입니다. 아까 했던 부분 아닌가요?
<+57>에서 rbx에 *(rbx+0x4)를 저장했기 때문에 지금은 세 번째 입력 값이 eax에 저장이 될 것입니다.
그렇다면,
두 번째 입력 값 + 세 번째 입력 값 = 네 번째 입력 값
이 되겠네요.
그리고 얘를 rbp가 5번째 입력 값이 될 때까지 반복합니다.
입력 값은 6개이므로 rbp가 5번째 입력 값이 되는 순간,
<+66> ~ <+76>의 연산 결과가 될 7번째 입력 값이 없기 때문에 5번째 입력 값이 반복 종료지점이 되나봅니다.
첫 번째 입력 값이 0, 두 번째 입력 값이 1이니까
정답은 "0 1 1 2 3 5"가 되지 않을까요?
확인해보면,
phase 2 가 통과 됩니다.