Win2k_driver_ch_5

Download Report

Transcript Win2k_driver_ch_5

ISLab Flash Team
Ch 5. Device Driver 개발의
일반적인 사항
Contents
1.
2.
3.
4.
5.
6.
7.
8.
Driver Design
Rules and Technic of Coding
Allocating Memory for Driver
UniCode String
Interrupt Synchronization
Synchronization of Multiple CPU
Linked Lists
Summary
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
2
Made By Hackereyes
ISLab Flash Team
1. Driver Design
표면적인 Design
• Data Flow Diagram
– Driver의 개별적인 기능 구성요소로 분리
• State Machine Chart
– Driver내의 제어의 흐름을 기술
– Driver내부의 자원의 동기화 처리 기술
• Data의 전송률 or Input/Output 응답 속도를 분석
– 수행 속도 성능 향상에 영향
• 외부 Event에 반응하는 Driver의 작동을 리스트화
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
4
Made By Hackereyes
점진적인 개발 방법론(1)
1. Kernel Mode Object Type 결정
2. Driver에 필요한 Context결정 및 Store Place 결정
3. DriverEntry, Unload Routine을 작성
4. IRP_MJ_CREATE, IRP_MJ_CLOSE dispatch Routine
•
CreateFile , CloseHandle
5. Hardware 검색및 자원을 할당하는 Code 추가
Unload시 할당된 자원을 해제하는 Code 추가
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
5
Made By Hackereyes
점진적인 개발 방법론(2)
6. IRP_MJ_XXX 함수를 처리하는 dispatch Routine 추가
•
Win32 App에서 ReadFile, WriteFile 등으로 Test 가능
7. 실질적인 Routine 작성
•
•
•
•
Start I/O Routine
Interrupt Service Routine
DPC Routine
DeviceIOControl Code 추가
•
Win32 App가 직접 Hardware Register를 제어할수 있음
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
6
Made By Hackereyes
ISLab Flash Team
Rules and Technic of Coding
General Advice
• Assemble Language 를 피함
– 가독성 저하, 호환성및 유지보수의 어려움
• Standard C Library 와 Link 하지 않음
– Driver에 위험한 Context 정보를 가지고 있을수 있음
• Kernel Mode Code를 제공
– Rtlxxx (Runtime Library)
• Microsoft Visual Source Safe Tool 제공
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
8
Made By Hackereyes
Naming Conventions
• Microsoft 에서 DDK를 통해 제시
– NTDDK.h 기술
• 모든 Data Type, Structure , Constant value, macro 등등
– C 의 data type 도 대응되는 Type으로 변환
• Ex) void*

