在分 发函数:
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] =
DriverObject->MajorFunction[IRP_MJ_CREATE_MAILSLOT] = HideCreate;
中使用ObQueryNameString函数会导致系统蓝屏,我是在win7 32位系统上测试的,求高手指导!
HideCreate函数实现如下:
NTSTATUS
HideCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status = STATUS_SUCCESS;
KEVENT waitEvent;
PSFILTER_DEVICE_EXTENSION devExt;
PIO_STACK_LOCATION irpSp;
POBJECT_NAME_INFORMATION objectNameInfo;
UCHAR objectNameInfoBuffer[MAX_PATH];
PUCHAR pAllocBuffer = NULL;
ULONG returnLength;
FILE_STANDARD_INFORMATION standardInformation;
PHIDE_STREAM_CONTEXT pStreamContext;
USHORT streamContextSize;
PFSRTL_PER_STREAM_CONTEXT ctxCtrl;
PHIDE_STREAM_CONTEXT ctx;
PAGED_CODE();
if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject))
{
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return status;
}
ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));
KeInitializeEvent(&waitEvent,NotificationEvent,FALSE);
IoCopyCurrentIrpStackLocationToNext( Irp );
IoSetCompletionRoutine( Irp,
HideCreateAndDirectoryControlCompletion,
&waitEvent,
TRUE,
TRUE,
TRUE
);
devExt = (PSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
status = IoCallDriver(devExt->AttachedToDeviceObject,Irp);
if (STATUS_PENDING == status)
{
status = KeWaitForSingleObject( &waitEvent,
Executive,
KernelMode,
FALSE,
NULL
);
ASSERT(STATUS_SUCCESS == status);
}
ASSERT(KeReadStateEvent(&waitEvent) || !NT_SUCCESS(Irp->IoStatus.Status)); //HDM: !NT_SUCCESS(Irp->IoStatus.Status) Why? If the event object is not set to a signaled state,就能认为Irp一定没有被成功处理吗?
do
{
if (!NT_SUCCESS(Irp->IoStatus.Status))
{
break;
}
//
// 判断是否为目录。如果HideQueryInformationFile失败,那么默认为目录
//
irpSp = IoGetCurrentIrpStackLocation(Irp);
status = HideQueryInformationFile( devExt->AttachedToDeviceObject,
irpSp->FileObject,
&standardInformation,
sizeof( standardInformation ),
FileStandardInformation,
NULL
);
if (NT_SUCCESS(status))
{
if (!standardInformation.Directory)
{
break;
}
}
//
// 得到目录名
//
objectNameInfo = (POBJECT_NAME_INFORMATION)objectNameInfoBuffer;
status = ObQueryNameString( irpSp->FileObject,
objectNameInfo,
sizeof(objectNameInfoBuffer),
&returnLength
);
if (STATUS_INFO_LENGTH_MISMATCH == status)
{
pAllocBuffer = ExAllocatePoolWithTag( PagedPool,
returnLength,
HIDE_POOL_TAG
);
if (NULL == pAllocBuffer)
{
break;
}
objectNameInfo = (POBJECT_NAME_INFORMATION)pAllocBuffer;
status = ObQueryNameString( irpSp->FileObject,
objectNameInfo,
returnLength,
&returnLength
);
ASSERT(STATUS_SUCCESS == status);
}
else if(!NT_SUCCESS(status))
{
break;
}
if(objectNameInfo->Name.Buffer[objectNameInfo->Name.Length / sizeof(WCHAR) - 1] == L'\\')
{
objectNameInfo->Name.Length--;
}
if(SfDebug & SFDEBUG_DISPLAY_CREATE_NAMES)
{
ANSI_STRING temp;
RtlUnicodeStringToAnsiString( &temp,
&objectNameInfo->Name,
TRUE
);
DbgPrint("%Z\n",&temp);
RtlFreeAnsiString(&temp);
}
if (HideIsParentDirOfHiddenFile(&objectNameInfo->Name))
{
//
// Allocating the Per-Stream Context
//
streamContextSize = sizeof(HIDE_STREAM_CONTEXT) + objectNameInfo->Name.Length; //HDM:注意也许可以再减1
pStreamContext = (PHIDE_STREAM_CONTEXT)ExAllocatePoolWithTag( PagedPool,
streamContextSize,
HIDE_POOL_TAG
);
if (NULL == pStreamContext)
{
break;
}
RtlInitEmptyUnicodeString( &pStreamContext->DirName,
(PWCHAR)((PUCHAR)pStreamContext + sizeof(HIDE_STREAM_CONTEXT)),
objectNameInfo->Name.Length
);
RtlCopyUnicodeString( &pStreamContext->DirName,
&objectNameInfo->Name
);
FsRtlInitPerStreamContext( &pStreamContext->ContextCtrl,
gSFilterDriverObject,
NULL,
HideDeleteContextCallback
);
//
// Associating a Per-Stream Context With a File Stream
//
HideAcquireContextLockExclusive(g_ctxLock);
ctxCtrl = FsRtlLookupPerStreamContext( FsRtlGetPerStreamContextPointer(irpSp->FileObject),
gSFilterDriverObject,
NULL
);
if (NULL != ctxCtrl)
{
ExFreePoolWithTag(pStreamContext,HIDE_POOL_TAG);
HideReleaseContextLock(g_ctxLock);
break;
}
FsRtlInsertPerStreamContext( FsRtlGetPerStreamContextPointer(irpSp->FileObject),
&pStreamContext->ContextCtrl
);
HideReleaseContextLock(g_ctxLock);
}
} while (0);
if (pAllocBuffer)
{
ExFreePoolWithTag(pAllocBuffer,HIDE_POOL_TAG);
}
//
// Save the status and continue processing the IRP
//
status = Irp->IoStatus.Status;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return status;
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)