어셈블리어 호출 규칙


어셈블리어의 호출 방식에 대해 알아봅시다. C 언어에서는 함수를
실행할 때 파라미터를 전달하는 방식을 갖습니다. printf라는 함수를
실행할 때는 printf(“내용”)과 같이 출력하기 원하는 내용을 전달합니
다. 이처럼 리눅스 환경의 어셈블리어도 파라미터를 전달하는 규칙이
있습니다. 일단 레지스터에 필요한 파라미터를 넣고, 모자라면 스택에
남은 파라미터를 넣는 형태로 진행됩니다.
앞서 실행한 call puts를 찾아가 직전에 있는 mov rdi, message를
살펴봅시다. 이 내용은 rdi에 message를 넣는 모습입니다. 파라미터
가 다수인 경우에는 레지스터에 더 많은 양을 전달하게 됩니다. 세부적
인 규칙은 다음과 같이 정해집니다. 아직은 잘 몰라도 되는 내용이니
간단히 읽고 넘어갑시다.

① 레지스터에 들어가는 파라미터는 오른쪽에서 왼쪽으로 전달해야
하며, 할당 순서는 정수와 포인터의 경우 rdi -> rsi -> rdx -> rcx ->
r8 -> r9순이며, 부동 소수점(float, double)의 경우 xmm0 -> xmm1
-> xmm2 -> xmm3 -> xmm4 -> xmm5 -> xmm6 -> xmm7순입
니다.


② 추가 파라미터는 오른쪽에서 왼쪽으로 스택에 지정되며 호출 후
호출자가 제거해야 합니다.
③ 파라미터 지정 후 호출 명령어가 생성되어 제어되면 [rsp]레지스
터로 리턴하며, 첫번째 메모리 파라미터는 [rsp+8]레지스터에 지정됩
니다.
④ 스택 포인터 rsp는 호출되기 전에 16byte 경계에 정렬되어야 합
니다. 하지만 호출 시 스택의 리턴 주소에 8byte를 푸시하므로 gets 함
수가 시작되면 rsp가 정렬되지 않습니다. 무언가를 밀거나 8byte만큼
을 빼서 rsp에 여분의 공간을 만들어야 합니다.

 

 

'경로 및 정보' 카테고리의 다른 글

shell code sample  (0) 2025.01.28
Protostar - Stack4  (0) 2025.01.28
리버싱에서의 레지스터란? (참고)  (0) 2025.01.27
PLT와 GOT 자세히 알기 1  (0) 2025.01.26
spel injection  (0) 2024.12.16
블로그 이미지

wtdsoul

,