본문 바로가기

Reverse Engineering

10. 콜린 컨베션 __stdcall 함수의 어셈블리어 코드

10. 콜린 컨베션 __stdcall 함수의 어셈블리어 코드

 

 

  

 본 포스팅의 내용은 해킹 맛보기 책의 내용중 3장 리버스 엔지니어링 P133~P281 까지

 실습 내용을 따라하기 해보았습니다. 책의 내용중 일부 발췌 (수정) 하였습니다. 문제가 될 때는 비공개 하도록 하겠습니다.

 

 

[발췌]

 구분

__cdecl 

__stdcall 

__fastcall 

 인자 전달 방법

 스택

 스택 

 레지스터, 스택 

 스택 해제 방법

 호출한 함수  

 호출된 함수  

 호출된 함수  

 

 

 

 

#include <stdio.h>



int __stdcall sum(int a, int b, int c)

{

return a+b+c;

}

int main()

{

int s;

s =sum(1, 2, 3);

printf("%d ", s);

return 0;


}

 

 


[발췌-수정]

인자 입력은 __cdecl 호출 규약과 같이 스택으로 입력하는 것을 확인할 수 있다. 

스택 해제는 호출된 함수에서 하며,__cdecl  호출 규약에서 보였던 스택 해제 명령어가 호출한 함수에서는 나타나지 않는다.

호출된 sum() 함수의 어셈블리어를 분석해보면 아래와 같이 RETN 명령어에서 스택 해제를 한다.  


 __stdcall 호출 규약을 사용하는 sum 함수 

  012013FA  88E5               MOV ESP,EBP          

  012013FC  50                   POP EBP                  

  012013FD C2 0C00           RETN 0C     


RETN 명령어는 호출된 함수에서 호출한 함수로 되돌아가는 명령어다. __cdecl 호출 규약에서 RETN 명령어만 쓰여 스택 해제는 하지 않았지만

__stdcll은 스택 해제를 호출된 함수에서 한다. 따라서 RETN 0C 명령어를 이용해 스택 해제를 한다. RETN 0C 명령어는 호출한 함수로 돌아가면서 0C만큼

더해주는 명령어다. 호출한 함수 주소 01201439 MOV DWORD PTR SS:[EBP-8], EAX로 돌아가면 이미 인자 입력에 사용된 스택은 해제되어 

스택을 효율적으로 다시 사용할 수 있게 된다.