심플스 - 프로그램과 책 이야기로 가득한 곳, (Simples.Kr)

  


   심플스 배너



 

글을 쓰기 앞서 IoGetDeviceObjectPointer라는 유용한 커널 함수가 존재하나 해당 함수는
내부적으로 IoGetRelatedDeviceObject 함수를 호출함으로 이름에 해당하는 PDEVICE_OBJECT를
리턴하는것이 아니라 이름에 해당하는 PDEVICE_OBJECT에 최상위 PDEVICE_OBJECT를 리턴합니다.

예를 들어 atapi 드라이버에 다음과 같이 사용중인 디바이스 오브젝트가 3개가 있을 경우
"\\Device\\Ide\\IdeDeviceP1T0L0-17"는 시디롬 장치의 디바이스 오브젝트인데
IoGetDeviceObjectPointer 함수를 사용하면 0x817E4030 주소를 가진 PDEVICE_OBJECT를 리턴하는것이 아니라
Attach 되어 있는 최상위 디바이스 오브젝트인 \\Driver\redbook ( unnamed - 디바이스 이름없음 ) 하게 됩니다.


b0072382_4a617605c9a93.png

 



그러므로 디바이스 이름으로부터 정확한 포인터를 얻으려면 다음과 같은 방법으로 얻을 수 있습니다.


#include <Wdm.h>

PDEVICE_OBJECT MyIoGetDeviceObjectPointer(__in WCHAR *DeviceObjectName, __in BOOLEAN bRelated)
{
    NTSTATUS ntStatus;
    PFILE_OBJECT FileObject;
    PDEVICE_OBJECT DeviceObject;
    UNICODE_STRING Name;

    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE FileHandle;
    IO_STATUS_BLOCK IoStatus;

    DeviceObject = NULL;

    RtlInitUnicodeString(&Name, DeviceObjectName);
    if (bRelated == TRUE)
    {
        // IoGetDeviceObjectPointer는 내부적으로 IoGetRelatedDeviceObject 함수를 호출합니다.
        // 따라서 DeviceObjectName 에 해당하는 디바이스 오브젝트 포인터를 얻어오는게 아니라
        // 해당 디바이스 오브젝트에 대한 최상위 디바이스 오브젝트를 얻어옵니다.
        ntStatus = IoGetDeviceObjectPointer(&Name, FILE_READ_ATTRIBUTES, &FileObject, &DeviceObject);
        if (NT_SUCCESS(ntStatus) == TRUE)
        {
            return DeviceObject;
        }
        else
        {
            return NULL;
        }
    }
    else
    {
        // 실제 해당 이름을 가진 디바이스 오브젝트를 얻옵니다.
        InitializeObjectAttributes(&ObjectAttributes,
                                    &Name,
                                    0,
                                    (HANDLE) NULL,
                                    (PSECURITY_DESCRIPTOR)NULL);

        ntStatus = ZwOpenFile(&FileHandle,
                             FILE_READ_ATTRIBUTES,
                             &ObjectAttributes,
                             &IoStatus,
                             0,
                             FILE_NON_DIRECTORY_FILE);

        if (NT_SUCCESS(ntStatus) == FALSE)
        {
            // 해당 디바이스 오브젝트를 열 수 없습니다.
            return NULL;
        }

        ntStatus = ObReferenceObjectByHandle(FileHandle,
                                                                0,
                                                                *IoFileObjectType,
                                                                KernelMode,
                                                                (PVOID *)&FileObject,
                                                                NULL);

        if (NT_SUCCESS(ntStatus) == TRUE)
        {
            // Windows 2000 소스코드 참고
            // 실제 내부 구현도 이와 비슷하게 되어 있습니다.

            //
            // If the file object was taken out against the mounted file system, it
            // will have a Vpb. Traverse it to get to the DeviceObject. Note that in
            // this case we should never follow FileObject->DeviceObject, as that
            // mapping may be invalid after a forced dismount.
            //
            if (FileObject->Vpb != NULL && FileObject->Vpb->DeviceObject != NULL)
            {
                DeviceObject = FileObject->Vpb->DeviceObject;
                //
                // If a driver opened a disk device using direct device open and
                // later on it uses IoGetRelatedTargetDeviceObject to find the
                // device object it wants to send an IRP then it should not get the
                // filesystem device object. This is so that if the device object is in the
                // process of being mounted then vpb is not stable.
                //

            }
            else if (!(FileObject->Flags & FO_DIRECT_DEVICE_OPEN) &&
                       FileObject->DeviceObject->Vpb != NULL &&
                       FileObject->DeviceObject->Vpb->DeviceObject != NULL)
            {

                DeviceObject = FileObject->DeviceObject->Vpb->DeviceObject;
                //
                // This is a direct open against the device stack (and there is no mounted
                // file system to strain the IRPs through).
                //

            }
            else
            {
                DeviceObject = FileObject->DeviceObject;
            }
            ZwClose(FileHandle);

            return DeviceObject;
        }
        else
        {
            ZwClose(FileHandle);

            return NULL;
        }
    }
}

