팀활동으로 리눅스 명령어들을 같이 정리하고 이해했고, BOF문서를 확인해서 개념을 잡았습니다. 또한 백준문제를 C언어로 풀이함으로서 기본을 다지는 시간을 가졌습니다.
생활코딩 - 리눅스 섹션 2 I/O Redirection , 섹션 3 쉘과 쉘스크립트, 섹션 4 디렉토리 구조돠 파일 찾는 법
ls -l > result.txt = ls -l의 내용을 result.txt에 저장한다. > 는 redirection을 의미한다. standard output은 1로 표준출력을 나타내는데 1> 로 쓰지만 1은 생략해도된다. 2>는 에러에 대한 redirection이다.
cat result.txt = 하면 result안에 있는 내용을 확인할 수 있다.
ls -l: standard output 모니터에 출력하지만
ls -l > result.txt 하면 파일에 출력값을 저장해서 볼 수 있다.
rm rename2.txt 1> result.txt 2> error.log
= 출력하는 결과가 있다면 result 파일에 저장이 될 것이고 오류를 출력하면 그 오류는 에러파일에 저장된다.
cat을 입력하면 사용자가 입력하는 정보를 standard input으로 받아드림
ctrl + d를 하면 빠져나온다.
쉘은 사용자가 입력하는 명령어를 해석하는 용도로 사용된다.
사용자가 입력한 명령어를 shell이 해석해서 커널이 이해할 수 있는 방식으로 전달해 준다.
커널은 어떤 처리를 수행할 수 있도록 하드웨어한테 전달한다.
사용자 -> 쉘 -> 커널 -> 하드웨어 ->커널->쉘->사용자 이 순서로 요청을 주고 받는 다고 생각하면 쉽다.
echo "hello" 입력하면 hello가 출력된다. echo라는 명령어는 단순하지만 echo $0 명령어는 다르다.
echo $0 = zsh, 현재 사용하고 있는 쉘을 표시한다. zsh가 출력된다면 zsh쉘을 사용해서 커널에 연결하고 있는 것이다.
bash는 기본 쉘 프로그램 , zsh 따로 설치해야하는 쉘이지만 는 자동완성으로 편의성이 높다.
zsh에서는 디렉토리로 옮겨갈 때 절대경로를 축약하여 쓸 수 있다. 예) cd /h/d/i를 입력하고 tap키를 누르면 절대경로가자동완성된다.
Shell Script
ls /bin는 bin 디렉토리는 루트 디렉토리 밑에 있는 디렉토리로 기본적인 유닉스 명령어가 저장되어 있다. 기본 프로그램이 위치하는 자리이기도 하며, bash, zsh, mkdir, nano 명령어들은 파일의 형태로 존재하는 프로그램이다.
#!/binbash 밑에 작성되는 코드들이 bin밑에 bash를 통해 해석되어야 한다는 약속이다.
./backup = backup이라는 파일을 실행하는 명령어이고
chmod +x backup = backup파일에 x를 추가함으로써 실행가능한 모드를 추가한 것이다.
/ -bin : User Binaries, nano, bash, pwd, mkdir ... 등등 사용자들이 사용하는 명령어
/sbin: System Binaries, reboot, shutdown 등 시스템 관리자가 사용하는 명령어 sudo
/etc : Configuration Files, 설정을 바꾸는 명령어, 컴퓨터가 동작하는 방법에 설정
/var : Variable Files, 내용 및 용량이 바뀔 수 있다.
/tmp : Temporay files 임시파일이 저장된 곳 프로그램을 종료하면 없어진다.
/home: Home DIrectiories, 사용자들의 디렉토리, 사용자의 파일들이 저장되는 디렉토리, cd ~/ 하면 바로 home으로 이동
/opt : Optional add on Applications, software를 설치할 때, 적당한 디렉토리에 위하하는데
파일의 사용 용도 - 명령을 보관하는 용도(실행파일), 데이터를 보관하는 용도
파일의 위치 찾는 방법: locate 파일명 예) locate *.log
locate는 DB에서 데이터를 찾는다. 디렉토리에서 찾지 않는다. 속도는 빠르지만 주기적인 업데이트가 필요하다.
locate가 사용하는 DB는 mlocate
find는 디렉토리에서 찾는다. 속도가 느리지만 현재 상태의 파일을 가져올 수 있다.
find /는 루트 .는 현재부터 하위파일까지
find / -name *.log : 루트디렉토리부터 이름에 log가 포함되어 있는 파일을 찾는다.
whereis 실행파일을 찾는데 그 파일이 어디에 있는지 확인할 수 있는 명령어
whereis rm -> rm이라는 명령어가 들어있는 디렉토리를 반환 출력값으로 /bin/ls 을 얻게된다.
$PATH는 변수이다. 콜론을 통해서 정보들이 구분되어 있고 리눅스에서 변수를 기본적으로 가지고 있다.
변수에 담겨있는 디렉토리들을 검색해서 ls라는 실행파일이 있는지 확인하는거고 그 명령어가 발견되면 실행한다.
해커 지망자들이 알아야 할 Buffer Overflow Attack의 기초 By 달고나 문서 정리 (0p~12p)
2. 8086 Memory Architecture
운영체제는 하나의 프로세스를 실행시키면 이 프로세스를 segment라는 단위로 묶어서 가용 메모리 영역에 저장시킨다.
메모리에는 여러 개의 프로세스가 저장되어 병렬적으로 작업을 수행한다. 가용한 메모리 영역에 여러개의 segment들이 저장될 수 있다.
시스템에서는 16383 개의 segment가 생성될 수 있다. 하나의 segment는 최대 2^32 바이트의 크기를 가진다.
code segment에는 시스템이 알아들을 수 있는 명령어들이 들어있다. 기계어 코드로써 컴파일러가 만들어낸 코드이다.
segment는 자신이 현재 메모리 상에 어느 위치에 저장될지 컴파일 과정에서는 알 수 없기 때문에 정확한 주소를 지정할 수 없다. 그래서 segment는 local address를 이용한다. 실제 메모리 상의 주소와 매핑되어 있다. 결국 segment는 segment elector에 의해서 자신의 시작 위치를 찾을 수 있다.
data segment에서는 프로그램이 실행시에 사용되는 데이터가 들어간다. 데이터는 전역변수들을 뜻하는데 프로그램 내에서 전역변수를 선언할 경우 그 변수가 data degment에 들어간다. data segment에는 4개의 data segment로 나뉘는데 data structure, 데이터 모듈, 동적 생성 데이터, 공유 데이터 부분으로 나뉜다.
stack segments는 현재 수행되고 있는 handler, task, program이 저장하는 데이터 영역으로 우리가 사용하는 버퍼가 stack segment에 들어간다. 프로그램이 사용하는 멀티플 스택을 생성하고 스택들이 스위치를 할 수 있다. 이 공간은 지역변수들이 자리잡는다. 처음 생성된 스텍들은 필요한 크기만큼 저장공간을 만들고 stack pointer (sp) 라는 레지스터가 스텍의 맨 위를 가리키고 있다. 스텍이 데이터를 저장하고 읽는 과정은 PUSH와 POP 명령어로 이루어진다.
3. 8086 CPU 레지스터 구조
레지스터는 범용 레지스터, 세그먼트 레지스터, 플래그 레지스터, 인스트럭션 포인터로 구성된다.
범용 레지스터: 연산에 사용되는 피연산자, 주소를 계산하는데 사용되는 피연산자, 메모리 포인터가 저장되는 레지스터, 프로그래머가 임의로 조작할 수 있게 허용되어 있는 레지스터이다.
세그먼트 레지스터: code segment, data segment, stack segment 를 가르키는 주소가 들어있는 레지스터, 사용자는 원하는 segment안의 특정데이터, 명령어를 정확하게 찾아낼 수 있다.
플래그 레지스터: 프로그램의 현재 상태나 조건 등을 검사하는데 사용하는 플래그가 들어있는 레지스터, 상태 플래그, 컨트롤 플래그, 시스템 플래그 들의 집합이다. 1, 3, 5, 15, 22~31번 비트는 예약되어 있어 조작할 수 없다.
인스트럭션 포인터: 다음 수행해야 하는 명령어들이 있는 메모리 상의 주소가 들어있는 레지스터, 다음 실행할 명령어가 있는 현재 code segment의 offset값과 JMP, Jcc, CALL, RET, IRET instruction이 있는 주소값을 가진다.
백준 단계별로 풀어보기 2884번
#include<stdio.h>
int main() {
int h, m;
scanf("%d %d", &h, &m);
m -= 45;
if (h > 0 && m < 0) {
m += 60;
h -= 1;
}
else if (h == 0 && m < 0) {
m += 60;
h = 23;
}
printf("%d %d", h, m);
return 0;
}
백준 단계별로 풀어보기 10951번
#include<stdio.h>
int main() {
int a, b;
while (scanf("%d %d", &a, &b) != EOF)
{
printf("%d\n", a + b);
}
return 0;
}
백준 단계별로 풀어보기 4344번
#include<stdio.h>
int main() {
int C, N, over;
double avg = 0;
int sc[1000];
scanf("%d", &C); //입력받기
for (int i = 0; i < C; i++) { //케이스 만큼 학생들 점수 입력받기
scanf("%d", &N);
avg = 0.0;
for (int j = 0; j < N; j++) { // 학생수 N만큼 성적을 배열sc로 저장
scanf("%d", &sc[j]);
avg += sc[j]; //평균값을 다 더하기
}
avg = avg / N; // sum값에서 학생수N으로 나눠서 평균Get
over = 0; //아직 배열을 돌지 않아서 평균을 넘는 사람이 없음
for (int j = 0; j < N; j++) { //반올림 N수만큼 반복
if (sc[j] > avg) //배열 sc[1]이 평균보다 높으면
over++; // 배열을 돌아서 평균을 넘는 사람이 발생
}
printf("%.3f%%\n", 100.0 * over / N); //퍼센테이지 계산
}
return 0;
}
'3. Pwnable (포너블)' 카테고리의 다른 글
[2022.11.26] 포시즌 - 포너블팀 활동보고 (0) | 2022.11.30 |
---|---|
[2022.11.19] 포시즌 - 포너블팀 활동보고 (1) | 2022.11.25 |
[2022.11.12] 포시즌 - 포너블팀 활동보고 (0) | 2022.11.12 |
[2022.10.8] 포시즌 - 포너블팀 활동보고 (0) | 2022.10.10 |
[2022.09.17] 포시즌-포너블팀 활동 보고 (0) | 2022.09.21 |