leave = move esp, ebp
pop ebp
: ebp 의 값을 esp에 저장한다.
esp가 가리키고 있는 주소값에 들어있는 값을 ebp에 저장하고 , esp = esp+4를 한다.
ret = pop eip
jmp eip
: esp가 가리키고 있는 주소값에 들어있는 값을 eip에 저장하고, esp = esp +4 한다.
eip가 가리키는 주소로 간다.
어셈블리 코드를 보면서 돌아가는 과정을 스택 메모리를 그려보며 따라가면 이해하기 쉽다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
_start:
push ebp
mov ebp, esp
sub esp, 8
mov [ebp-4], 12
lea eax, [ebp-4]
mov [ebp-8], eax
mov [eax], 6
mov eax, [ebp-8]
push eax
call func
add esp, 4
mov eax, 0
leave
ret
func:
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov [eax], 32
leave
ret
|
cs |
아래 스택은 push ebp를 실행했을 때 스택의 모습니다.
epb | esp |
ret |
아래 스택은 mov ebp, esp를 실행했을 떄 스택의 모습니다.
ebp | esp =ebp |
ret |
sub esp, 8 : esp = esp-8
mov [ ebp-4 ] , 12 : ebp-4의 주소값에 12를 저장한다.
esp | |
12 | |
ebp | |
ret |
lea eax, [ ebp-4 ] : ebp -4 의 주소값을 eax에 저장한다.
// eax = & ebp-4
mov [ ebp-8 ], eax : [ ebp -8 ] =eax
// [ ebp - 8 ] = & ebp-4
& [ebp-4] | esp |
12 | |
ebp | |
ret |
mov [ eax ], 6 : eax의 주소값에 6을 저장한다.
mov eax, [ ebp-8 ] : eax = & [ ebp - 8 ]
push eax
& [ ebp -8 ] | esp |
& [ ebp- 4 ] | |
12 | |
ebp | |
ret |
call func : 그 다음 명령어를 저장.
push ebp : 여기서의 ebp는 func함수에서의 ebp이다.
// ebp는 main에서의 ebp를 저장함
// 시스템 복원할때 그 지점을 복붙해 놓는거랑 비슷한거
mov ebp, esp
mov eax, [ ebp + 8 ] : ebp + 8 의 주소값의 값을 eax에 저장한다.
// [ ebp + 8 ] = & [ ebp -8 ]
// c코드에서 포인터와 같은 해석이 가능함
// [] = * pointer
ebp | esp =ebp |
다음 명령어를 저장. | |
& [ ebp -8 ] | |
& [ ebp- 4 ] | |
12 | |
ebp | |
ret |
mov [ eax ], 32 : 32를 eax의 주소값의 값에 저장한다.
// eax = 32
ebp | esp |
다음 명령어를 저장. | |
32 | |
& [ ebp- 4 ] | |
12 | |
ebp | |
ret |
leave : mov esp, ebp
pop ebp
// ebp 를 esp에 저장하고, esp + 4 를 한후, 빼준다.
다음 명령어를 저장. | esp |
32 | |
& [ ebp- 4 ] | |
12 | |
ebp | |
ret |
ret : pop eip
jmp eip
// eip , 즉 cpu에 저장되어있는 명령어를 저장하고 , esp = esp+4 한다.
// 그 명령어로 이동한다.
32 | esp |
& [ ebp- 4 ] | |
12 | |
ebp | |
ret |
이제 func 안의 스택을 모두 진행했다, 다시 main으로 넘어가서 이어간다.
add esp , 4 : 4를 esp에 더해준다
// esp = esp+4
mov eax , 0 : 0을 eax에 저장한다.
// eax = 0
leave : mov esp, ebp // ebp 값을 esp에 넣고
pop ebp // esp = esp+4
ret : pop eip
jmp eip
// eip의 명령어로 가서 esp=esp+4
// eip의 주소값으로 이동
esp = ebp | |
32 | |
& [ ebp- 4 ] | |
12 | |
ebp | |
ret |
댓글