일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 드론
- px4
- 커널
- 시그널
- C++
- 리눅스 커널
- 리눅스커널
- C언어
- Leviathan
- css
- radare2
- 컴퓨터구조
- kernel
- 시스템 프로그래밍
- Pwnable.kr
- write up
- 어셈블리어
- Bandit
- 프로그래밍
- 취약점
- 시스템해킹
- 시스템
- 알고리즘
- pwn.college
- 리버싱
- wargame
- 리눅스
- 워게임
- pwncollege
- 시스템프로그래밍
- Today
- Total
Computer Security
#26 Input Test Driver 1 본문
문제 Input Test Driver를 풀어보며 실습해 볼 것이다.
터치 스크린 input device driver에 misc device를 추가하여 원하는 값을 event driver에 보고할 수 있다는 컨셉의 문제이다.
우리는 아래의 파일들로 문제를 풀어 볼 것이다.
start.sh : qemu의 실행 옵션이 들어있는 쉘 스크립트
pow_check.py : 문제 서버의 PoW check 코드
vmlinux : 디버깅을 위한 데이터들이 살아있는 커널 이미지 파일이다.
example.c : 드라이버 사용 예제 코드
문제 배경 지식 - Input Device Driver
hardware --> device driver --> event driver --> evdev interface --> application
Input Device Driver
- 마우스, 터치 스크린, 키보드 등의 다양한 입력 장치들에 대해 각각 특징에 따라 통합하여 관리하는 디바이스 드라이버다.
- device driver와 event driver 간의 통신을 기반으로 작동한다.
- input_event 구조체 형식으로 application에 이벤트 값을 전달한다.
아래는 커널 소스의 Documentation/input/input-programming이다. 살펴보자.
이 소스코드는 하나의 버튼을 입력을 받아 입력 이벤트로 전달하는 코드이다.
이 코드의 순서도는 아래와 같다.
1.
모듈에는 하나의 module_init 및 module_exit를 매크롤로 명시한 함수를 호출하게 된다.
이는 드라이버 초기화 진입점 및 해제 진입점이 된다.
2.
해당 함수의 호출 시점은 드라이버의 형태에 따라 다르게 나타난다. 만약 드라이버가 Built-in(커널에 포함) 이라면, 커널 부팅 중 do_initcalls에 의해, 적재가능한 모듈 형태라면 모듈이 적재될 대 해당 함수가 불려진다.
3.
init 시에는 GPIO 등의 필요하 자원에 따른 속성을 초기화한다.
위의 소스코드에서는 interrupt를 이용했기 때문에 BUTTON_IRQ라는 irq넘버를 지정해 그에 대한 interrupt handler 함수를 등록했다.
4.
필요한 하드웨워 자원을 초기화 헀으니, 입력 디바이스 드라이버를 초기화 해줘야 한다.
5.
입력 드라이버를 등록하기 위해선 input 디바이스 정보를 가진 자료구조가 필요한데, 그것이 input_dev라는 구조체이다.
6.
input_dev 메모리를 할당한다.
input_allocate_device()를 호출하면 커널 영역의 메모리를 할당해 input_dev를 만들고 이를 반환한다.
7.
입력 비트필드 설정
input_dev는 input 디바이스에 대한 다양한 정보를 포함하고 있다.
그중 가장 중요한 요소는 어떠한 이벤트를 핸들링 하냐 인데, evbit는 디바이스가 지원하는 이벤트의 타입을 포함하고 있 으며, 대표적으로 EV_KEY, EV_REL, EV_ABS, EV_MSC등이 있다.
8.
input_dev등록
input_dev를 다 정의 했으면, 입력 디바이스 드라이버를 커널에 등록 해야한다.
input_register_device(struct input_dev)
9.
등록이 완료되면 이제 입력 디바이스 드라이버는 interrupt를 기다리며 버튼이 눌릴때까지 대기한다.
interrupt가 발생했을 경우에 BUTTON_IRQ에 등록된 인터럽트 핸들러가 호출되어 입력 이벤트를 전달한다.
10.
모듈 init과 유사하게 모듈 해제시에는 입력디바이스를 해제하고, 그에 필요했던 시스템 자원을 해제한다.
Input Test Driver 사용 예제 코드인 example.c 파일을 살펴보자.
1~4 값을 event driver에 보고한다.
event driver는 evdev interface에 input_event 구조체로 이벤트 값을 전달한다.
'리눅스 커널 해킹' 카테고리의 다른 글
#26 Input Test Driver 3 (0) | 2022.09.05 |
---|---|
#26 Input Test Driver 2 (0) | 2022.09.04 |
#25 Double Fetch (0) | 2022.09.02 |
#24 Arbitrary Write 2 (0) | 2022.09.01 |
#23 Arbitrary Write 1 (0) | 2022.08.31 |