Windows/DeviceDriver 2021. 4. 25. 18:06

05. 5편 구조체분석1 (DRIVER_OBJECT, UNICODE_STRING)

  • WDK 도움말에 구조체 이름을 검색하여 참고하면 좋다.

디바이스 드라이버 구조체

간단한 샘플 드라이버 코드

#include <ntddk.h>

NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
{
  return STATUS_UNSUCCESSFUL;
}
  • DriverEntry 함수의 인자는 다음과 같다.

    • pDrvObj : 샘플 드라이버를 설명하는 DRIVER_OBJECT 구조체의 주소

    • pRegPath : 샘플 드라이버가 등록된 시스템 레지스트리의 키 이름 정보가 보관된 메모리를 설명하는 UNICODE_STRING 구조체의 주소


DRIVER_OBJECT 구조체

  • DriverInit : 디바이스 드라이버를 올리는 IO Manager가 DriverEntry의 주소를 저장한다.

  • DriverUnload : 드라이버가 내려갈 때 실행되는 콜백 함수

    • 기본 값은 NULL이며, 프로그래머가 저장해야 한다.

실습

  • 정상적으로 드라이버를 올렸다가 내리는 작업을 WinDbg로 확인할 것이다.

    • 코드를 빌드한 뒤 .sys 드라이버 파일은 가상 머신으로 옮기고, .pdb 심볼 파일은 WinDbg에서 설정한 경로로 옮긴다.

      #include <ntddk.h>
      
      void SampleDriverUnload(PDRIVER_OBJECT pDrvObj)
      {
        pDrvObj = pDrvObj;
      }
      
      NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
      {
        pRegPath = pRegPath;
      
        pDrvObj->DriverUnload = SampleDriverUnload;
      
        return STATUS_SUCCESS;
      }
  • 가상 머신과 WinDbg 프로그램을 실행한다.

    • WinDbg에서 가상 머신을 멈춘 뒤 브레이크 포인트를 설정한다.

      bp sample!DriverEntry
      bp sample!SampleDriverUnload
    • 가상 머신에서 관리자 권한으로 CMD를 열어서 드라이버를 올린다.

      sc start sample
    • 올리는 순간 가상 머신이 멈추고 WinDbg에 소스 코드가 나오고 디버깅을 시작한다.

      • 소스 코드가 뜨지 않으면 WinDbg가 소스 코드의 경로를 찾지 못한 것이다.

        • 이럴 경우 직접 소스 코드를 불러와야 볼 수 있다는 것 같다.
    • Go를 눌러 디버깅을 마친 뒤에 드라이버를 메모리에서 내린다.

      sc stop sample
    • 내린 순간 다시 가상 머신이 멈추고 디버깅을 시작한다.

      • pDrvObj->DriverUnload에 등록된 SampleDriverUnload 함수가 호출된 것을 볼 수 있다.

참고