[ Export Driver ]
1. 위의 첨부된 예제를 참고하여 Export Driver를 작성한다.
2. 생성된 sys파일을 %windir%\system32\drivers 에 복사
3. 생성된 lib파일을 Export Driver를 호출하는 다른 드라이버의 소스코드파일이 위치한곳에 복사
[ Export Driver를 호출하는 드라이버 ]
1. SOURCES파일상에 아래의 내용을 추가
TARGETLIB = 생성된 lib파일명.lib2. 함수의 원형을 선언
ex) EXTERN_C DECLSPEC_IMPORT void ExportFunction();
[ 참고 ]
- Import Driver와 같은 경로 에 Export Driver가 없다면, 호출은 실패한다.
- Export Driver를 동적으로 로드 (유저모드의 LoadLibarary()를 사용한 명시적 링크)할 수 없다. 커널에서 사용할 수 있는 ZwLoadDriver() 는 레거시타입의 드라이버를 로드할 때 쓰이며, Export Driver를 로드할수는 없다.
또한,
런타임때 함수의 주소를 알아올 수(유저모드의 GetProcAddress()) 없다. 커널에서 사용할 수 있는 MmGetSystemRoutineAddress() 는 Ntoskrnl.exe 및 hal만을 대상으로 동작한다.
위의 문제를 해결하기 위해서는, 레거시타입의 드라이버를 제작하여 ZwLoadDriver()로 로드한 후, 함수의 주소를 얻기 위해 IOCTL로 이 주소를 질의하는 방법을 사용할 수 있다. 이에 대한 추가적인 내용은 http://www.microsoft.com/whdc/driver/tips/KmDLL.mspx 를 참조하기 바란다.
- Export Driver의 Export 선언은 __declspec(dllexport) 선언을 통해서도 가능하지만, DllInitialize 및 DllUnload 함수에 대해서는 반드시 PRIVATE 속성으로 Export 해야한다. (PRIVATE 속성은, Linker에게 DLL로드를 위한 Export함수임을 알려주지만 임포트 라이브러리(*.lib) 파일 내에는 Export 함수로 포함시키지 않음을 의미한다) 하지만, __declspec(dllexport) 방법을 이용해서는 PRIVATE속성을 부여할 수 없다. 따라서, Export Driver를 만들경우엔 오로지 .DEF파일을 이용해야 한다. (아직까지는...)
- Windows 98 Gold 버전에서는 DllInitialize를 호출하지 않으며, 98 SE 및 ME에서는 DllUnload를 호출하지 않는다. (즉, 한번 로드되면 Import Driver가 언로드되더라도 Export Driver는 언로드되지 않고 계속 메모리상에 유지된다.)
- DllInitialize 함수에서 인자로 넘어오는 UNICODE_STRING 은 아무런 의미를 가지지 않는다. 단지 데코레이션일 뿐이다. (실제로 넘어오는 값은 \Registry\Machine\System\CurrentControlSet\Services\'Export Driver Name' 이지만 실제로 이 키는 생성되지 않는다)
출처 : http://www.microsoft.com/whdc/driver/tips/KmDLL.mspx
http://www.wd-3.com/archive/KernelDlls.htm