#include <ntifs.h> #include <windef.h> #define TAG 'tset' //test /* 用户层常用%systemroot%,很是方便,驱动呢? 在对象目录的根目录下有个符号链接systemroot,其值是:"\Device\Harddisk0\Partition1\Windows"。 但是在XP的应用层和驱动都没有导出RtlExpandEnvironmentStrings_U。 本文就是演示这些东西的。 注意: "\Device\Harddisk0\Partition1" "\Device\HarddiskVolume1" "\\.\Harddisk0Partition1" "\\.\PhysicalDrive0" 的关系。 如果不转换去打开文件的结果是://C0000034 系统找不到指定的文件。 用L"systemroot"或者L"%systemroot%"后面加文件去打开文件,返回的结果是:C000003b 指定的路径无效。 注意: 这个可以在系统启动的很早的时候获取,那时候文件驱动可能还没有加载,但是对象管理器已经初始化了。 made by correy made at 2014.06.14 homepage:http://correy.webs.com */ DRIVER_UNLOAD Unload; VOID Unload(__in PDRIVER_OBJECT DriverObject) { } #pragma INITCODE DRIVER_INITIALIZE DriverEntry; NTSTATUS DriverEntry(__in struct _DRIVER_OBJECT * DriverObject, __in PUNICODE_STRING RegistryPath) { ULONG ActualLength; HANDLE LinkHandle = 0; WCHAR NameBuffer[MAX_PATH]; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING LinkString, NameString, file_name, temp; NTSTATUS status = STATUS_SUCCESS; USHORT x = 0; KdBreakPoint(); DriverObject->DriverUnload = Unload; LinkString.Buffer = NameBuffer; LinkString.MaximumLength = sizeof(NameBuffer); RtlZeroMemory(NameBuffer, sizeof(NameBuffer)); RtlInitUnicodeString(&NameString, L"\\systemroot");//注意格式。 InitializeObjectAttributes(&ObjectAttributes, &NameString, OBJ_KERNEL_HANDLE, NULL, NULL); status = ZwOpenSymbolicLinkObject(&LinkHandle, SYMBOLIC_LINK_QUERY | GENERIC_READ , &ObjectAttributes); if (!NT_SUCCESS( status )) { KdPrint(("ZwOpenSymbolicLinkObject fail with 0x%X\n",status)); ZwClose(LinkHandle); return status; } status = ZwQuerySymbolicLinkObject(LinkHandle, &LinkString, &ActualLength); if (!NT_SUCCESS( status )) { KdPrint(("ZwQuerySymbolicLinkObject fail with 0x%X\n",status)); ZwClose(LinkHandle); return status; } KdPrint(("%wZ \n",&LinkString));//得到的值形如:"\Device\Harddisk0\Partition1\Windows"。 ZwClose(LinkHandle); /* 还得对这个路径进行解析,对象管理器在下面的情况(ZwOpenFile)是不会解析的,而是返回C0000034 系统找不到指定的文件。 注意:这是这偷懒不好的解析方式,仅仅演示用的。实际的工程要改进。 */ for (x = LinkString.Length; x > 0; x -= 2) { if (LinkString.Buffer[x/2] == L'\\') { break; } } temp.Buffer = &LinkString.Buffer[x/2]; temp.Length = LinkString.Length - x; temp.MaximumLength = LinkString.MaximumLength - x; LinkString.Length = x; //以上是把UNICODE_STRING以最后的斜杠一分为二。主要是因为转换后的数据也写入这里但是不会造成破坏。这是假定。 InitializeObjectAttributes(&ObjectAttributes, &LinkString, OBJ_KERNEL_HANDLE, NULL, NULL); status = ZwOpenSymbolicLinkObject(&LinkHandle, SYMBOLIC_LINK_QUERY | GENERIC_READ , &ObjectAttributes); if (!NT_SUCCESS( status )) { KdPrint(("ZwOpenSymbolicLinkObject fail with 0x%X\n",status)); ZwClose(LinkHandle); return status; } status = ZwQuerySymbolicLinkObject(LinkHandle, &LinkString, &ActualLength); if (!NT_SUCCESS( status )) { KdPrint(("ZwQuerySymbolicLinkObject fail with 0x%X\n",status)); ZwClose(LinkHandle); return status; } KdPrint(("%wZ \n",&LinkString));//得到的值形如:"\Device\Harddisk0\Partition1\Windows"。 ZwClose(LinkHandle); /*status = RtlAppendUnicodeToString(&LinkString, &LinkString.Buffer[x]); if (!NT_SUCCESS (status)) { KdPrint(("RtlAppendUnicodeToString fail with 0x%X!\n", status)); return status; }*/ status = RtlAppendUnicodeStringToString(&LinkString, &temp ); if (!NT_SUCCESS (status)) { KdPrint(("RtlAppendUnicodeStringToString fail with 0x%X!\n", status)); return status; } /* 测试用例一: 这个应该是成功的。 */ { UNICODE_STRING file_name, temp ; OBJECT_ATTRIBUTES ob; HANDLE FileHandle = 0; IO_STATUS_BLOCK IoStatusBlock = {0}; file_name.Buffer = ExAllocatePoolWithTag(NonPagedPool, MAX_PATH, TAG); if (file_name.Buffer == NULL) { DbgPrint("发生错误的文件为:%s, 代码行为:%d\n", __FILE__, __LINE__); return STATUS_UNSUCCESSFUL ; } RtlZeroMemory(file_name.Buffer, MAX_PATH); RtlInitEmptyUnicodeString(&file_name, file_name.Buffer,MAX_PATH); RtlCopyUnicodeString(&file_name, &LinkString); status = RtlAppendUnicodeToString(&file_name, L"\\regedit.exe"); if (!NT_SUCCESS (status)) { KdPrint(("RtlAppendUnicodeToString fail with 0x%X!\n", status)); if (file_name.Buffer) { ExFreePoolWithTag(file_name.Buffer, TAG); file_name.Buffer = NULL; } return status; } InitializeObjectAttributes(&ob, &file_name, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 0, 0); status = ZwOpenFile(&FileHandle, GENERIC_READ | SYNCHRONIZE, &ob, &IoStatusBlock, FILE_SHARE_READ, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); if (!NT_SUCCESS (status)) { KdPrint(("ZwOpenFile fail with 0x%x.\n", status)); if (file_name.Buffer) { ExFreePoolWithTag(file_name.Buffer, TAG); file_name.Buffer = NULL; } return status; } //测试结束的扫尾工作。 if (file_name.Buffer) { ExFreePoolWithTag(file_name.Buffer, TAG); file_name.Buffer = NULL; } if (FileHandle) { status = ZwClose(FileHandle); if (!NT_SUCCESS (status)) { KdPrint(("ZwClose fail with 0x%x.\n", status)); } else { FileHandle = NULL; } } } return status; }
2014年6月14日星期六
内核(对象管理器)中的systemroot
订阅:
博文评论 (Atom)
没有评论:
发表评论