[드림핵] 실습 환경 구축/ 컴퓨터 구조/ 리눅스 메모리 구조
시스템해킹 실습환경 구축
vmware workstation에 이미 칼리 리눅스와 우분투가 설치되어 있지만
WSL2(Windows Subsystem For Linux 2) 이라는 새로운 환경을 구축해보자
window+R -> winver 로 윈도우 버전 확인
파워쉘에서 다음의 명령어 입력
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
재부팅 후 다음 명령어 실행
wsl --set-default-version 2
이후 WSL2 업데이트 -> https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi그리고 microsoft store에 들어가 우분투 22.04를 설치
vmware, virtualbox 없이도 리눅스 실습 환경 구축이 가능하다니!
컴퓨터구조
CPU가 사용하는 명령어와 관련된 설계를 명령어 집합구조(Instruction Set Architecture, ISA)라고 하는데 가장 흔히 사용되는 ISA는 x86-64 아키텍처임
폰노이만 구조
연산, 제어 -> CPU :
프로세스의 코드호출, 실행, 결과저장의 역할. 산술논리장치(Arithmetic Logic Unit, ALU), 제어장치(Control Unit), 레지스터(Register) 등으로 구성
레지스터의 경우 기억장치 들보다 속도가 더 빠르기 때문에 병목현상 방지를 위해 사용
저장-> 메모리:
데이터를 임시적으로 저장하는 주기억장치인 램(RAM)
장기간 보관해야 하는 데이터 저장은 보조기억장치인 HDD, SSD 등으로 분류
데이터, 제어 신호 교환 -> 버스(bus):
데이터 버스(Data Bus), 주소 버스(Address Bus), 제어 버스(Control Bus) 등이 있음
64비트 아키텍쳐: CPU가 한번에 처리할 수 있는 양이 64이고 이 단위를 워드 WORD라고 함
레지스터
레지스터는 CPU에서 데이터를 빠르게 이용할 수 있도록 있는 장치인데 x64 아키텍처에는 범용 레지스터(General Register), 세그먼트 레지스터(Segment Register), 명령어 포인터 레지스터(Instruction Pointer Register, IP), 플래그 레지스터(Flag Register)로 분류할 수 있음
범용레지스터는 다음과 같고, 8바이트 단위이다
rax (accumulator register)
|
함수의 반환 값
|
rbx (base register)
|
x64에서는 주된 용도 없음
|
rcx (counter register)
|
반복문의 반복 횟수, 각종 연산의 시행 횟수
|
rdx (data register)
|
x64에서는 주된 용도 없음
|
rsi (source index)
|
데이터를 옮길 때 원본을 가리키는 포인터
|
rdi (destination index)
|
데이터를 옮길 때 목적지를 가리키는 포인터
|
rsp (stack pointer)
|
사용중인 스택의 위치를 가리키는 포인터
|
rbp (stack base pointer)
|
스택의 바닥을 가리키는 포인터
|
32비트에서는 eax, ebx 등이었으나 64 아키텍쳐에서 확장된게 rax, rbx 의 형태다
세그먼트 레지스터
코드, 데이터, 스택 메모리등을 가리키는 용도로 cs, ss, ds, es, fs, gs 6가지로 나뉘고 16비트 단위임.
주로 사용되는 cs, ds, ss 세 가지를 알아보자면
cs: 프로그램의 코드 세그먼트 시작 주소, 일반적으로 프로그래밍에서 직접 참조할 필요는 X
ds: 프로그램의 데이터 세그먼트 시작 주소, 이 주소+명령어 오프셋 = DS에 속한 바이트 위치 참조
ss: 스택의 구현을 하는 역할, 이 주소+스택포인터 SP 오프셋 = 참조 스택의 현재 워드
명령어 포인터 레지스터
CPU가 어느 부분의 코드를 실행할지 가리키는 역할로 rip이며, 크기는 8바이트
플래그 레지스터
깃발을 올리고 내리듯이 자신의 여러 비트들로 CPU의 현재 상태를 표현함(RFLAGS: 64비트 크기의 플래그 레지스터 )
주로 사용되는 플래그는 CF, ZF, SF, OF이다
ZF(Zero Flag) | 연산 결과가 0일 경우 |
SF(Sign Flag) | 연산 결과가 음수 |
CF(Carry Flag) | 값이 표현 가능한 범위를 넘었을 때/ 왼쪽 비트 추가 |
OF(Overflow Flag) | 부호 없/있는 숫자 합 -> 부호 있/없는 숫자 결과 |
틀린문제
Q. rax = 0x0123456789abcdef 일 때, al의 값은?
A: rax는 64비트 레지스터이고 al은 최하위 8비트이므로 가장 낮은 8비트인 ef가 이에 해당함
답: 0xef
Q. rax = 0x0123456789abcdef 일 때, ah의 값은?
A: al 다음 두번째 8비트 부분을 가리키는게 ah 레지스터이므로 ef앞에 있는 cd.
답: 0xcd
추가적으로 chat gpt를 이용해서 더 요약해보았다
64비트 레지스터 | rax |
32비트 레지스터 | eax |
16비트 레지스터 | ax |
8비트 레지스터 | al, ah, spl, bpl, sil, dil |
이와 비슷하게 rbx, ebx, bx 도 마찬가지인 구조이다
리눅스 메모리 구조
리눅스에서는 적재되는 데이터의 용도에 따라 코드 세그먼트, 데이터 세그먼트, BSS 세그먼트, 힙 세그먼트, 그리고 스택 세그먼트 이렇게 5가지의 세그먼트로 구분한다.
보안 관점에서 보면 각 메모리의 용도에 맞는 권한만이 있다는 장점이 있는데 예를 들어 데이터 세그먼트에 있는 데이터에는 cpu가 읽을 권한만 있고 실행 권한은 없다
각각의 세그먼트에 대해 알아보자
코드 세그먼트
실행 가능한 기계 코드가 있고, 코드 실행을 위해 읽기 권한, 실행 권한이 부여된다
악의적 코드 삽입을 막기 위해 쓰기 권한은 제거한다
가령 c언어로 된 소스코드를 기계어로 컴파일되면, 이 코드가 코드 세그먼트에 저장되고 -> 프로그램 실행 시, 운영체제는 해당 프로그램을 메모리에 로드한다 -> cpu는 코드 세그먼트의 첫 번째 명령어로 이동하는 방식이다
gpt가 비유하기를 코드 세그먼트는 연극 대본, cpu 는 배우, 메모리는 무대라고 하니 이런 식으로 기억하면 좋을 것 같다
데이터 세그먼트
컴파일 시점에 값이 정해진 전역 변수/상수들이 있는 세그먼트로 기본적으로 읽기 권한이 부여되지만 변수의 값이 변할 수 있는지 여부에 따라 쓰기 가능/불가능 세그먼트로 다시 분류된다.
BSS 세그먼트
컴파일 시점에 값이 정해지지 않은 전역 변수가 있는 세그먼트, 읽기/쓰기 권한
#include <iostream>
int bss_data;
int main() {
std::cout << bss_data << std::endl; // 0 출력
return 0;
}
스택 세그먼트
함수의 임시 변수가 실행중에 저장되는 프로세스의 스택 영역이고, 스택 프레임이라는 단위를 사용한다.
스택과 같이 LIFO 방식으로 운영되고, 스택 포인터에 의해 관리됨
힙 세그먼트
스택과 마찬가지로 동적으로 할당되지만 스택 세그먼트와 반대 방향으로 자라기 때문에 충돌하지 않도록 되어있음.
읽기, 쓰기 권한 부여됨.
코드 세그먼트
|
실행 가능한 코드가 저장된 영역
|
읽기, 실행
|
main() 등의 함수 코드
|
데이터 세그먼트
|
초기화된 전역 변수 또는 상수가 위치하는 영역
|
읽기와 쓰기 또는 읽기 전용
|
초기화된 전역 변수, 전역 상수
|
BSS 세그먼트
|
초기화되지 않은 데이터가 위치하는 영역
|
읽기, 쓰기
|
초기화되지 않은 전역 변수
|
스택 세그먼트
|
임시 변수가 저장되는 영역
|
읽기, 쓰기
|
지역 변수, 함수의 인자 등
|
힙 세그먼트
|
실행중에 동적으로 사용되는 영역
|
읽기, 쓰기
|
malloc(), calloc() 등으로 할당 받은 메모리
|
틀린문제
변수 값이 명확히 선언되지 않아서 난 bss라고 선택했는데 둘다 답이 RODATA 였다
d_str의 경우, 상수로 간주되므로 읽기 전용 데이터 영역이고
b는 d_str의 메모리 주소를 저장하는 포인터이기 때문에 읽기 전용이라고 함.
배운걸 금방 까먹지 않게 계속 되새김질 하자!