Windows Driver Model

Namespace("\\.\"、"\??\")


Lucas最近又開始假認真了!司徒只好配合演出,誇張的是他竟然在研究Namespace,這部份真的相當複雜,因為有分NT Namespace、Win32 Device Namespace、Device Namespace、File Namespace("\\.\"、"\??\"、"\??\GLOBALROOT\"、"\\?\"、"\GLOBAL??\"、"\Device\"、"\DosDevices\")等幾個部份,說實話,這部份建議使用者依照既有的範例使用即可,除非使用者想找一些微軟的漏洞,不然真的不需要花時間看這種東西,理由是:這部份可能會跟OS版本而略有差異,而司徒介紹的也緊止於測試WinXP、Win7x86平台,是否在之後的OS又有變更,司徒真的不敢保證,如果說完這些後,使用者還是有興趣的話,就可以繼續看下去。

NT Namespace

Name Windows APIs String Parsing Description
\\.\ Yes Win32 Device Namespace,指到NT Namespace的GLOBAL??資料夾,只能使用Win32 API相關的API呼叫,如:CreateFile()
\??\ Yes 指到NT Namespace根目錄,WinXP不支援
\??\GLOBALROOT\ Yes 指到NT Namespace根目錄,WinXP不支援
\\?\ No 指到NT Namespace根目錄,Windows APIs會把\\?\改成\??\
\GLOBAL??\ Yes 指到NT Namespace的GLOBAL??資料夾
\Device\ Yes 指到NT Namespace的Device資料夾
\DosDevices\ Yes 指到NT Namespace的GLOBAL??資料夾

P.S. Windows APIs String Parsing代表是否需要轉置Namespace(WinXP呼叫RtlDosPathNameToNtPathName_U(), Win7呼叫RtlDosPathNameToRelativeNtPathName()),轉置的意思就是:是否會把/改成\

程式碼:

#include <windows.h>
#include <winternl.h>
#include <stdio.h>
#pragma comment(lib, "ntdll.lib")

typedef NTSTATUS (__stdcall *NT_OPEN_FILE)(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, ULONG ShareAccess, ULONG OpenOptions);

void WINAPI RtlInitUnicodeString(PUNICODE_STRING target, LPCWSTR source)
{
  if((target->Buffer = (LPWSTR)source)){
    target->Length = wcslen(source) * sizeof(WCHAR);
    target->MaximumLength = target->Length + sizeof(WCHAR);
  }
  else{
    target->Length = target->MaximumLength = 0;
  }
}

void DoNtOpenFile(wchar_t *name)
{
  PVOID Info;
  NT_OPEN_FILE NtOpenFileStruct;
  HMODULE hModule = LoadLibrary("ntdll.dll");
  NtOpenFileStruct = (NT_OPEN_FILE)GetProcAddress(hModule, "NtOpenFile");
  if(NtOpenFileStruct != NULL){
    UNICODE_STRING filename;
    RtlInitUnicodeString(&filename, name);
   
    OBJECT_ATTRIBUTES obj;
    obj.Attributes = 0x40;
    obj.ObjectName = &filename;
    obj.Length = 0x18;
    obj.RootDirectory = NULL;
    obj.SecurityDescriptor = NULL;
    obj.SecurityQualityOfService = NULL;
   
    IO_STATUS_BLOCK iostatusblock;
    HANDLE hFile = NULL;
    NTSTATUS stat = NtOpenFileStruct(&hFile, 0x100001, &obj, &iostatusblock, 7, 0x20);
    printf("NtOpenFileStruct(%S): (status:0x%x)\n", name, stat);
    if(stat == 0){
      CloseHandle(hFile);
    }
  }
}

void DoCreateFile(char *name)
{
  HANDLE hFile = CreateFile(name, MAXIMUM_ALLOWED, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
  printf("CreateFile(%s): (handle:0x%x, err:0x%x)\n", name, hFile, GetLastError());
  if(hFile != (HANDLE)-1){
    CloseHandle(hFile);
  }
}

int __cdecl main(int argc, char* argv[])
{
  // device namespace
  DoCreateFile("\\\\.\\ndis");
  DoCreateFile("\\??\\ndis");
  DoCreateFile("\\??\\GLOBALROOT\\ndis");
  DoCreateFile("\\\\?\\ndis");
  DoCreateFile("\\GLOBAL??\\ndis");
  DoCreateFile("\\Device\\ndis");
  DoCreateFile("\\DosDevices\\ndis");
  DoCreateFile("ndis");
  printf("\n");
  
  DoNtOpenFile(L"\\\\.\\ndis");
  DoNtOpenFile(L"\\??\\ndis");
  DoNtOpenFile(L"\\??\\GLOBALROOT\\ndis");
  DoNtOpenFile(L"\\\\?\\ndis");
  DoNtOpenFile(L"\\GLOBAL??\\ndis");
  DoNtOpenFile(L"\\Device\\ndis");
  DoNtOpenFile(L"\\DosDevices\\ndis");
  DoNtOpenFile(L"ndis");
  printf("\n");
  
  // file namespace
  DoCreateFile("\\\\.\\c:\\test\\test.txt");
  DoCreateFile("\\??\\c:\\test\\test.txt");
  DoCreateFile("\\??\\GLOBALROOT\\c:\\test\\test.txt");
  DoCreateFile("\\\\?\\c:\\test\\test.txt");
  DoCreateFile("\\GLOBAL??\\c:\\test\\test.txt");
  DoCreateFile("\\Device\\c:\\test\\test.txt");
  DoCreateFile("\\DosDevices\\c:\\test\\test.txt");
  DoCreateFile("c:\\test\\test.txt");
  printf("\n");
  
  DoNtOpenFile(L"\\\\.\\c:\\test\\test.txt");
  DoNtOpenFile(L"\\??\\c:\\test\\test.txt");
  DoNtOpenFile(L"\\??\\GLOBALROOT\\c:\\test\\test.txt");
  DoNtOpenFile(L"\\\\?\\c:\\test\\test.txt");
  DoNtOpenFile(L"\\GLOBAL??\\c:\\test\\test.txt");
  DoNtOpenFile(L"\\Device\\c:\\test\\test.txt");
  DoNtOpenFile(L"\\DosDevices\\c:\\test\\test.txt");
  DoNtOpenFile(L"c:\\test\\test.txt");
  printf("\n");
  
  // c:\test/test.txt
  DoCreateFile("\\\\.\\c:\\test/test.txt");
  DoCreateFile("\\??\\c:\\test/test.txt");
  DoCreateFile("\\??\\GLOBALROOT\\c:\\test/test.txt");
  DoCreateFile("\\\\?\\c:\\test/test.txt");
  DoCreateFile("\\GLOBAL??\\c:\\test/test.txt");
  DoCreateFile("\\Device\\c:\\test/test.txt");
  DoCreateFile("\\DosDevices\\c:\\test/test.txt");
  DoCreateFile("c:\\test/test.txt");
  return 0;
}

Device Namespace測試


逆向看一下轉換後的名稱


整理表格(Device Namespace測試)

Before CreateFile() In CreateFile()
\\.\ndis \??\ndis
\??\ndis \??\c:\??\ndis
\??\GLOBALROOT\ndis \??\c:\??\GLOBALROOT\ndis
\\?\ndis \??\ndis
\GLOBAL??\ndis \??\c:\GLOBAL??\ndis
\Device\ndis \??\c:\Device\ndis
\DosDevices\ndis \??\c:\DosDevices\ndis
ndis \??\${CURRENT_DIR}\ndis
Before NtOpenFileStruct() In NtOpenFileStruct()
\\.\ndis \\.\ndis
\??\ndis \??\ndis
\??\GLOBALROOT\ndis \??\GLOBALROOT\ndis
\\?\ndis \\?\ndis
\GLOBAL??\ndis \GLOBAL??\ndis
\Device\ndis \Device\ndis
\DosDevices\ndis \DosDevices\ndis
ndis ndis

File Namespace測試


逆向看一下轉換後的名稱


整理表格(File Namespace測試)

Before CreateFile() In CreateFile()
\\.\c:\test\test.txt \??\c:\test\test.txt
\??\c:\test\test.txt \??\c:\??\c:\test\test.txt
\??\GLOBALROOT\c:\test\test.txt \??\c:\??\GLOBALROOT\c:\test\test.txt
\\?\c:\test\test.txt \??\c:\test\test.txt
\GLOBAL??\c:\test\test.txt \??\c:\GLOBAL??\c:\test\test.txt
\Device\c:\test\test.txt \??\c:\Device\c:\test\test.txt
\DosDevices\c:\test\test.txt \??\c:\DosDevices\c:\test\test.txt
c:\test\test.txt \??\c:\test\test.txt
Before NtOpenFileStruct() In NtOpenFileStruct()
\\.\c:\test\test.txt \\.\c:\test\test.txt
\??\c:\test\test.txt \??\c:\test\test.txt
\??\GLOBALROOT\c:\test\test.txt \??\GLOBALROOT\c:\test\test.txt
\\?\c:\test\test.txt \\?\c:\test\test.txt
\GLOBAL??\c:\test\test.txt \GLOBAL??\c:\test\test.txt
\Device\c:\test\test.txt \Device\c:\test\test.txt
\DosDevices\c:\test\test.txt \DosDevices\c:\test\test.txt
c:\test\test.txt c:\test\test.txt

轉置測試


逆向看一下轉換後的名稱


整理表格(轉置測試)

Before CreateFile() In CreateFile()
\\.\c:\test/test.txt \??\c:\test\test.txt
\??\c:\test/test.txt \??\c:\??\c:\test\test.txt
\??\GLOBALROOT\c:\test/test.txt \??\c:\??\GLOBALROOT\c:\test\test.txt
\\?\c:\test/test.txt \??\c:\test/test.txt
\GLOBAL??\c:\test/test.txt \??\c:\GLOBAL??\c:\test\test.txt
\Device\c:\test/test.txt \??\c:\Device\c:\test\test.txt
\DosDevices\c:\test/test.txt \??\c:\DosDevices\c:\test\test.txt
c:\test/test.txt \??\c:\test\test.txt
Before NtOpenFileStruct() In NtOpenFileStruct()
\\.\c:\test/test.txt \\.\c:\test/test.txt
\??\c:\test/test.txt \??\c:\test/test.txt
\??\GLOBALROOT\c:\test/test.txt \??\GLOBALROOT\c:\test/test.txt
\\?\c:\test/test.txt \\?\c:\test/test.txt
\GLOBAL??\c:\test/test.txt \GLOBAL??\c:\test/test.txt
\Device\c:\test/test.txt \Device\c:\test/test.txt
\DosDevices\c:\test/test.txt \DosDevices\c:\test/test.txt
c:\test/test.txt c:\test/test.txt


返回上一頁