본문 바로가기

3. Pwnable (포너블)/2) 개념 정리

[2022.03.26] "생활코딩-LINUX" 강의 듣기 + 달고나 문서 p.5-7

[ 생활코딩 - Linux 강의]

 

https://inf.run/RMWK

 

오늘은 [리눅스 기초] 패키지 매니저(윈도우) 3 40 ~ IO Redirection – input 까지 수강했다.

 

 

 

 

 

 

1.     패키지 매니저(윈도우)

A.     Sudo apt-cache search htop :htop가 들어간 모든 것을 찾기

B.     Sudo apt-get upgrade htop :htop을 업그레이드 하기

C.     Sudo apt_get remove htop: htop을 삭제하기

 

2.     패키지 매니저 homebrew (MAC)

A.     Brew.sh에 접속하여 주소를 복사> terminal 입력 > 카피한 명령어 붙여넣기 후 설치

B.     return에서 enter입력

C.     brew help : 도움말

D.     brew search htop: htop이라는 프로그램의 존재 여부 확인

E.      brew install htop-osx : htop-osx라는 프로그램 다운로드

F.      sudo htop : 컴퓨터의 상태들

G.     brew list : 설치된 프로그램 리스트 확인

H.     brew uninstall htop-osx : 삭제하기

I.       brew upgrade vim: vim이라는 파일 업그레이드

J.      brew upgrade :  모든 프로그램 업그레이드

K.     brew update: 목록을 최신 버전으로 맞춤

 

3.     IO Redirection – output

A.     ls -l : 현재 파일의 디렉토리 출력

B.     ls -l > result.txt : 출력될 결과가 result.txt에 감

C.     cat result.txt : result.txt를 불러옴

