#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)
没有评论:
发表评论