작은 메모장

함수 호출규약 본문

KISA 사이버 보안 훈련/리버스 엔지니어링 훈련

함수 호출규약

으앙내눈 2023. 7. 5. 22:04

함수 호출규약 (Function calling convention)

함수를 호출하는 호출자(caller)와 호출당하는 피호출자(callee)간 파라미터 전달 및 사용된 스택영역 해제와 관련된 내용을 정의하고 있는 규약

주로 파라미터 전달 방법, 파라미터 전달 순서, 파라미터 전달에 사용된 스택영역 해체 주체에 대한 정의를 포함

IA32/64에서는 함수 호출 시 파라미터와 복귀 주소를 스택에 저장, MIPS, ARM 아키텍처에서는 레지스터에 저장

아키텍처 호출 규약 이름 매개변수 전달방향 매개변수 전달에 사용되는 레지스터 스택영역 해제 주체
IA32 cdecl RTL 없음 호출자
stdcall RTL 없음 피호출자
fastcall RTL ECX, EDX 피호출자
x86-64 MS x64 호출규약 RTL RCX/XMM0,
RDX/DMM1,
R8/XMM2,
R9, XMM3
호출자
시스템 V AMD64 ABI RTL RDI, RSI, RDX, RCX, R8, R9, XMM0-7 호출자

 

함수 파라미터 전달

함수에 파라미터를 전달하는 방식은 크게 3가지, 스택 이용, 레지스터 이용, 스택과 레지스터 이용

__cdecl, __stdcall 모두 스택을 이용하여 파라미터 전달

 

함수 파라미터 전달 순서

파라미터 전달에 스택을 이용하는 경우, 파라미터 전달 순서에 관한 약속이 필요

Leftmost to Rightmost 방식과 Rightmost to Leftmost 방식 중 하나를 사용

__cdecl, __stdcall 모두 Leftmost to Rightmost 방식

         ----------> Leftmost to Rightmost
function (A, B, C, D)
         <---------- Rightmost to Leftmost

함수 파라미터 전달 코드 예

.text:00401023		push	3
.text:00401023		push	2
.text:00401023		push	1
.text:00401023		call	sub_401000

 

리턴 값 전달

리턴값 사이즈 <= 4byte인 경우, EAX 레지스터를 이용하여 리턴 값을 전달

4byte < 리턴값 사이즈 < 8byte인 경우, 상위 4바이트는 EDX, 하위 4바이트는 EAX레지스터를 이용하여 값을 전달

[callee]
.text:00401014		mov		eax, [ebp+var_4]

.text:00401017		mov		esp, ebp
.text:00401019		pop		ebp
.text:0040101A		retn


[caller]
.text:0040106A		call	sub_401000
.text:0040106F		add		esp, 8
.text:00401072		push	eax

 

레지스터 사용

Caller Saved Register

callee가 자유롭게 사용할 수 있는 레지스터

함수를 호출하기 전과 함수에서 복귀한 후 EAX, ECX, EDX 레지스터 값이 같아야 함

이때, caller가 callee를 호출하기 전, 위 3개 값을 백업해야 함

Callee Svaed Register

callee는 함수 호출 전과 함수에서 복귀한 후 EBX, ESI, EDI 레지스터 값이 같아야 함

callee는 이 레지스터들을 사용하는 경우, 위 3개 값을 백업해야 함