메모리 레이아웃 기초
01 메모리 구조의 이해
- 소스코드가 어떻게 메모리에 배치되는지 살펴보자.
#include <stdio.h>
int retVal = 0;
int outVal;
int main() {
char string[] = "hello";
char *ptr;
static int output = 1;
ptr = (char *)malloc(sizeof(string)); // ptr 포인터 변수에 동적 힙 메모리 주소 할당
print("%s\n", string);
return retVal;
}
물리 주소 | 메모리 세그먼트 | 저장 데이터 | 실제 데이터 |
0x000000 | Text(=Code) | 실행명령 |
#include <stdio.h> int main() { printf("%s\n", string); return retVal; } |
Data | 전역, const, static 변수, 초기화된 변수 |
int retVal = 0; static int output = 1; |
|
BSS | 초기화되지 않은 변수 | int outVal; | |
Heap | 동적 메모리 | ptr = (char *)malloc(sizeof(stirng)); | |
힙과 스택의 여분 공간 | 변수가 늘어날 경우 힙과 스택의 시작점 사이에 있는 이 공간에 할당 | ||
0xffffffff | Stack | 지역변수 |
char string[] = "hello"; char *ptr; |
- 실 소스코드는 위와 같이 메모리에 올라가고, CPU가 이 내용을 읽어 CPU 안에 있는 register로 불러와서 처리한 후 실행된 결과가 우리에게 보여진다.
- Stack은 메모리의 높은 주소에서 낮은 주소 방향으로 데이터가 쌓인다! 중요!
: Heap과 Stack의 여분 공간에 해당하는 메모리 영역을 효율적으로 사용하기 위함
02 메모리 레이아웃을 이해하기 위한 구조 분석
- 우리가 작성한 코드는 C언어의 문법만 준수하면 되지만,
- 실행 파일은 해당 실행 파일이 실행될 플랫폼의 환경에 맞춰 최적화된 형태로 재구성된다. (ex. 어셈블리 언어)
● 인자 전달 순서 관련 개념
#include <stdio.h>
void function(int a, int b, int c) {
char buffer1[5];
char buffer2[10];
}
int main() {
function(1, 2, 3);
return 0;
}
- main()에서 function()에 전달하는 인자의 순서?
→ 일반적인 생각과 달리, c=3 > b=2 > a=1 의 순서로 스택에 변수값이 쌓인다.
즉, Stack에 오른쪽에서 왼쪽 방향으로 인자 값이 쌓인다!
- gdb로 디버깅하여 구조 확인
gcc로 컴파일하여 실행파일을 만들었다.
fuction() 함수를 호출하는 부분을 보면, c=3 > b=2 > a=1 순으로 인자값이 전달되는 것을 볼 수 있다.
'write-up > pwnable' 카테고리의 다른 글
[ftz] level5: what is your name? (0) | 2019.08.12 |
---|---|
[ftz] level4: suck my brain (0) | 2019.07.28 |
[ftz] level3: can you fly? (0) | 2019.07.28 |
[ftz] level2: hacker or cracker (0) | 2019.07.25 |
[ftz] level1: find local shell backdoor (0) | 2019.07.25 |
댓글