본문 바로가기
reversing

함수호출 규약(Calling Convention)

by 코끼리_땃쥐 2021. 11. 9.
반응형

Calling Convention은 우리말로 '함수 호출 규약' 이라고 합니다.

'함수를 호출할 때 어떤 식으로 전달하는가?'에 대한 일종의 약속입니다.

 

함수 호출전에 파라미터를 스택을 통해서 전달한다는 것을 알고 있습니다. 스택이란 프로세스에 정의된 메모리 공간이며 아래 방향(주소가 줄어드는 방향)으로 자랍니다. 또한 PE헤더에 그 크기가 명시되어 있습니다. 즉 프로세스가 실행될 때 스택 메모리의 크기가 결정됩니다.

 

스택에 저장된 값은 임시로 사용하는 값이기 때문에 더 이상 사용하지 않는다고 하더라도 값을 지우거나 하면 불필요하게  CPU자원을 소모합니다. 어차피 다음 번에 스택에 다른 값을 입력할 때 저절로 덮어쓰는데다가 스택 메모리는 이미 고정되어 있기 때문에 메모리 해제를 할 수도 없고 할 필요도 없습니다.

 

스택 메모리는 고정되어 있고 ESP로 스택의 현재위치를 가리키는데, 만약 ESP가 스택의 끝을 가리킨다면 더 이상 스택을 사용 할 수 없습니다. 함수 호출 후에 ESP(스택 포인터)를 어떻게 정리하는지에 대한 약속이 바로 함수 호출 규약입니다. 주요한 함수 호출 규약은 아래와 같습니다.

 

cdecl

stdcall

fastcall

 

애플리케이션 디버깅에서는 cdecl와 stdcall의 차이점을 확실히 알아야합니다.

어떤 방식이든지 파라미터를 스택을 통해 전달하는 기본 개념은 동일합니다.

 

cdecl

cdecl 방식은 주로 C언어에서 사용되는 방식이며, Caller(호출자)에서 스택을 정리하는 특징을 가지고 있습니다.

 

stdcall

stdcall 방식은 Win32 API에서 사용 되며, Callee(피호출자) 에서 스택을 정리하는 것이 특징입니다.

C언어는 기본적으로 cdecl 방식이라고 설명하였습니다. stdcall방식으로 컴파일 하고 싶을 때는 '_stdcall' 키워드를 붙여 주면됩니다.

 

fastcall

tastcall 방식은 기본적으로  stdcall 방식과 같습니다만, 함수에 전달하는 파라미터일부(2개까지)를  스택 메모리가 아닌 레지스터를 이용하여 전달한다는 것이 특징입니다. 어떤 함수의 파라미터가 4개라면, 앞의 두 개의 파라미터는 각각 ECX, EDX 파라미터를 이용하여 전달합니다.

fastcall의 장점은 이름 그대로 좀 더 빠른 함수 호출이 가능합니다.(CPU 입장에서는 멀리 있는 메모리 보다  CPU와 같이 붙어있는 레지스터에 접근하는 것이 훨씬 더 빠릅니다.) 그런데 호출 자체만 보면 빠르지만, EXC, EDX 레지스터를 관리하는 추가적인 오버헤드가 필요한 경우가 있습니다. 가령 함수 호출 전에 ECX, EDX에 중요한 값이 저장되어 있다면 백업 해놓아야 할 것입니다. 또한 함수 내용이 복잡하다면 ECX, EDX 레지스터를 다른용도로 사용할 필요가 있을 때 역시 이들이 가지고 있는 파라미터 값을 어딘가에 따로 저장할 필요가 생깁니다.

반응형

'reversing' 카테고리의 다른 글

PE File Format  (0) 2022.04.25
Hook ? (훅 이란 ?)  (0) 2022.02.24
스택 프레임  (0) 2021.11.08
스택  (0) 2021.11.04
CPU 레지스터  (0) 2021.11.04

댓글