D.     rm rename2.txt : 해당 파일 삭제 > 다시 한 번 더 쓰면 에러 발생(이미 삭제되었기 때문

E.      rm rename2.txt > result.txt : 에러 발생(이미 삭제되었기 때문)

F.      rm rename2.txt 2> error.log : 에러에 대한 로그 파일 리다이렉션

G.     rm. Rename2.txt 1> result.txt 2> error.log : error.log 파일의 보관

 

4.     IO Redirection – input

A.     cat hello.txt : hello.txt 파일 화면에 출력

B.     cat : 이거만 실행하면 대기상태가 됨. 이 때 무언가 입력하면 그대로 다시 출력해줌

C.     cat < hello.txt : hello.txt의 파일을 입력으로 간주함

D.     head linux.txt : 앞쪽의 일부만 출력함

E.      head -n1 linux.txt: 1줄만 출력

F.      head -n1 < linux.txt > one.txt : one.txt에 저장

 

 

 

code segment

시스템이 알아들을 수 있는 컴파일러가 만들어낸 기계어 코드 명령어들이 저장된다.

명령들은 명령을 수행하면서 많은 분기 과정과 점프, 시스템 호출 등을 수행한다. 예를 들어, main함수에서 factorial함수를 호출하고 그 리턴 값을 다시 main함수에서 출력하는 것이 있다. 이처럼 분기, 점프를 위해 메모리 상의 특정 위치에 있는 명령을 지정해 주어야 한다. 하지만 segment는 자신이 현재 메모리 상에 어느 위치에 저장될지 컴파일 과정에서는 알 수 없기 때문에 정확한 주소를 지정할 수 없다. 메모리 상에 어느 위치에 저장될지는 실행 과정에서 알 수 있기 때문에 실행 과정 전 단계인 컴파일 과정에서는 알 수 없는 것이다. 따라서 segment에서는 logical address를 사용한다.

Logical address는 실제 메모리 상의 주소 (physical address)와 매핑 되어 있다. segment segment selector에 의해서 자신의 시작 위치(offset)를 찾을 수 있고 자신의 시작 위치로부터의 위치(logical address)에 있는 명령을 수행할 지를 결정하게 되는 것이다. 따라서 실제 메모리 주소 physical address offset + logical address 라고 할 수 있다. 예를 들어, 하나의 프로그램이 실행되기 위해 0번부터 99번까지의 주소가 필요하다고 생각해보자. 그럼 이 프로그램은 총 100개의 주소가 필요한 것이다. 메모리는 0번부터 3999번까지의 주소가 있다고 생각해보자. 그럼 메모리는 총 4000개의 주소를 가지고 있는 것이다. 4000개의 주소가 있는 메모리의 특정 주소부터  100개의 주소가 필요한 프로그램이 저장되어 실행되는 것이다. 컴파일 과정 중에는 이 프로그램이 어느 주소에 할당될 지는 모르지만, 실행 중에는 알 수 있다. 만약, 실행 중 이 프로그램이 3000번째 주소에 할당되었다면 이 프로그램은 3000번부터 3099번까지의 주소를 이용하는 것이다. 여기서 offset(시작위치)3000이고, logical address는 그 시작위치로부터 얼마나 떨어져 있는 명령어를 실행중인지 나타낸다. 만약 0~99의 명령어 중 50번째 명령어를 실행 중이라면 logical address50이 되어 offest + logical address3050이 되는 것이다. 이렇게 segment가 메모리상의 어느 위치에 있더라도 segment selectorsegment ofset을 알아내어 해당 instruction의 정화한 위치를 찾아낼 수 있게 된다.

 

data segment

프로그램이 실행시에 사용되는 전역변수가 저장된다.

data segment는 다시 네 개의 data segment로 나뉘는데 각각 현재 모듈의 data structure 상위 레벨로부터 받아들이는 데이터 모돌 동적 생성 데이터, 다른 프로그램과 공유하는 공유 데이터 부분이다.

 

stack segment

현재 수행되고 있는 handler, task, . program이 저장하는 데이터 영역으로

우리가 사용하는 버퍼가 바로 이 stack segment에 자리잡게 된다. 또한 프로그램이 사용하는 multiple 스텍을 생성할 수 있고 각 스텍들간의 switch가 가능하다. 지역 변수들이 자리잡는 공간이다.

스텍은 처음 생성될 때 그 필요한 크기만큼 만들어지고 프로세스의 명령에 의해 데이터를 저장해 나가는 과정을 거치게 되는데 이것은 stack pointer(SP)라고 하는 레지스터가 스텍의 맨 꼭대기를 가리키고 있다. 스덱에 데이터를 저장하고 읽어 들이는 과정은 PUSH POPinstruction에 의해서 수행된다.

스텍의 데이터 구조를 이해하기 위해서 쉽게 떠올릴 수 있는 것은 바로 접시 닦기를 생각하면 된다. 식당의 주방에서 접시를 닦는다고 생각해 보자 새로 씻은 접시는 선반 위에 쌓아둔 접시 더미의 맨 위에 올려 놓는다(PUSH). 그리고 다음 씻은 접시는 그 위에 다시 올려 놓는다(PUSH). 음식을 담기 위해 접시를 사용할 텐데 이 때 맨 아래 접시를 끄집어 내려고 하지 않을 것이다 당연히 맨 위의 접시를 사용한다(POP). 스텍도 이와 마찬가지로 가장 최근에 PUSH된 데이터를 POP 명령을 통해서 가져오게 된다.

이와 비슷하게 파인애플 통조림을 생각해볼 수 있다. 파인애플 통조림을 제조할 때, 바닥부터 차례대로 파인애플을 쌓아 올린다. 꽉 채워져있는 통조림에서 맨 아래에 있는 파인애플을 꺼내려고 하려면 그 위에 쌓여진 파인애플을 모두 꺼내야 빼낼 수 있다. 그럼 파인애플 통조림을 만들 때, 가장 처음 들어간 파인애플은 바닥에 있는 파인애플이고, 가장 나중에 들어간 파인애플은 맨 위에 있는 파인애플인 것이다. 그럼 이 파인애플 통조림을 먹는 사람은 가장 나중에 들어간 파인애플을 가장 먼저 먹게 되는 것이다. 이게 바로 후입 선출이다.