함수 호출 규약
Calling Convention, 해석하면 '함수 호출 규약' 이란 어떤 함수를 호출 할 때, 그 함수의 파라미터(인자)를 어떤 방식으로 전달하는가에 대한 하나의 약속이다.
함수를 호출 할 때, 프로세스에 정의되어있는 스택 메모리 공간을 이용해서 파라미터를 함수로 전달하게 되고, 이 스택 메모리 공간은 프로세스가 실행 될 때에 해당 PE헤더에 스택 메모리의 크기가 명시되어 있다. 스택에 저장되는 값들은 임시적인 값들이기 때문에 더이상 사용하지 않더라도 값을 지우거나 하지 않는다, 굳이 지우려고 하지 않더라도 스택에 다른 값을 입력할 때 저절로 덮어 쓰기 때문에 불필요한 CPU 자원 소모의 낭비를 막기 위해서 그대로 내버려 둔다.
주요한 함수 호출 규약
- cdecl
- stdcall
- fastcall
cdecl 방식
c언어 에서 주로 사용되는 방식으로 Caller에서 Stack을 정리
main() 쪽에서 함수 호출뒤 ADD ESP. 8 을 실행
1
2
|
CALL 00401000
ADD ESP, 8 ; 함수 호출뒤 stack 정리
|
cs |
컴파일 뒤 어셈블리어를 확인하면 CALL 00401000 함수 호출 뒤 ADD ESP, 8로 Stack을 정리한다.
➡️ 장점: print()함수와 같이 가변 길이 파라미터를 전달 가능. (stdcall, fastcall에서는 가변 길이 파라미터를 전달하는 기능을 구현하기 어렵다)
stdcall 방식
Win32 API에서 사용되는 방식으로 Callee에서 Stack을 정리
c언어에서 컴파일 하고 싶다면 함수 앞에 _stdcall 키워드를 붙여주면 된다.
1
2
3
4
5
6
|
#include "stdio.h"
int _stdcall add(int a, int b)
{
return a + b;
}
|
cs |
1
|
CALL 00401000; 함수 호출 뒤 ADD ESP, 8이 없다.
|
cs |
컴파일 뒤 어셈블리어를 확인하면 CALL 00401000 뒤에 ADD ESP, 8이 없다.
➡️ 장점: Callee에 Stack 정리 코드가 있어서 Caller의 크기가 cdecl방식에 비해 작아진다.
fastcall 방식
기본적으로 stdcall과 방식이 같다.
함수에 전달하는 파라미터 일부(2개까지)를 스택 메모리가 아닌 레지스터를 이용하여 전달한다.
함수의 파라미터가 4개라면 앞의 두개는 ECX, EDX파라미터를 이용하여 전달
➡️ 장점: 파라미터 전달시 스택이 아닌 레지스터에 접근하기 때문에 훨씬 더 빠르다.
출처 및 참고 : https://security-nanglam.tistory.com/540
HyunZzang의 프로그래밍 공간 / 함께 공부해요!!
도움이 되셨다면 "좋아요❤️" 또는 "구독👍🏻" 부탁드립니다 :)