심플스 - 프로그램과 책 이야기로 가득한 곳, (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
번호 제목 글쓴이 날짜 조회 수
163 Linux Tip 리눅스 기반 오픈 소스 사이트 모음 삽질신 2009-11-16 73703
162 Linux Tip VirtualBox에 우분투 설치 후에 내부 네트워크 접속 설정하기 file esniper 2010-09-10 35806
161 Windows Research IE Cache 경로 변경하기 lain 2011-06-09 31366
160 Windows Research 화면캡쳐방지는 어떻게 구현될까? [3] lain 2010-09-04 29706
159 Windows Research VMWare 탐지 기법 우회 - 2 [2] lain 2011-04-04 29694
158 PHP Tip php 파싱 라이브러리 - snoopy esniper 2009-03-26 21155
157 Linux Tip Directory index forbidden by Options directive 삽질신 2009-11-16 20863
156 Linux Tip VirtualBox에서 오른쪽 CTRL키 사용하기(VitualBox 호스트키) file [2] esniper 2010-09-10 20046
155 Windows Tip SSH 터널링 - putty의 plink 사용예 esniper 2009-03-26 19956
154 문서자료 고품질의 무료 아이콘들 [3] esniper 2010-09-08 19784
153 문서자료 json 문법 체크 사이트 Lyn 2012-02-28 19434
152 PHP Tip mysql_insert_id() - 마지막 insert 된 아이디 값 esniper 2009-03-26 18853
151 Windows Research 커널레벨에서 IAT Hook lain 2011-06-11 17479
150 Linux Tip 우분투 설치 후 putty에서 한글 안 깨지도록 설정하기 file esniper 2010-09-10 17342
149 Windows Research SetEvent 함수는 언제 실패할까? lain 2010-09-04 16789
148 Linux Tip 우분투 ssh or mysql 서버 접속지연이 있는 경우 해결책 esniper 2010-09-10 16762
147 Windows Research 유저 레벨에서 API Hook 1부 file [1] lain 2010-09-03 16304
146 Linux Tip 우분투에 IRC서버 설치후 닉네임 길이와 동접자 조절. [1] 오랑캐꽃 2010-11-26 16304
145 Windows Research Sysinternals - Filemon source code file [5] lain 2010-09-04 15903
144 Windows Research Sysinternals - Regmon source code file [1] lain 2010-09-04 15729

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