강의정리/Z0FCourse_Re

[x64] fastcall과 호출 규약

우와해커 2020. 1. 21. 15:36

참고 (공통: 함수 매개면수는 오른쪽에서 왼쪽 순으로 스택 위로 푸시된다)
- cdecl: 일반적으로 x86 C 컴파일러의 기본 호출 규약이다.
- stdcall: 마이크로소프트 Win32 API 및 오픈 왓콤 C++의 표준 호출 규약이다.
- fastcall: x64 Windows의 호출 규칙이다.

 

호출규약에 대해 더 많은 정보 필요한 경우 아래 참고
https://docs.microsoft.com/ko-kr/cpp/build/x64-software-conventions?view=vs-2019
https://docs.microsoft.com/ko-kr/cpp/build/x64-calling-convention?view=vs-2019
https://en.wikibooks.org/wiki/X86_Disassembly/Calling_Conventions
https://en.wikibooks.org/wiki/X86_Disassembly/Calling_Convention_Examples

 


Fastcall

 

우리는 x64 Windows에서 리버스 엔지니어링을 할 것이기 때문에 대부분 x64 빠른 호출에 중점을 둘 것입니다.
DLL 장에 들어가면 cdecl도 알아야합니다.

 

일반적으로 호출 규칙 이름 앞에 이중 밑줄 접두어 (__)가 표시됩니다. 예를 들면 다음과 같습니다. __fastcall.
나는 이것이 필요하지 않기 때문에 이것을 하지 않을 것입니다.

 

Fastcall은 x64 Windows의 호출 규칙입니다 .Windows uses a four-register fastcall calling convention by default.
Fastcall은 함수 매개 변수를 뒤로 (오른쪽에서 왼쪽으로) 푸시합니다.
호출 규칙에 대해 이야기 할 때 "응용 프로그램 이진 인터페이스"(ABI)에 대해들을 수 있습니다.
ABI는 호출 규칙, 매개 변수 처리 등과 같은 프로그램에 대한 다양한 규칙을 정의합니다.

 

So how does the x64 Windows calling convention work?

 

- 처음 네 개의 인수 / 매개 변수는 레지스터로 전달됩니다. 부동 소수점 값 (floats 또는 double)이 아닌 매개 변수는
RCX, RDX, R8 및 R9 (순서대로)를 통해 전달됩니다. 부동 소수점 값에는 포인터, 정수, 부울, 문자 등이 포함됩니다.
부동 소수점 매개 변수는 XMM0, XMM1, XMM2 및 XMM3 (순서대로)을 통해 전달됩니다.

부동 소수점 값은 부동 소수점과 복식을 포함합니다.
전달되는 매개 변수가 레지스터에 맞지 않을 정도로 큰 경우 참조로 전달됩니다.
매개 변수는 여러 레지스터에 분산되지 않습니다. 다른 매개 변수는 스택에 놓입니다.

레지스터를 통해 전달된 매개 변수까지, 모든 매개 변수에는 스택에 예약 된 공간이 있습니다.
또한 매개 변수가 전달되지 않더라도 스택에 4 개의 매개 변수를 위한 공간이 항상 있습니다.
이 공간은 컴파일러가 사용할 수 있고 자주 사용하기 때문에 완전히 낭비되지 않습니다.

 

- 기본 포인터 (RBP)가 저장되어 복원 할 수 있습니다.

 

- 함수의 반환 값은 integer, bool, char 등인 경우 RAX를 통해 전달된다.
  float 또는 double 인 경우 XMM0을 통해 전달됩니다.

 

- caller는 callee의 매개 변수를 위한 공간을 할당해야합니다.
  매개 변수가 전달되지 않더라도 호출자는 항상 4개의 매개 변수를 위한 공간을 할당해야 합니다.

 

- 레지스터 RAX, RCX, RDX, R8, R9, R10, R11은 휘발성으로 간주되며 함수 호출시 (전체 프로그램 최적화와 같은 분석에 의해 안전성이 제공되지 않는 한) 소멸 된 것으로 간주되어야합니다. 레지스터 RBX, RBP, RDI, RSI, RSP, R12, R13, R14 및 R15는 비휘발성으로 간주되며 이를 사용하는 함수에 의해 저장 및 복원되어야합니다.

 

- 필요한 경우 대부분 호출자가 스택을 청소합니다. 

 


cdecl (C Declaration)

- Fastcall은 함수 매개 변수를 오른쪽에서 왼쪽으로 푸시합니다.
- 기본 포인터 (RBP)가 저장되어 복원 할 수 있습니다.
- 반환 값은 EAX를 통해 전달됩니다.
- 호출자가 스택을 청소합니다. 이것이 cdecl을 특별하게 만드는 것입니다

  호출자가 스택을 정리하기 때문에 cdecl은 다양한 수의 매개 변수를 허용합니다