|
RE: APC level access local variable
Hi Tony,
I using following PreOperation to trace IRP_MJ_CREATE for specific file.
FLT_PREOP_CALLBACK_STATUS
FltPreOperationCallback (
__inout PFLT_CALLBACK_DATA Data,
__in PCFLT_RELATED_OBJECTS FltObjects,
__deref_out PVOID *CompletionContext
)
{
FLT_PREOP_CALLBACK_STATUS returnStatus = FLT_PREOP_SUCCESS_NO_CALLBACK;
//assume we are NOT going to call our completion routine
PFLT_FILE_NAME_INFORMATION nameInfo = NULL;
UNICODE_STRING defaultName;
PFLT_VOLUME pFLTVolume;
PUNICODE_STRING nameToUse = NULL;
UNICODE_STRING uStrGuidName,uStrPath,uVolume,uStrExtension;
PUNICODE_STRING pStrExtension = NULL;
NTSTATUS status,nStatus;
UNICODE_STRING uStrVolume;
UNICODE_STRING uStrParentPath;
BYTE bAccessType = 0;
BOOLEAN bMatched = FALSE;
try
{
RtlInitUnicodeString(&uStrExtension,L"exe");
if(KeGetCurrentIrql()== PASSIVE_LEVEL && (Data->Iopb->MajorFunction ==
IRP_MJ_CREATE ||Data->Iopb->MajorFunction==IRP_MJ_SET_INFORMATION ||
Data->Iopb->MajorFunction==IRP_MJ_WRITE ||
Data->Iopb->MajorFunction==IRP_MJ_READ ||
Data->Iopb->MajorFunction==IRP_MJ_CLEANUP))
{
RtlInitUnicodeString(&uStrGuidName,NULL);
RtlInitUnicodeString(&uStrPath,NULL);
RtlInitUnicodeString(&uStrParentPath,NULL);
if (FltObjects->FileObject != NULL)
{ // Check if FileObject is NULL
status = FltGetFileNameInformation( Data,FLT_FILE_NAME_OPENED
|FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP,
&nameInfo );
}
else
{
status = STATUS_UNSUCCESSFUL;
}
if (NT_SUCCESS( status ))
{
status = FltParseFileNameInformation( nameInfo );
ASSERT(NT_SUCCESS(status));
}
if(NT_SUCCESS(status))
{
nStatus =
FltGetVolumeFromFileObject(WinFLTData.m_Filter,FltObjects->FileObject,&pFLTVolume
);
if(NT_SUCCESS(nStatus))
{
uStrGuidName.Length = 0;
uStrGuidName.MaximumLength = 520;
uStrGuidName.Buffer =
(PWSTR)ExAllocatePoolWithTag(NonPagedPool,520,'uLT1');
if(uStrGuidName.Buffer != NULL)
nStatus = FltGetVolumeGuidName(pFLTVolume,&uStrGuidName,NULL);
FltObjectDereference(pFLTVolume);
if(NT_SUCCESS(nStatus) && uStrGuidName.Buffer != NULL &&
nameInfo->Name.Length > 0)
{
uStrPath.Length = 0 ;
uStrPath.MaximumLength = nameInfo->Name.Length + 520;
uStrPath.Buffer =
(PWSTR)ExAllocatePoolWithTag(NonPagedPool,nameInfo->Name.Length + 520,'uLT2');
uStrParentPath.Length = 0 ;
uStrParentPath.MaximumLength = nameInfo->Name.Length + 520;
uStrParentPath.Buffer =
(PWSTR)ExAllocatePoolWithTag(NonPagedPool,nameInfo->Name.Length + 520,'uLT3');
if(uStrPath.Buffer != NULL && uStrParentPath.Buffer != NULL)
{
RtlAppendUnicodeStringToString(&uStrPath,&uStrGuidName);
RtlAppendUnicodeStringToString(&uStrPath,&nameInfo->ParentDir);
RtlAppendUnicodeStringToString(&uStrPath,&nameInfo->FinalComponent);
RtlAppendUnicodeStringToString(&uStrParentPath,&uStrGuidName);
RtlAppendUnicodeStringToString(&uStrParentPath,&nameInfo->ParentDir);
if(Data->Iopb->MajorFunction == IRP_MJ_CREATE && gListLock )
{
if(Traverseinto_NoAccess_List(uStrPath))
bMatched = TRUE;
}
}
if(uStrParentPath.Buffer != NULL)
{
ExFreePoolWithTag(uStrParentPath.Buffer,'uLT3');
uStrParentPath.Buffer = NULL;
}
if(uStrPath.Buffer != NULL)
{
ExFreePoolWithTag(uStrPath.Buffer,'uLT2');
uStrPath.Buffer = NULL;
}
}
if(uStrGuidName.Buffer != NULL)
{
ExFreePoolWithTag(uStrGuidName.Buffer,'uLT1');
uStrGuidName.Buffer = NULL;
}
}
}
if (nameInfo != NULL)
{
FltReleaseFileNameInformation( nameInfo );
nameInfo = NULL;
}
if(bMatched)
{
Data->IoStatus.Status = STATUS_ACCESS_DENIED ;
Data->IoStatus.Information = 0;
FltSetCallbackDataDirty(Data);
return FLT_PREOP_COMPLETE;
}
}
}
except (EXCEPTION_EXECUTE_HANDLER)
{
if(uStrParentPath.Buffer != NULL)
{
ExFreePoolWithTag(uStrParentPath.Buffer,'uLT3');
uStrParentPath.Buffer = NULL;
}
if(uStrPath.Buffer != NULL)
{
ExFreePoolWithTag(uStrPath.Buffer,'uLT2');
uStrPath.Buffer = NULL;
}
if(uStrGuidName.Buffer != NULL)
{
ExFreePoolWithTag(uStrGuidName.Buffer,'uLT1');
uStrGuidName.Buffer = NULL;
}
if (nameInfo != NULL)
{
FltReleaseFileNameInformation( nameInfo );
nameInfo = NULL;
}
}
if (Data->Iopb->MajorFunction == IRP_MJ_SHUTDOWN) {
FltPostOperationCallback( Data,
FltObjects,
NULL,
0 );
returnStatus = FLT_PREOP_SUCCESS_NO_CALLBACK;
}
else
{
*CompletionContext = NULL;
returnStatus = FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
return returnStatus;
}
In above preoperation function to match with specific file using following
function like :
// RTL_AVL_TABLE gLockTable
// FAST_MUTEX hLockMutex
// DATAFILEINFO structure
typedef struct _DATAFILEINFO
{
int m_ID;
BYTE m_SecurityLevel;
BYTE m_NoAccessType;
BYTE m_NoVisibleType;
BYTE m_NoDeleteType;
BYTE m_NoWriteType;
BYTE m_DataType;
BYTE m_Mask;
wchar_t m_MaskCode[10];
wchar_t m_DataPath[MAX_PATH];
}DATAFILEINFO, *PDATAFILEINFO;
BOOLEAN Traverseinto_NoAccess_List(UNICODE_STRING uPath)
{
DATAFILEINFO tbObj;
BOOLEAN bSuccess = FALSE;
DbgPrint("Traverse into Lock List");
if(gListLock)
{
ExAcquireFastMutex( &hLockMutex );
RtlStringCbCopyW(tbObj.m_DataPath,uPath.MaximumLength,uPath.Buffer);
//GetLock(DATALOCK);
if(RtlIsGenericTableEmptyAvl(&gLockTable) == FALSE)
{
if(RtlLookupElementGenericTableAvl(&gLockTable,&tbObj) != NULL)
{
bSuccess = TRUE;
}
}
//ReleaseLock(DATALOCK);
ExReleaseFastMutex( &hLockMutex );
}
return bSuccess;
}
Note when I am not this function to traverse table then working fine , but when
I traversed this function then getting BSOD, with this message Debug overrun
buffer like.
Let me know if anybody can help this.
Thanks
|