본문 바로가기
.study/pwnable

[포너블 기초] 함수 호출 규약

by Carry_on 2023. 9. 14.

함수 호출 규약은 함수를 호출 했을 때와 함수를 실행하고 반활할 떄의 약속이다.

 

예를 들어 Main함수에서 sum함수를 호출 할 때, sum으로 인자값을 전달해주는데 어떤 방법을 사용하고, sum함수의 호출이 끝났을 때 sum함수에서 return한 값을 어떻게 main함수로 가져오는지 등을 정해놓은 것이 함수 호출 규약이다.

 

 

x86 함수 호출 규약

함수호출규약 사용 컴파일러 인자 전달 방식 스택 정리 적용
stdcall MSVC Stack Callee WINAPI
cdecl GCC, MSVC Stack Caller 일반 함수
fastcall MSVC ECX, EDX Callee 최적화된 함수
thiscall MSVC ECX(인스턴스), Stack(인자) Callee 클래스의 함수

 

x86-64 함수 호출 규약

함수호출규약 사용 컴파일러 인자 전달 방식 스택 정리 적용
MS ABI MSVC RCX, RDX, R8, R9 Caller 일반 함수,
windows syscall
System ABI GCC RDI,RSI,RDX,RCX,R8,R9,XMM0-7 Caller 일반 함수

 

CallerCallee

Caller는 호출자 즉, 함수를 호출한 쪽이고 Callee는 피호출자 즉, 호출을 당한 함수를 말한다.

예를 들어 main()에서 add()를 호출 했다면, Caller는 main()이고 Callee는 add()이다.

 

cdecl

#include "stdio.h"

int add(int a, int b)
{
    return (a + b);
}

int main(int argc, char* argv[])
{
    return add(1, 2);
}

위 코드를 디버거로 살펴보면 401010 main()에서 파라미터 1,2를 401000 add()로 넘겨주고, 함수가 끝난 뒤 Caller였던 main 함수에서 ADD ESP,8 명령어를 통해 스택포인터의 위치를 조정해주는 것을 볼 수있다.

 

stdcall

#include "stdio.h"

int _stdcall add(int a, int b)
{
    return (a + b);
}

int main(int argc, char* argv[])
{
    return add(1, 2);
}

stdcall 방식에서는 add()함수에서 RETN 8을 통해 Callee가 직접 스택을 정리하는 모습을 볼 수있다.

'.study > pwnable' 카테고리의 다른 글

[포너블 기초] 버퍼 오버플로우  (0) 2023.10.01
[포너블 기초] x86_handray  (0) 2023.09.14
[포너블 기초] Docker  (0) 2023.09.13
[포너블 기초] 스택 프레임  (0) 2023.09.12
[포너블 기초] x86-32, x86-64 레지스터  (0) 2023.09.12