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

  

DosPathNameToNtPathName

Windows Research 조회 수 14189 추천 수 0 2010.09.03 17:36:03
 

Win32와 드라이버간에 통신을 할 때 Win32에서 드라이버에게 파일경로를 넘겨주어야 할 때가 있었는데 Win32에서
C 드라이브를 경로에 경우 "C:\\"와 같이 접근하면 되지만 드라이버에서는 "\\??\\C:\\" 와 같이 접근을 해야 합니다.

간단하게 위와 같은 경우에는 앞에 "\\??\\" 를 붙여주면 되지만 네트워크 공유 폴더에 경우에는
또 다른 방식으로 이름을 지정해 주어야 합니다.

즉, 상황에 따라 Win32에서 파일 이름을 파싱하여 드라이버에서 인식 할 수 있는 이름으로 변환 후 드라이버에 넘겨주곤 하였는데
좀 더 깔끔한 방법을 소개하려고 합니다.

사실 조금만 생각해보면 Kernel32.CreateFileA는 Kernel32.CreateFileW를 호출하게 되고
( Win32에서 유니코드와 그렇지 않은 API로 나뉘어지는데 유니코드가 아닌 함수는 내부적으로 유니코드로 변환하여
  유니코드용 함수를 호출하게 됩니다. 그래서 유니코드로 만들어진 프로그램이 빠르다는 말이 있죠.. )
Kernel32.CreateFileW는 내부적으로 NtDll.NtCreateFile 를 호출할 것입니다.

그리고 여기서 NtCreateFile은 파일이름을 인자로 받지 않습니다.
즉, 그 전에 파일 이름이 NtPathName으로 변환된다는 말입니다.

IDA로 Kernel32.DLL를 열어본 후 Export 된 CreateFileW에서 호출하는 함수들을 보면 다음과 같이 바로 눈에 띄는 함수가 있습니다.
( 해당 Kernel32.DLL은 Windows XP SP2 입니다. 버전이 다른 운영체제에 경우에는 다른 함수를 사용하는 경우도 있습니다. )


b0072382_4971b1f3078e5.png 


함수 이름에서 이미 무엇을 하는 함수인지 설명이 다 되어 있습니다.
구글링을 조합한 해당 함수를 사용하는 예제코드는 다음과 같습니다.

#include <Windows.h>
typedef struct _UNICODE_STRING {
    USHORT  Length;
    USHORT  MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef BOOLEAN (__stdcall *RtlDosPathNameToNtPathName_U)(PCWSTR DosName,
                                                          PUNICODE_STRING NtName, 
                                                          PCWSTR *DosFilePath OPTIONAL, 
                                                          PUNICODE_STRING NtFilePath );
typedef void (__stdcall *RtlFreeUnicodeString)(     
    PUNICODE_STRING UnicodeString
    );
int _tmain(int argc, _TCHAR* argv[])
{
    RtlDosPathNameToNtPathName_U pRtlDosPathNameToNtPathName_U;
    RtlFreeUnicodeString pRtlFreeUnicodeString;
    HMODULE hModule;
    UNICODE_STRING NtName;
    hModule = ::LoadLibrary(_T("NtDLL.DLL"));
    if (hModule == NULL)
    {
        printf("NTDLL을 로드 할 수 없습니다.\n");
        return (-1);
    }
    pRtlDosPathNameToNtPathName_U = (RtlDosPathNameToNtPathName_U)::GetProcAddress(hModule, "RtlDosPathNameToNtPathName_U");
    if (pRtlDosPathNameToNtPathName_U == NULL)
    {
        printf("RtlDosPathNameToNtPathName_U API를 찾을 수 없습니다.\n");
        return (-1);
    }
    pRtlFreeUnicodeString = (RtlFreeUnicodeString)::GetProcAddress(hModule, "RtlFreeUnicodeString");
    if (pRtlFreeUnicodeString == NULL)
    {
        printf("RtlFreeUnicodeString API를 찾을 수 없습니다.\n");
        return (-1);
    }
    if (pRtlDosPathNameToNtPathName_U(_T("\\\\10.1.26.15"), &NtName, NULL, NULL) == FALSE)
    {
        printf("pRtlDosPathNameToNtPathName_U 실패\n");
        return 0;
    }
    // 가져온 이름을 출력
    ::MessageBoxW(0, NtName.Buffer, _T("확인"), 0);
    pRtlFreeUnicodeString(&NtName);
    return 0;
}

위에 코드를 통해서 DosPathName을 NtPathName으로 변경할 수 있습니다.
예제 코드에서는 _T("\\\\10.1.26.15") 에 NtPathName를 얻으려고 하였습니다.

실행결과는 다음과 같습니다.


b0072382_4971b1f3078e5.png 



참고로 이 함수는 유저레벨에서만 사용 할 수 있고 인자로 넘겨주는 경로가 존재하지 않아도 상관이 없습니다.
즉, 경로를 드라이버에서 사용가능한 경로로 변환할 뿐 경로가 올바른지는 확인하지 않습니다.

해당 함수가 Undocumented 된 API이긴 하지만 제가 테스트해봤을 때는 거의 모든 운영체제에서 돌아갔습니다.
테스트한 운영체제는..
Windows XP SP2, Windows 2003 Server, Windows XP 64Bit, Windows Vista 64Bit, Windows 7 64Bit 입니다.
( 그냥 다 된다고 보시면 됩니다.-_- )

List of Articles
번호 제목 글쓴이 날짜 조회 수
43 문서자료 SCSI Multi-Media Commands - 5 (MMC-5) file lain 2010-09-03 11609
42 문서자료 Seagate - SCSI Commands Reference Manual file lain 2010-09-03 11792
41 문서자료 Intel® Threading Building Blocks: Documents lain 2010-09-03 11122
40 문서자료 Mozilla - Accessibility/AT-Windows-API lain 2010-09-03 9128
39 문서자료 Win32 Assembly Tutorials [1] lain 2010-09-03 11381
38 문서자료 the Operating System resource center lain 2010-09-03 10978
37 문서자료 Bona Fide OSDev Documents lain 2010-09-03 10607
36 문서자료 Keybaord Scan Codes Demystified lain 2010-09-03 10771
35 문서자료 Intel i80x86 CPU Architecture lain 2010-09-03 11437
34 문서자료 Hexray - Failures and troubleshooting lain 2010-09-03 12086
33 Windows Research 윈도우즈 버전이 Windows XP SP2인지 확인하는 다른 방법 [1] lain 2010-09-03 22439
32 Windows Research 유저 레벨에서 API Hook 1부 file [1] lain 2010-09-03 23489
31 Windows Research 유저 레벨에서 API Hook 2부 file [2] lain 2010-09-03 20622
30 Windows Research IDA에 HexRay를 사용할 때의 주의점 [1] lain 2010-09-03 16325
29 Windows Research IDA에서 Microsoft 바이너리 파일을 리버싱 할 때 디버그 심... file [1] lain 2010-09-03 17402
28 Windows Research 커널 모듈 리스트 가져오기 [3] lain 2010-09-03 18540
27 Windows Research VMWare 탐지 기법 우회 [2] lain 2010-09-03 24535
26 Windows Research 커널 디버거 탐지 기법 우회 lain 2010-09-03 18105
25 Windows Research ZwQueryInformationFile을 비동기 파일핸들로 호출 시 STATUS... file lain 2010-09-03 16076
» Windows Research DosPathNameToNtPathName file lain 2010-09-03 14189

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