ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 10 함수 호출 규약 (Calling Convention)
    리버싱 엔지니어링/리버싱 핵심 원리 2022. 3. 17. 00:13

    함수를 호출할 때 파라미터를 어떤 식으로 전달하는가에 대한 일종의 약속

    • 스택에 저장된 값은 임시로 사용하는 값, 값을 지우거나 하면 불필요하게 CPU 자원을 소모하는 것
      • 다른 값을 입력할 때 자동으로 덮어씀
      • 스택 메모리는 이미 고정되어있기 때문에 메모리를 해제할 수 없음
    • 스택 메모리는 고정되어 있고 ESP로 스택의 현재 위치를 가리킴
    • 함수 호출 후 ESP는 함수 호출 전으로 복원되어야 함
    • 함수 호출 후에 ESP를 어떻게 정리하는지 : 함수 호출 규약
    • 주요 함수 호출 규약
      • cdecl
      • stdcall
      • fastcall
    • caller(호출자) : 함수를 호출한 쪽
    • callee(피호출자) : 호출을 당한 함수

    10.1 cdecl

    • 주로 C언어에서 사용되는 방식, Caller(호출자)에서 스택을 정리
    #include "stdio.h"
    
    int add(int a, int b)
    {
        return (a + b);
    }
    
    int main(int argc, char* argv[])
    {
        return add(1, 2);
    }

     

     

    cdecl.exe

    • 401013~40101C 주소 영역
      • add() 함수 파라미터 1, 2를 역순으로 스택에 입력
      • add() 함수 후 ADD ESP, 8 명령으로 스택을 정리
    • cdecl : Caller인 main() 함수가 자신이 스택에 입력한 함수 파라미터를 직접 정리하는 방식

    10.2 stdcall

    • Win32 API에서 사용되며, Callee(피호출자)에서 스택을 정리함
    #include "stdio.h"
    
    int _stdcall add(int a, int b)
    {
        return (a + b);
    }
    
    int main(int argc, char* argv[])
    {
        return add(1, 2);
    }
    
    • stdcall 방식으로 컴파일 : ‘_stdcall’ 키워드 추가

    stdcall.exe

    • main() 함수에서 함수 호출 후 스택 정리코드(ADD ESP,8) 생략
    • 스택 정리 : add()함수의 마지막(40100A) RETN 8
      • RETN 8 : RETN + POP 8바이트
      • Callee 내부에 스택 정리 코드가 존재하므로 cdecl 방식에 비해 코드 크기가 작아짐
    • stdcall : Callee인 함수 내부에서 스택을 정리하는 방식
    • Win32 API는 API를 직접 호출할 때 호환성을 좋게 하기 위한 것

    10.3 fastcall

    • 기본적으로 stdcall 방식과 같지만, 함수에 전달하는 파라미터 일부를 스택 메모리가 아닌 레지스터를 이용하여 전달
    • 장점 : 빠른 함수 호출 가능
      • CPU 입장에서 멀리 있는 메모리보다 CPU에 같이 붙어있는 레지스터에 접근하는 것이 빠르기때문

    댓글

Designed by Tistory.