어셈블리어 call, leave, ret 명령어와 스택프레임
call 주소
함수를 호출할 때 쓰이는 명령어다.(어셈블리어에서는 프로시저라는 개념이 있지만 함수와 비슷하기도 하고 더 친숙해서 함수라고 쓰겠다.)
call을 통해 함수를 호출하고 ret명령어로 반환될 때 다시 돌아오기 위해서 다음 명령어의 주소를 stack에 넣고 해당 함수의 주소로 이동한다. 어셈블리어로 쉽게 풀어쓰면 아래와 같다. (위 사진을 참고하자)
push 0x0000000000402377
jmp helloworld.4029A0
스택프레임
leave 명령어를 공부하기 전에 조금 알아두면 좋을 것 같아서 넣어본다.
글 아래 주소를 참조할테니 한 번 읽어보면 좋을 듯 하다.
PUSH EBP MOV EBP, ESP SUB ESP, 상수 |
; 함수 시작 ; 현재의 ESP(스택포인터)를 EBP에 저장 ; 사용할 공간(상수)만큼 ESP(스택포인터)를 늘림. |
... |
; 함수 본체 ; 여기서 ESP가 변경되더라도 EBP가 변경되지 않으므로 ; 안전하게 로컬 변수와 파라미터를 엑세스할 수 있음 |
MOV ESP, EBP POP EBP RETN |
; ESP를 정리 ; 리턴되기 전에 저장해 놓았던 EBP 값으로 복원 (leave명령어에 해당되는 내용) ; 함수 종료 |
출처: https://furysecurity.tistory.com/13 [IT & 일상:티스토리]
잘 정리해두셔서 가져와봤다. 위 과정처럼 새로운 함수마다 스택을 분리하고 새로운 스택공간을 만드는 것을 스택프레임이라고 생각한다. 출처된 사이트 들어가면 스택프레임에 대한 정의까지 볼 수 있다. 정의내리는 건 별로 안좋아해서..
leave ← operand없이 혼자 사용된다.
사용되었던 스택을 정리할 때 사용되는 명령어이다.(나는 리버싱 하면서 본 적 없는 것 같다...)
함수내에서 명령들이 모두 실행되고 값을 반환하기 전에 스택의 최상단에 있는 rsp의 주소를 rbp의 주소로 되돌리고 호출 되기 전 함수의 스택으로 돌아간다. 어셈블리어로 쉽게 풀어쓰면 아래와 같다.
mov rsp, rbp
pop rbp
아래가 스택이라고 생각하고 자세히 설명하겠다. leave명령어를 실행하기 전의 상황이다.
rsp = 0x00420100, rbp = 0x00420180이라고 가정하자.
솔직히 leave 자주 쓰이는 지 모르겠다...
ret ←operand없이 혼자 사용된다.
함수의 모든 명령이 끝나고 원래의 함수로 돌아갈 때 쓰이는 명령어다.
pop rip 라고 생각하면 쉽다. 스택에서 함수가 호출될 때 push했던 주소(call함수 호출 명령어의 다음 명령어 주소)를 RIP에 넣는다.
https://furysecurity.tistory.com/13
스택 프레임(Stack Frame) 에 대해 알아보자
공부를 시작하기에 앞서 본 글은 '리버싱핵심원리', 이승원 저자, 인사이트 를 참고했음을 밝힙니다. 또한 공부하는 입장에서 정리를 목적으로 작성하였기때문에 틀린 정보가 있을수도 있다는
furysecurity.tistory.com
https://learn.dreamhack.io/38#3
로그인 | Dreamhack
dreamhack.io