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 |