PVOID
(64bits platform에서 쉽게 이식)
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
9
Made By Hackereyes
Header File
• NTDDK.h or WDM.h 을 포함하기도 함
• Device 특성을 다루는 자체 Header File을 가질수 있음
– #ifdef 사용
• 이식성 고려
• 가독성 증가
• 유지 보수 비용 감소
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
10
Made By Hackereyes
Return Value
• Windows 2000  32 bits state value 사용
• NTSTATUS structure
– Win2k 자체 함수 사용시, 성공/실패 를 반환
– Call Back Function은 I/O Manager에게 NTSTATUS 반환
– I/O 요청 처리후 반드시 IRP의 상태를 NTSTATUS 값으로 지정
• NTSTATUS 는 NTSTATUS.h 에 정의 되어 있음
– STATUS_XXX 형태의 많은 양의 Symbol을 기술
• Ex) STATUS_SUCCESS , STATUS_NAME_EXISTS 등등
• NTSTATUS는 NT_SUCCESS() function을 사용해 검증
– 반드시 Error유무를 확인해야 함
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
11
Made By Hackereyes
Windows 2000 Driver에서 지원하는 함수
목 록
함수 이름
목 록
함수 이름
실행부
ExXxx()
Object Manager
ObXxx()
HAL
HalXxx()
Process
Manager
PsXxx()
I/O Manager
IoXxx()
Runtime Library
RtlXxx()
Kernel
KeXxx()
Security Moniter
SeXxx()
Memory
Manager
MmXxx()
기타
ZwXxx()
• I/O Manager는 하위 Level Func을 쉽게 호출가능하게
위와같은 상위 Level Func을 제공함.
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
12
Made By Hackereyes
Initial Routine 의 폐기
• Driver가 Memory에 Load된 후 더 이상 필요없는 Routine
을 Memory에서 폐기시킴
• DriverEntry와 DriverEntry 안에서만 불리는 SubRoutine
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
13
Made By Hackereyes
Control Driver Paging
• Driver Routine도 Page Out 될수 있음
– Page Out 되지 않는다면, Memory에 대한 부담이 큼
• PASSIVE_LEVEL IRQL 에서 수행되는 모든 함수
– Reinitialize , Unload , Shutdown , Dispatch , Thread 등등
• MmPageEntireDriver()
– 전체 Module을 일시적으로 Paging 시킴
– 반드시 DriverEntry 마지막에 호출
– 해당 Device를 Open 중인 Handle이 없으면 IRP_MJ_CLOSE
Routine을 호출해야함
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
14
Made By Hackereyes
ISLab Flash Team
Allocating Memory for Driver
Memory Used in Driver
• malloc, free, new, delete 등은 사용 못함
• Global Value는 사용 자제(읽기는 가능)
• Kernel Stack
– Driver Routine이 수행되는 동안 Nonpaged 공간 제공
• Paged Pool
– Heap 영역, Paging 될수 있음. 접근시 Page Fault 가능
• Nonpaged Pool
– 높은 IRQL Routine은 Memory에 상주하는 Heap영역 필요
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
16
Made By Hackereyes
Kernel Stack
• X86  12K , Other platform  16K
• 어떠한 경우에도 Overflow가 발생하면 안됨
– 중첩되는 Routine Call을 피함
– Recusive Call을 피함 (깊이에 제한을 둠)
– 큰 Data Structure를 피함. (Pool 이용)
• Cache Memory에 존재
– DMA에 사용되어서는 안됨
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
17
Made By Hackereyes
Pool
• Kernel Routine으로 할당
– ExAllocatePool, ExFreePool 등등
• Pool 사용시 주의 사항
– Memory관리 철저 (낭비되어선 안됨)
– NonPaged Memory 할당및 해제는 DISPATCH Level 이하에서
수행
– 더 이상 필요하지 않은 Memory는 반드시 해제 (Unload시)
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
18
Made By Hackereyes
System에서 지원하는 하위 Memory 할당(1)
• Pool 영역에 작은 Block들을 빈번히 할당하면 Memory가
조각나게 됨
• 사용자는 큰 Pool영역을 할당받은뒤 그안에서 사용
– Ex) SCSI Request Block
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
19
Made By Hackereyes
System에서 지원하는 하위 Memory 할당(2)
• ZONE Buffer
– Driver에 의해 할당된 큰 덩어리의 Pool Memory
– 구시대적 방법, 잘쓰이지 않음
• LookAside List
–
–
–
–
Fixed Size Memory Block에 대한 Linked List
ZONE Buffer와는 다르게 동적으로 Size를 조절 가능
Memory 낭비가 적음
LookAside List Depth를 설정함 (초기값)
• Depth가 작으면 비용이 증가
• Depth가 크면 Memory 낭비
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
20
Made By Hackereyes
ISLab Flash Team
UniCode String
Unicode
User Buffer
UniCode
or not
Device Driver
UniCode
Only
Kernel
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
22
Made By Hackereyes
Unicode String Data Type(1)
UNICODE_STRING Structure
Field
Contents
USHORT Length
현재 문자열의 Bytes 길이
USHORT MaximumLength
문자열의 최대 길이
PWSTR Buffer
Driver에서 할당된 실제 문자열의 Data를
갖고 있는 Pointer
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
23
Made By Hackereyes
Unicode String Data Type(2)
• Unicode는 L을 문자열의 접두어로 가짐
– Ex) L”some text”  Unicode
“some text”  8 bits ANSI
• wchar_t
data type 사용
– DDK.h에는 wchar_t  WCHAR
wchar_t*  PWSTR
• Unicode String의 종결은 UNICODE_NULL사용
– C Library String에서의 NULL과 같음
– 16 bits 0(zero) 값임
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
24
Made By Hackereyes
Working with Unicode(1)
• Unicode를 다루는 일반 함수
Function
Contents
RtlInitUnicodeString
NULL 종료 Unicode 문자열 초기화
RtlAnsiStringToUnicodeSize
ANSI 문자열 Unicode 크기계산
RtlAnsiStringToUnicodeString
ANSI  Unicode
RtlIntegerToUnicodeString
정수  Unicode
RtlAppendUnicodeStringToString
두 Unicode 결합
RtlCopyUnicodeString
Unicode 문자열 복사
RtlUpcaseUnicodeString
Unicode 문자열을 대문자화
RtlCompareUnicodeString
두 Unicode 비교
RtlEqualUnicodeString
두 Unicode 문자열 길이 비교
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
25
Made By Hackereyes
Working with Unicode(2)
• PASSIVE_LEVEL IRQL에서만 사용하는 것이 좋음
• Unicode 문자수 ≠ Bytes
• 문자들의 순서 대조 or 대소문자 구분에 대해 가정 불가
• 256개 공간에 전체문자열을 담을수 있다고 가정 불가
• UNICODE_STRING 사용을 위한 C++ class wrapper제공
– CUString class
– Paged Pool 에 할당
– 큰 문자열 처리에는 부적합
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
26
Made By Hackereyes
IRQ Level
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
27
Made By Hackereyes
Interrupt Synchronization
• Interrupt Synchronization 필요성
Interrupt
하위 IRQL
{
foo.x = 1;
..
..
foo.y = 2;
}
상위 IRQL
{
foo.x = 10;
foo.y = 20;
}
Struct foo 결과
{
Int x = 10
Int y = 2
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
28
Made By Hackereyes
Interrupt Blocking(1)
• 하위 IRQL Routine이 상위 IRQL Routine에 의해
Interrupt되는 문제점 해결방법
• Interrupt Blocking 이란?
– IRQL 을 잠시 올려 실행후 이전 IRQL로 복귀
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
29
Made By Hackereyes
Interrupt Blocking(2)
• CPU의 IRQL을 조정할수 있는 Functions
Function
Contents
KeRaiseIrql
CPU의 IRQL 값을 명시된 IRQL로 변경
현 Level이하의 Interrupt를 Blocking
KeLowerIrql
상승된 IRQL을 원래값으로 복귀
KeGetCurrentIrql
함수가 호출된 시점의 IRQL 값 Return
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
30
Made By Hackereyes
Interrupt Blocking(3)
• Interrupt Blocking의 Rules
– 공유 Data를 접근하는 모든 Routine들은
명시된 IRQL로 상승되지 않는 이상 공유 Data에 접근 불가
– 만약 낮은 IRQL Routine이 Agreed IRQL로 상승했다면
가능한 빨리 작업을 끝내야함
– IRQL을 상승시킬때, 원래의 IRQL값보다 낮추면 안됨
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
31
Made By Hackereyes
DPC를 사용한 Synchronization
• DPC는 공유된 Data접근을 처리하는 또하나의 방법
• DPC는 항상 Serial 하게 수행하기 때문
• DPC는 비교적 낮은 IRQL에서 수행
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
32
Made By Hackereyes
ISLab Flash Team
Synchronization of Multiple CPU
Spin Lock(1)
• Spin Lock 사용 이유
– Multiprocessor 환경에서 CPU의 IRQL을 조정해도 해당 CPU에
만 적용됨
• Spin Lock이란?
– 특정 Data Structure과 관계된 Mutex Object
– Kernel Mode가 보호되는 Data에 접근시 그 Data와 관계된
Spin Lock의 소유를 요청
– 오직 한 CPU만이 Spin Lock Object 소유 가능
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
34
Made By Hackereyes
Spin Lock(2)
CPU 1
CPU 2
Raise IRQL
Repeat
Request Spin Lock
Until ACQUIRED
foo.x = 1;
foo.y = 2;
Release Spin Lock
Restore IRQL
Raise IRQL
Repeat
Request Spin Lock
Until ACQUIRED
foo.x = 10;
foo.y = 20;
Release Spin Lock
Restore IRQL
Foo의
Spin Lock
Struct foo 결과
Int x = 10
Int y = 20
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
35
Made By Hackereyes
Spin Lock(3)
• Interrupt Spin Lock
– 다수의 Driver Routine에 의해 공유되는 Data Structure접근 동
기화
• Excutive Spin Lock
– OS에서 사용되는 다양한 Data Structure 보호
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
36
Made By Hackereyes
Spin Lock(4)
• Rules
– 가능한 빨리 해제해야함
• 다른 CPU의 활동을 Block하는 것임
– Spin Lock을 소유하는 동안 H/W or S/W Exception을 발생시키
면 안됨
– Spin Lock을 획득하는 동안에는 Paging 가능성이 있는 Code나
Data는 접근하면 안됨
– CPU가 이미 획득하고 있는 Spin Lock을 획득을 시도하지 말것
• DeadLock을 유발할수 있음
– 다수의 Spin Lock을 동시에 획득하려하는 Code는 피할것
• DeadLock을 유발할수 있음
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
37
Made By Hackereyes
ISLab Flash Team
Linked Lists
Single Linked List
• SINGLE_LIST_ENTRY 선언으로 List 생성
• Next Field 만 존재
• List 앞쪽에 Entry 추가, 삭제 가능
– PushEntryList, PopEntryList
• Spin Lock으로 보호 받을수 있음
– SINGLE_LIST_ENTRY 선언후 Spin Lock 초기화 하여 사용
– ExInterlockedPushEntryList , ExInterlockedPopEntryList
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
39
Made By Hackereyes
Double Linked List
• LIST_ENTRY 선언으로 List 생성
• Flink , Blink 두 Field가 있음
• List에 Entry 추가, 삭제 가능
– InsertHeadList , InsertTailList
– RemoveHeadList , RemoveTailList
– IsListEmpty
• Spin Lock으로 보호 받을수 있음 (interlock)
– LIST_ENTRY 선언후 Spin Lock 초기화 하여 사용
– ExInterlockedInsertTailEntryList,
ExInterlockedInsertHeadEntryList 등등 사용
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
40
Made By Hackereyes
List로 부터의 Block 제거(1)
• List에서 Block을 빼내오면 SINGLE_LIST_ENTRY or
LIST_ENTRY Structure를 반환
• Return 된 Structure는 현 List를 포함하는 더 큰 Structure
일수 있음
• Return Structure에서 Parent Pointer를 찾아야 함
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
41
Made By Hackereyes
List로 부터의 Block 제거(2)
0
500
100
200
……
700
300
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
42
Made By Hackereyes
List로 부터의 Block 제거(3)
0
500
100
200
……
700
300
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
43
Made By Hackereyes
List로 부터의 Block 제거(4)
• Windows 2000 에서 CONTAINING_RECORD Macro를 제공
Parameter
Contents
Address
Remove Func을 사용하여 Return 된 Address
Type
포함하는 Structure Data Type
Field
Address Parameter가 가리키는 Structure의 Field
Return Value
자신을 포함하는 Structure의 Pointer
- CONTAINING_RECORD Macro ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
44
Made By Hackereyes
ISLab Flash Team
Summary
Summary
• Device Driver Coding에는 소정의 순서가 있음
• Windows 2000에서 제공하는 각종 Routine 이용
• Code 작성시 Memory 할당에 유의
• Device Driver는 Unicode 만을 통해 Kernel과 통신
• IRQL에 따른 Interrupt 처리
• Multiple CPU에서의 Spin Lock 사용
• Linked List 사용법
ISLab Flash Team
Ch 5. Device Driver 개발의 일반적인 사항
46
Made By Hackereyes