< 스택 프레임 생성 >

복귀할 포인터 위치를 저장하기 위해 rbp를 스택에 추가함



실행이 끝난 후, 현재 스택 주소로 복귀하기 위해 rsp값을 rbp에 넣음.
rsp, rbp 주소 : 0x7fffffffdff0


rsp에서 0x10만큼을 뺌 → 0x10만큼의 지역변수 공간을 확보함


rax에 fs:[0x28] 값을 8byte 크기만큼 복사
stack canary는 fs:[0x28]에서 가져오며, 이를 스택에 저장하고 함수가 끝나기 전에 다시 fs:[0x28]와 비교
Stack canary : buffer overflow를 감시하기 위해 buffer와 return address 사이에 존재
return address로 넘어가기 전 canary값이 원래 값과 같은지 확인
- 값이 같지 않을 경우, 프로그램 강제 종료
buffer overflow는 canary의 값을 덮어씀
→ 컴퓨터는 return address로 넘어가기 전 buffer overflow 그리고 강제종료에 대해 경고
https://www.youtube.com/watch?v=N7kGd76evsM


← RBP 주소

[rbp - 8]의 주소에 8byte 크기로 rax 값을 넣음
[rbp - 8]의 주소(=0xc310b2cbe7a4d100)에는 8byte 크기의 stack canary 값이 들어있음


eax 레지스터를 0으로 초기화


[rip + 0xde6]의 주소를 rdi에 복사
[rip + 0xde6] → 다음 실행할 명령어 주소 + 0xde6

eax 레지지스터를 0으로 초기화

printf 함수 호출
PLT(Procedure Linkage Table) : 외부 프로시저를 연결해 주는 테이블. PLT를 통해 다른 라이브러리에 있는 프로시저를 호출해 사용할 수 있음.
프로시저(procedure) : C언어에서 함수와 비슷한 개념. 하지만 함수와 달리 리턴 값을 남기지 않음.



[rbp - 0x10]의 주소를 rax에 복사. rax, rsp 스택 위치가 같음


rax의 값을 rsi에 복사. rax, rsi, rsp 스택 위치가 같음
scanf의 두 번째 인자 : rsi (입력받은 값이 들어감)


[rip + 0xddb]의 주소를 rdi에 복사 (scanf로 입력 받은 값이 들어감)
scanf의 첫 번째 인자 : %d

eax 레지스터를 0으로 초기화



scanf 함수 호출 → scanf로 입력 받은 값은 rdi에 저장

[rbp - 0x10]의 주소 값을 8byte 크기로 eax에 복사


eax의 값을 edi에 복사

test 함수 호출

[rbp - 0xc] 주소에 4byte 크기로 eax 값 복사 (eax는 test 함수의 return 값을 담고 있음)
<조건 분기문>

[rbp - 0xc] 주소에 있는 4byte 크기의 값 - 1 의
- 결과가 0이면([rbp - 0xc == 1]) ZF가 1
- 결과가 0이 아니라면([rbp - 0xc != 1]) ZF가 0

ZF가 0([rbp - 0xc != 1])이면 main+120으로 점프함

[rbp - 0xc]에 있는 4byte 크기의 값 - 0 의
- 결과가 0이면([rbp] - 0xc == 0) ZF가 1
- 결과가 0이 아니라면([rbp - 0xc] != 0) ZF가 0

ZF가 0([rbp - 0xc] != 0])이면 main+136으로 점프함

eax에 0을 넣음 (=return 0)

<main+21>에서 [rbp - 8]에 8byte 크기로 복사한 canary 값을 rdx에 복사

rdx값과 원래의 값(qword ptr fs:[0x28])이 다르다면 buffer overflow를 당했다 판단하고 강제 종료

rdx값과 원래의 값(qword ptr fs:[0x28])이 같다면 <main + 161>로 점프
<스택 프레임 해체>
<main+161> leave
- mov esp, ebp
- pop ebp
→ ebp의 값을 esp에 복사함. 현재 ebp가 가리키는 값을 esp값으로 설정해 현재 ebp는 이전 함수의 ebp로 복구
<main+162> ret
- pop eip
- jmp eip
→ 현재 esp가 가리키는 값(return address)를 eip로 설정, eip로 점프
위 코드를 C언어 코드로 보면 다음과 같다

'Layer7' 카테고리의 다른 글
| ELF file (0) | 2021.06.02 |
|---|---|
| 코드 분석 하기 (0) | 2021.05.30 |
| Assembly X86 Stack 관리 (1) | 2021.05.24 |
| Assembly X64 (0) | 2021.05.22 |
| 실행파일 생성 과정 (0) | 2021.05.15 |