함수 호출 규약 : 함수의 호출 및 반환에 대한 약속
함수 호출 시 프로그램의 실행 흐름이 다른 함수로 이동하며 반환 시 원래의 함수로 돌아와 기존의 실행 흐름 이어감.
-> 반환된 이후를 위해 호출자(Caller)의 상태(Stack frame) 및 반환 주소(Return Address)를 저장해야 함.
-> 피호출자(Callee)가 요구하는 인자 전달, 피호출자 실행 종료 시 반환값 전달받음.
컴파일러는 지원하는 호출 규약 중 CPU 아키텍처에 적합한 것을 선택.
-> ex. 인자 전달 시 x86 아키텍처는 레지스터의 수가 적어 스택으로 인자 전달, x86-64 아키텍처는 레지스터만 이용하고 인자가 너무 많을 때만 스택 이용.
CPU의 아키텍처가 같아도 컴파일러가 다르면 적용하는 호출 규약이 다를 수 있음.
-> ex. C언어 컴파일 시 윈도우는 MSVC, 리눅스는 gcc 사용.
x86 아키텍처는 스택을 통해 인자를 전달하며 사용한 스택을 호출자가 정리함.
인자 전달 시에는 마지막 인자부터 첫 번째 인자까지 거꾸로 스택에 push.
리눅스는 SYSTEM V(SYSV) Application Binary INterface(ABI)를 기반으로 제작.
SYSV ABI는 ELF 포맷, 링킹 방법, 함수 호출 규약 등의 내용 포함.
x86 함수 호출 규약
| 함수 호출 규약 | 사용 컴파일러 | 인자 전달 방식 | 스택 정리 | 
|---|---|---|---|
| stdcall | MSVC | Stack | Callee | 
| 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 | 
| System ABI | GCC | RDI, RSI, RDX, RCX, R8, R9, XMMO-7 | Caller | 
버퍼(Buffer)는 완충 장치 라는 뜻으로, 컴퓨터 과학에서는 데이터가 목적지로 이동되기 전에 보관되는 임시 저장소라는 뜻.
수신 측과 송신 측 사이에 버퍼라는 임시 저장소를 두고 간접적으로 데이터 전달.
최근에는 저장될 수 있는 모든 단위를 버퍼라고 부름.
버퍼 오버플로우(Buffer Overflow)는 버퍼가 넘치는 것을 의미함.
버퍼는 각각 크기가 있는데 큰 크기의 버퍼에 들어가야 하는 데이터가 작은 크기의 버퍼에 들어가려 하면 오버 플로우 발생.
일반적으로 버퍼는 메모리상 연속해서 할당되어 어떤 버퍼에서 오버 플로우가 발생하면 뒤에 있는 버퍼들의 값이 조작될 수 있음.
버퍼 오버플로우는 모든 메모리 영역에서 발생할 수 있으며, 이를 통해 중요 데이터가 변조되거나 데이터 유출, 실행 흐름 조작 등의 문제로 이어질 수 있음.