관리 메뉴

FU11M00N

함수 호출 규약 (feat stdcall,fastcall) 본문

System Hacking/System Hacking Basic

함수 호출 규약 (feat stdcall,fastcall)

호IT 2020. 11. 6. 21:06

- 함수 호출 규약?

함수 호출 규약 (Calling Convention) 함수(subroutine, callee)가 어떻게 인자를 전달받고 결괏값을 반환하는지에 대한 로우 레벨에서의 규칙입니다.

 

- Callee? Caller?

 

Caller(호출자) - 함수를 호출한 쪽.

Callee(피호출자) - 호출을 당한 함수.

ex) main()에서 printf()를 호출했다면 Caller는 main(), Callee는 printf().

 

 

 

c언어에서는 기본적으로 명시를 안 하면 cdecl 함수 호출 규약을 사용합니다.

이번 글에선 stdcall 과 fastcall을 자세히 알아보겠습니다.

 

 

- stdcall

 

stdcall은 가변인자 ex) printf를 지원하지 않습니다. 

stdcall은 Callee 에서 스택을 정리하기 때문에 Callee 쪽에서는 가변 인자의 스택 크기를 알 수 없습니다.

 

stdcall은 Win32 API 함수에서 자주 사용 되는 호출 규약입니다.

또한 DLL파일을 만들때에도 STDCALL로 선언하여 다른 언어에서 API를 호출할 때 호환성을 위함입니다.

c언어에서는 stdcall을 사용할려면 함수 앞에 명시해줘야 합니다.

인자 전달 순서

오른쪽 인자부터 전달한다.

인자 전달 매체

Stack을 사용합니다.

Stack Frame 정리 방법

호출을 당한 Callee가 함수를 종료하면서 인자를 정리합니다.

 

stdcall c코드
stdcall 디스어셈블

 

- fastcall

 

인자 전달에 레지스터를 사용하므로, 속도가 빠른 장점이 있다.

 

주로 2개의 인자를 사용하며, 인자가 3개 이상이면 Stack을 함께 사용해 인자를 전달합니다.

 

함수에 전달하는 파라미터 일부(2개까지) 스택 메모리가 아닌 레지스터를 이용하여 전달합니다.

인자 전달 순서

오른쪽 인자부터 전달한다.

인자 전달 매체

ECX, EDX, Stack 순서로 사용한다. 보통은 2개의 인자만 사용한다.

Stack Frame 정리 방법

호출을 당한 Callee가 함수를 종료하면서 인자를 정리한다.

주의. 아래의 코드들은 3개의 인자입니다.

fastcall c코드
fastcall 디스어셈블

 

한장 으로 요약. 출처 - 리버싱 입문 조성문 프리렉

함수 호출 규약을 한 장으로 요약하자면 위의 사진과 같습니다.

 

 

ref:

https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160&viewFallbackFrom=vs-2019

 

x64 calling convention

Details of the default x64 calling convention.

docs.microsoft.com

https://tyeolrik.github.io/reversing/2017/03/06/Reversing-9-Calling-Convention.html

https://blog.kimtae.xyz/7

 

 

Comments