VOID DriverUnload(__in PDRIVER_OBJECT DriverObject)
{
    KdPrint(("Driver unload.\n"));
}


NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
    NTSTATUS ntStatus;
    PDEVICE_OBJECT DeviceObject;

    // 드라이버가 언로드 될 수 있도록 합니다.
    DriverObject->DriverUnload = DriverUnload;

    DeviceObject = MyIoGetDeviceObjectPointer(L"\\Device\\Ide\\IdeDeviceP1T0L0-17", FALSE);
    KdPrint(("DeviceObject : %p\n", DeviceObject));

    return STATUS_SUCCESS;
}

MyIoGetDeviceObjectPointer 에 두 번째 인자가 TRUE을 경우에는 기존 IoGetDeviceObjectPointer 함수를
사용하며 FALSE인 경우에는 이름에 해당하는 PDEVICE_OBJECT를 바로 얻어옵니다.

List of Articles
번호 제목 글쓴이 날짜 조회 수
» Windows Research 디바이스이름으로부터 PDEVICE_OBJECT 얻기 file [레벨:6]lain 2010-09-04 3674
141 Windows Research 하드디스크에 존재하지 않는 드라이버 바이너리 가져오기 file [5] [레벨:6]lain 2010-09-03 3627
140 Windows Research DosPathNameToNtPathName file [레벨:6]lain 2010-09-03 2617
139 Windows Research ZwQueryInformationFile을 비동기 파일핸들로 호출 시 STAT... file [레벨:6]lain 2010-09-03 3481
138 Windows Research 커널 디버거 탐지 기법 우회 [레벨:6]lain 2010-09-03 3708
137 Windows Research VMWare 탐지 기법 우회 [2] [레벨:6]lain 2010-09-03 5115
136 Windows Research 커널 모듈 리스트 가져오기 [3] [레벨:6]lain 2010-09-03 2627
135 Windows Research IDA에서 Microsoft 바이너리 파일을 리버싱 할 때 디버그 ... file [1] [레벨:6]lain 2010-09-03 3725
134 Windows Research IDA에 HexRay를 사용할 때의 주의점 [1] [레벨:6]lain 2010-09-03 3347
133 Windows Research 유저 레벨에서 API Hook 2부 file [2] [레벨:6]lain 2010-09-03 2336
132 Windows Research 유저 레벨에서 API Hook 1부 file [1] [레벨:6]lain 2010-09-03 2498
131 Windows Research 윈도우즈 버전이 Windows XP SP2인지 확인하는 다른 방법 [1] [레벨:6]lain 2010-09-03 2728
130 문서자료 Hexray - Failures and troubleshooting [레벨:6]lain 2010-09-03 2130
129 문서자료 Intel i80x86 CPU Architecture [레벨:6]lain 2010-09-03 1981
128 문서자료 Keybaord Scan Codes Demystified [레벨:6]lain 2010-09-03 2058
127 문서자료 Bona Fide OSDev Documents [레벨:6]lain 2010-09-03 1981
126 문서자료 the Operating System resource center [레벨:6]lain 2010-09-03 1543
125 문서자료 Win32 Assembly Tutorials [1] [레벨:6]lain 2010-09-03 1985
124 문서자료 Mozilla - Accessibility/AT-Windows-API [레벨:6]lain 2010-09-03 1984
123 문서자료 Intel® Threading Building Blocks: Documents [레벨:6]lain 2010-09-03 2600

  • 이용약관
  • 개인정보취급방침
  • 사이트맵