CreateFile(...) Study+more

우리가 유저모드 App에서 CreateFile함수를 호출했다 치자.
그러면, 얘는 현재 UNICODE가 정의 되어있는지 확인한 다음에 CreateFileW를 호출하던지,
CreateFileA를 호출한 다음에 CreateFileA에서 CreateFileW를 호출하는 진행(어차피 CreateFileW호출)을
하게된다.
그러면, 얘는 몇가지 일을 한 다음에 ZwCreateFile을 호출하게 된다.
ZwCreateFile중에서 몇개 신경써야 할 인자는, PHANDLE과 POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK
정도가 될거 같다.

PIO_STATUS_BLOCK는 결과값을 의미하고, PHANDLE은 커널 객체의 핸들, POBJECT_ATTRIBUTES는 내가
잘 모르는 그 무엇(!.?)이다.

ZwCreateFile은 NtCreateFile을 호출하고(걍 Alias일뿐..), 그 다음으로 I/O Manager가 IRP를 만들어 낸다.
그리고 아마도 IoCallDriver()를 호출해서, IRP를 해당 디바이스 스택에 전송할 것이고.

디바이스 스택의 디바이스 객체에 해당하는 드라이버의 디스패치 루틴에서 처리를 해 주겠지.

IRP와 IO_STACK_LOCATION구조체 선언부를 보면, 우리가 CreateFile과 ZwCreateFile에 주었던 인자들이
포함되어 있다는것을 어렵지 않게 알수 있을것이다. (하지만, 실제 값을 비교해 보지는 못해서 장담할수는 없다.)


CreateFile->ZwCreateFile->I/O Manager-IRP/IO_STACK_LOCATION생성->DriverDispatchRoutine
이 될것 같다.
CreateFileW(
    __in     LPCWSTR lpFileName, //파일명
    __in     DWORD dwDesiredAccess, //객체에 접근하기 위한 권한 (읽기, 쓰기, 둘다)
    __in     DWORD dwShareMode, //0으로 설정하면 공유 안됨.
    __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes, //보안 서술자의 포인터. NULL이면 상속 안됨.
    __in     DWORD dwCreationDisposition, //파일 생성시 처리(항상 새로 생성, 등)
    __in     DWORD dwFlagsAndAttributes, //파일 속성과 플래그들
    __in_opt HANDLE hTemplateFile
    );


typedef struct _SECURITY_ATTRIBUTES {  
    DWORD nLength; //sizeof
    LPVOID lpSecurityDescriptor;  //NULL이면, 기본 보안 지정자.
    BOOL bInheritHandle; //상속 여부
} SECURITY_ATTRIBUTES,  *PSECURITY_ATTRIBUTES,  *LPSECURITY_ATTRIBUTES;


ZwCreateFile(
    __out PHANDLE FileHandle, //파일을 가리키는 핸들 CreateFile의 리턴값
    __in ACCESS_MASK DesiredAccess, //객체에 접근하기 위한 권한
    __in POBJECT_ATTRIBUTES ObjectAttributes, //
    __out PIO_STATUS_BLOCK IoStatusBlock, //요청 처리된 결과값
    __in_opt PLARGE_INTEGER AllocationSize, //초기 할당 크기를 포함하고 있는 라지 인티저의 포인터
    __in ULONG FileAttributes, //dwFlagsAndAttributes
    __in ULONG ShareAccess, //dwShareMode
    __in ULONG CreateDisposition, //
    __in ULONG CreateOptions,
    __in_bcount_opt(EaLength) PVOID EaBuffer,
    __in ULONG EaLength
    );


typedef DWORD ACCESS_MASK;
typedef ACCESS_MASK* PACCESS_MASK;


typedef struct _IO_STATUS_BLOCK {
    union {
        NTSTATUS Status;
        PVOID Pointer;
    } DUMMYUNIONNAME;
    //FILE_CREATED, FILE_OPENED, FILE_OVERWRITTEN, FILE_SURPERSEDED, FILE_EXISTS, FILE_DOES_NOT_EXIST중 하나.
    ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;


#define FILE_SUPERSEDED        0x00000000
#define FILE_OPENED        0x00000001
#define FILE_CREATED        0x00000002
#define FILE_OVERWRITTEN        0x00000003
#define FILE_EXISTS            0x00000004
#define FILE_DOES_NOT_EXIST        0x00000005


typedef struct _OBJECT_ATTRIBUTES {   
    ULONG  Length; //sizeof
    HANDLE  RootDirectory;    
    PUNICODE_STRING  ObjectName; //열 핸들의 유니크 객체 이름
    ULONG  Attributes; //속성
    PVOID  SecurityDescriptor; //보안 서술자의 포인터    
    PVOID  SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
※InitializeObjectAttributes() 매크로를 통해 초기화 할수 있다.


VOID  InitializeObjectAttributes(    
    OUT POBJECT_ATTRIBUTES  InitializedAttributes,    
    IN PUNICODE_STRING  ObjectName,    
    IN ULONG  Attributes,    
    IN HANDLE  RootDirectory,    
    IN PSECURITY_DESCRIPTOR  SecurityDescriptor);


typedef struct _IRP {
     .  .  
    PMDL  MdlAddress;  
    ULONG  Flags;  
    union {    
        struct _IRP  *MasterIrp;   
         .    .    
        PVOID  SystemBuffer;  
    } AssociatedIrp;  
    .  .  
    IO_STATUS_BLOCK  IoStatus;  
    KPROCESSOR_MODE  RequestorMode;  
    BOOLEAN PendingReturned;  
    .  .  
    BOOLEAN  Cancel;  
    KIRQL  CancelIrql;  
    .  .  
    PDRIVER_CANCEL  CancelRoutine;  
    PVOID UserBuffer;  
    union {    
        struct {    
            .    .    
            union {      
                KDEVICE_QUEUE_ENTRY DeviceQueueEntry;      
                struct {        PVOID  DriverContext[4];      };    
            };    
            .    .    
            PETHREAD  Thread;    
            .    .    
            LIST_ENTRY  ListEntry;    
            .    .    
        } Overlay;  
        .  .  
    } Tail;
} IRP, *PIRP;


typedef struct _IO_STACK_LOCATION {  
    UCHAR  MajorFunction;  
    UCHAR  MinorFunction;  
    UCHAR  Flags;  
    UCHAR  Control;  
    union {        
        //        
        // Parameters for IRP_MJ_CREATE         
        //        
        struct {         
            PIO_SECURITY_CONTEXT SecurityContext;            
            ULONG Options;            
            USHORT POINTER_ALIGNMENT FileAttributes;            
            USHORT ShareAccess;            
            ULONG POINTER_ALIGNMENT EaLength;        
        } Create;  
    } Parameters;  
    .  .
    PDEVICE_OBJECT  DeviceObject;  
    PFILE_OBJECT  FileObject;  
    .  .
} IO_STACK_LOCATION, *PIO_STACK_LOCATION;

덧글

  • Robert 2017/01/25 18:50 # 삭제 답글

    You are my inspiration , I have few web logs and very sporadically run out from to brand.
댓글 입력 영역