본문 바로가기

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

[2023.04.01] '생활코딩 - Linux' 강의 수강 및 달고나 문서 ~p.12

'생활 코딩 - Linux' 강의를 섹션 4부터 섹션 6까지 수강하고 달고나 문서를 목차 3번까지 학습하였다.


<섹션 4. 디렉토리 구조와 파일 찾는 법>
 
- 유닉스 계열에서는 데이터와 실행 프로그램 성격에 따라 위치가 정해짐
 
디렉토리 정리
/root: 최상위 디렉토리
/bin: 유저가 사용하는 명령들
/sbin: 시스템 root 관리자가 사용하는 프로그램
/etc: 프로그램 동작 방법 변경
/var: 변경가능한 파일들
/tmp: 임시로 자장하는 파일들
/home: 사용자들의 디렉토리
/lib: sbin과 bin의 공통 라이브러리
/opt: 소프트웨어 설치 시에 적절한 디렉토리에 자동으로 위치시킴. 
 
파일 찾는 법
1. locate --> locate + 파일이름 
- 데이터베이스를 뒤져서 파일을 찾음
- 파일을 찾는 속도가 빠름
2. find  --> 명령어 구조에 따라 찾는 방법이 달라짐
-  디렉토리를 뒤져서 직접 파일을 찾음 
- locate에 비해서 속도가 느림
3. whereis
- 필요한 실행파일의 위치를 찾음
4. $PATH
- 명령어의 위치를 지정해 사용자가 명령을 실행할 때 명령의 전체경로를 적지 않을 수 있게 함.
 
 
 
<섹션 5. 프로세스와 실행>
 
컴퓨터 구조
중앙처리장치(프로세서): CPU
저장장치(스토리지): ssd, hdd, sd카드
- 가격이 쌈. 저장용량이 큼. 속도가 느림 
메모리: RAM 등
- 가격이 비쌈. 저장용량 적음. 속도가 빠름.
--> 평소에는 스토리지에 저장하다가 필요할 때 메모리에 적재 후 CPU가 읽어서 처리 
 
프로세스 모니터링
ps: 프로세스 리스트를 보는 명령
ps aux: 백그라운드에 있는 프로세스까지 모든 프로세스 리스트를 보여줌
top: 실시간으로 변경되는 프로세스 상태를 보여주는 명령어
htop: top프로그램의 업그레이드 버전. 더 그래피컬하게 보여줌
 
백그라운드 실행
- 리눅스에서도 백그라운드와 포그라운드를 왔다갔다하는 것이 가능함
ctrl+z: 실행 중이던 파일을 백그라운드로 보냄
job: 백그라운드 작업들의 목록 보여줌
fg % 숫자: job 후에 'fg % n' 입력하면 n 번째 프로그램을 다시 실행
 
항상 실행 / 정기적 실행
daemon: 프로그램 형태 중 하나. 항상 실행되고 있음  
cron: 정기적으로 명령을 실행시켜주는 도구
crontab -e: 정기적으로 실행할 작업 정의
 
쉘의 스타트업 설정
쉘을 열었을 때 특정한 명령어가 바로 실행되도록 함.alias l = 'ls-al' --> l이라고 입력하면 ls-al에 해당하는 명령어 실행
 
 
 
<섹션 6. 사용>
 
다중사용자
유닉스계열: 다중사용자 시스템 (각자의 아이디로 컴퓨터에 로그인)
--> 사람마다 권한을 체크해야 하기 때문에 시스템의 복잡도가 높음.
id: 자신이 누군인지 알려줌
who: 현재 시스템에 누가 접속해있는지 알려
 
관리자와 일반 사용자
super user: 관리자
user: 사용자
sudo: 일시적으로 관리자의 권한 가지는 명령어
su -root : super user가 되는 명령어
exit: 일반 사용자로 돌아감
 
사용자의 추가
sudo useradd -m 사용자이름: 새로운 사용자의 디렉토리 생성
새로운 사용자에게 sudo 권한 부여
1. super user 사용 가능한 사용자로 접속
2. sudo usermod -a -G sudo 사용자이름
3. su -사용자이름 입력
 
 
 


 
 
 
<8086 Memory architecture>
8086 시스템의 기본적인 메모리 구조는 <그림1>과 같음

 
 
 
- 시스템이 초기화되기 시작할 때 시스템은 커널을 메모리에 적재,
  가용 메모리 영역 확인함
- 운영에 필요한 기본적인 명령어 집합을 커널에서 찾음
   --> 커널 영역이 반드시 그림과 같이 있어야 함
 
 
 


segment: 하나의 프로세스를 묶은 것. 가용 메모리에 저장되며 실행 시점에 실제 메모리의 어느 위치에 저장될 지 결정된다. 
<그림 2>는 프로세스를 실행시켰을 때 segment가 가용 메모리 영역에 저장된 구조이다. 

 
 
 
- 메모리에는 여러 개의 프로세스가 저장되어 병렬적으로 작업 수행
segment는 code segment와 data segment, stack segment로 나뉨.
- code segment: 명령어들이 존재
- data segment: 프로그램 실행 시 사용되는 데이터 존재
- stack segment: 현재 수행되고 있는 handler, task, program이 저장하는 데이터 영역
 
 
 
 


logical address: 실제 메모리 상의 주소와 매핑되어 있는 가상으로 부여받은 주소
physical address: 실제 메모리 주소
offset: segment의 시작 위치
segment selector: 세그먼트 레지스터
 
<그림 3>은 segment의 위치를 설명하는 그림이다. 

-segment는 컴파일 과정에서는 자신의 주소를 알 수 없기 때문에 logical address를 사용함
- 실행 후에 segment의 시작 주소인 offset을 알게되고 offset의 주소와 
logical address의 주소를 더해 physical address의 주소 구함
 
그림 3에서 
logical address: 0x00000100
offset: 0x80010000
physical address = logicla address + offset 
                            = 0x00000100 + 0x80010000
                            = 0x80010100
 
--> segment 상의 logical address와 offset 주소로 실제 주소를 찾음
 
 
 
<8086 CPU 레지스터 구조>
레지스터: CPU 내부에 존재하는 저장 공간
- 범용 레지스터: 연산자와 피연산자, 메모리 포인터가 저장되는 레지스터
- 세그먼트 레지스터: code segment, data segment, stack segment를 가리키는 주소가 들어있는 레지스터
- 플래그 레지스터: 프로그램의 현재 상태나 조건 등을 검사하는데 사용되는 플래그들이 있는 레지스터
- 인스트럭션 포인터: 다음에 수행해야 할 명령이 있는 메모리상 주소가 저장되어 있는 레지스터