질문
0x555555554652 <caller> push rbp
0x555555554653 <caller+1> mov rbp, rsp
0x555555554656 <caller+4> push 7
0x555555554658 <caller+6> mov r9d, 6
0x55555555465e <caller+12> mov r8d, 5
0x555555554664 <caller+18> mov ecx, 4
0x555555554669 <caller+23> mov edx, 3
0x55555555466e <caller+28> mov esi, 2
0x555555554673 <caller+33> movabs rdi, 0x1b69b4bacd05f15
0x55555555467d <caller+43> call callee <callee>
0x555555554682 <caller+48> add rsp, 8
여기 마지막에 add rsp, 8이 늘어난 스택 다시 줄여주는거라는데 8이 call callee할때 늘어난건가요?
아니면 어디서 늘어난건가요
#시스템_해킹
#배경지식
#호출_규약
작성자 정보
답변
1
2dedce
워게임 고인물
앞부분에서
0x555555554652 <caller> push rbp <------ rbp 스택에 넣어서 저장 나중에 함수 끝낼 때 leave;하면 rbp는 복구됩니다.
0x555555554653 <caller+1> mov rbp, rsp
여기서 스택에 rbp값을 푸시하는데 이거는 함수호출과 관련없는 부분이고 함수 시작부분에는 항상 있는 부분이고요.
아래 부분에서 함수 호출전 인자를 채우는 부분에서 rsp가 8 줄어들었습니다.
0x555555554656 <caller+4> push 7 <---- 여기서 스택에 푸시하면 스택에 rsp가 8 줄어듭니다.
0x555555554658 <caller+6> mov r9d, 6
0x55555555465e <caller+12> mov r8d, 5
0x555555554664 <caller+18> mov ecx, 4
0x555555554669 <caller+23> mov edx, 3
0x55555555466e <caller+28> mov esi, 2
0x555555554673 <caller+33> movabs rdi, 0x1b69b4bacd05f15
0x55555555467d <caller+43> call callee <callee>
0x555555554682 <caller+48> add rsp, 8 <------------- rsp를 8 더해서 복구시킵니다.
즉 x64의 호출규약인 fastcall에따라 함수 호출 전에 인자를 먼저 레지스터에 넣고, 남은 인자는 스택에 넣기때문에 스택에 넣은 만큼 caller가 rsp를 다시 더해줘야 합니다. rsp는 항상 스택의 top을 가리키기 때문에 푸시를 하면 스택에 값을 넣음과 동시에 rsp는 새로운 top을 가리키기 위해 -8 되어야 하죠.
call callee할 때도 사실 복귀주소가 스택에 푸시되므로 rsp가 8줄어들긴 하지만 그건 어차피 함수 마지막에 ret;하면 스택에서 팝되면서 복귀하기 때문에 관련없습니다.