System Hacking

정보보안5 (10,11) - call, 스택메모리의 함수표현

김현17 2017. 10. 26. 21:12

1. call & jmp 명령의 차이

- 공통점 : 해당 주소의 명령을 실행한다. ( 해당 주소를 eip 레지스터에 저장 )

! cpu 는 eip 레지스터를 통해 실행할 명령어를 찾는다.

 

- 차이점 : jmp 명령어는 해당 주소로 바로 이동하지만, call 명령어는 스택에 데이터를 저장하고 이동한다. (call명령어는 복귀할 주소를 저장한다!)

 

 

아래 예제는 다음 c언어 코드를 어셈블리로 표현한 것이다.

int sum (int a, int b){

int sum = 0;

a + b = sum;

return sum;

}

int main(void) {

int a = 10;

int b = 20;

int sum = 0;

 

sum = sum(a, b);

printf("%d \n", sum);

return 0;

}

[ 함수의 인자를 전달하는 방법 ]

1. 레지스터를 이용한 전달 : fastcall (64bit)

2. 공유 메모리를 이용한 전달

3. 스택 메모리를 이용한 전달 : 이것을 이용.

여기서 중요하게 보아야 할 것은 함수 호출에 있어서 스택메모리의 상황이다. 다음의 그림과 같이 보자.

 

최초 main ebp 부터 시작해서 12byte공간을 할당하고 push 2번을통해서 a와 b의 인자를 넘겨주고 call을 한 것을 볼 수 있다. 그리고 sum함수에서 다시 prologue와 leave,ret을 통해 메모리를 사용하고 도로 반환했고, sum func에서의 ebp에서 ebp+8 ebp+12에 접근하여 함수 인자값을 가져다 쓰는 것을 확인할 수 있다. 그리고 ret로 eip를 pop하면서 메인함수의 call함수 이 후의 스택으로 돌아온다. 그리고 return 하는 값을 eax에 저장하는 것을 확인할 수 있다.

 

 

2. 스택 메모리를 이용한 인자 전달

 

윈도우는 callee가 사용한 스택메모리 정리

리눅스는 caller가 사용한 스택메모리 정리

 

! C Calling Convention

- C 호출 규약에 따른 내용

 

1. callee-saved register

- ebp, esi, edi, ebx       백업을 하고 써야함(피호출자 책임)

 

2. caller-saved register

- eax, ecx, edx            (호출자 책임)

 

 

 

[실습]

- 지난번에 작성했던 loop.asm 코드를 지역변수를 사용해서 동작하도록 수정

  (모든 변수는 스택 메모리를 사용)

 

저번에 했던 return 문을 스택메모리를 이용하여 표현하면 다음과같다.