본문 바로가기

모의해킹/시스템 해킹

리눅스 커널 해킹 (배경 지식)

728x90

• 리눅스 커널 개론

- 컴퓨터의 가장 기본적인 자원들을 관리하고 통제하기 위한, 운영체제의 핵심이 되는 소프트웨어

- 커널 내부는 태스크 관리자, 메모리 관리자, 파일 시스템, 네트워크 관리자, 디바이스 드라이버 관리자 등으로 구분됨

- 가상 메모리 구조상 스택의 윗 영역에 존재

- 가상 메모리의 3~4GB 구간에 존재하는 커널 영역은 모든 태스크들의 공통 영역으로 사용됨

- 가상 메모리 주소와 물리 메모리 주소를 변환하기 위해 커널 내부에는 페이징 기법이 구현되어 있음

 

1. 유저 모드 / 커널 모드란?

- 하나의 프로세스가 실수로 다른 프로세스에 입출력 작업을 하는 등의 보안적 이슈르 방지하기 위해, 유저가 컴퓨터의 자원에 함부로 접근할 수 없도록 모드를 나누어 둔 것

- 유저 모드 : 접근할 수 있는 영역이 제한적이며, 유저 애플리케이션이 실행되는 모드

- 커널 모드 : 컴퓨터의 모든 자원에 접근할 수 있으며 커널이 실행되는 모드

 

2. 시스템 호출이란?

커널 동작(시스템 호출 동작 과정)

- 유저 공간에 유저 애플리케이션의 요청에 따라 커널에 접근하기 위한 인터페이스

- input/ output 작업을 하기 위해선 커널에게 요청해야 함

- 시스템 호출을 했을 경우 현재 모드를 커널 모드로 바꾼 뒤, 특정 작업 후 system call function을 호출

 

3. 태스크란?

- 리눅스 커널에서는 프로세스와 스레드를 별도로 구분하지 않고, 모두 태스크로 동등하게 관리함(단지 쓰레드 그룹에 속해 있는 가 등의 여부에 따라 차이)

- 모든 태스크들은 task_struct 구조체로 관리

- 프로세스와 쓰레드를 생성하는 모든 함수는 do_fork() 함수를 거치며, 이 함수는 taks_struct를 생성하는 역할을 함

- 하나의 태스크가 생성될 때, 커널 스택과 taks_struct가 할당됨 -> 각 태스크마다 커널 스택이 할당 됨

task_struct
pid_t pid  프로세스마다 부여하는 식별 값
pid_t tgid 쓰레드 그룹 아이디
chat comm[] 프로세스의 이름
sturct task_strcut*real_parent 자신을 생성한 부모 태스크를 가리킴
struct task_struct*parent 현재 부모 태스크를 가림킴
struct mm_struct*mm mm_struct는 유저 공간의 텍스터, 데이터, 스택 힙 등의 영역의 위치와 메타데이터를 가지고 있음

 

* mm_struct

-> start_code, end_cdoe : 각각 Text 영역의 시작과 끝의 주소

-> start_data, end_data : 각각 Data 영역의 시작과 끝의 주소

-> start_brk, brk : 각각 Heap 영역의 시작과 끝의 주소, brk는 증가가 가능

-> stack_start : Stack 영역의 시작 주소

 

4. 슬랩 할당자란?

- 커널에서 사용하는 동적 메모리 할당자이며 메모리 풀 구조를 가지고 있음, 미리 고정된 크기의 메모리 블록들을 할당해 놓는다는 것

- 슬랩 캐시 : 커널에서 자주 요청하는 크기에 대한 동적 메모리를 확보하고 관리하는 주체

- 슬랩 객체 : 슬랩 캐시가 할당해 놓은 메모리 블록, malloc()의 chunk와 비슷한 개념 -> 커널에서는 kmalloc() 함수 사용

- 슬랩 페이지 : 슬랩 객체로 구성된 페이지

 

* 주요 자료 구조

- 슬랩 할당자는 kmalloc_caches []라는 전역 배열을 이용해 각 크기별 슬랩 캐시들을 관리함

- 각 슬랩 캐시는 keme_cache라는 구조체로 표현됨

- 슬랩 캐시는 슬랩 객체의 할당 속도를 높이기 위해 CPU 개수만큼 kmem_cache_cpu라는 구조체를 추가적으로 이용함

kmalloc() 함수 실행 과정: kmalloc() -> kmem_cache_alloc_trace() -> slab_alloc() -> slab_alloc_node()

* slab_alloc_node()

- kmem_cache_cpu 구조체로 관리되는 per-cpu 슬럽 캐시를 불러옴

- 각종 작업 후 kmem_cache_cpu의 freelist에 해제된 슬랩 객체가 있을 경우 해당 슬랩 객체를 최종적으로 반환

- kmem_cache_cpu의 freelist에 NULL이 있을 경우 슬랩 페이지를 새로 할당받은 뒤 슬랩 객체를 반환

 

5. 디바이스 드라이버란?

종류 설명
Character Device 버퍼 캐시를 사용하지 않으며 Device를 파일처럼 직접 접근
(마우스, 키보드 등의 드라이브)
Block Device Hard Disk와 같은 file system을 기반으로 block단위로 접근 
Network Device 네트워크 스택과 네트워크 하드웨어 사이에 위치하여 데이터의 송수신 담당

- 유저 애플리케이션이 정형화된 인터페이스를 통해 장치에 접근할 수 있도록 해주는 소프트웨어

- 커널이 컴파일될 때부터 포함된 디바이스 드라이버도 있고 별도로 컴파일되어 커널 부팅 후에 로드되는 디바이스 드라이버도 있음

- 디바이스 드라이버는 모듈의 일종, 모듈 프로그래밍을 통해 프로그래밍할 수 있음

 

* file_operations 

- 디바이스 드라이버와 유저 애플리케이션 간의 커뮤니케이션을 위한 인터페이스

- 각종 함수 포인터 멤버들이 선언되어 있음

 

* 주로 사용되는 함수

- copy_from_user(a, b, c) : 유저 공간에서 커널 공간으로 데이터를 안전하게 복사하는 함수. 유저 공간 주소 b에서 c바이트만큼 커널 공간 주소 a로 복사

- copy_to_user(a, b, c) : 커널 공간에서 유저 공간으로 데이터를 안전하게 복사하는 함수. 커널 공간 주소 b에서 c바이트만큼 유저 공간 주소 a로 복사

- mutex / spinlock : 커널에서의 race condition을 방지하기 위한 커널 동기화 함수

 

6. 모듈 프로그래밍

- 모듈이란 동적으로 커널에 등록하거나 제거할 수 있는 프로그램을 뜻함. 이로 인해 커널 이미지를 재컴파일 하지 않고도 기능을 추가할 수 있음

- 모듈 프로그래밍을 통해 디바이스 드라이버를 작성할 수 있음

- 모듈은 kbuild라는 규칙이 있는 Makefile을 통해 컴파일할 수 있음

- 컴파일된 모듈은 insmod, rmmod 등의 명령어로 등록 및 제거가 가능

 

'모의해킹 > 시스템 해킹' 카테고리의 다른 글

shell_basic  (0) 2023.12.09
Welcome  (0) 2023.12.09
qemu & gdb 세팅  (0) 2023.05.30
리눅스 커널 & 파일 시스템 빌드  (0) 2023.05.29
시스템 해킹 기본 지식  (0) 2023.05.11